diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 81cfe8bb60b3e..3cf6671be9600 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -396,6 +396,15 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, VFS = Preamble->StatCache->getConsumingFS(std::move(VFS)); assert(CI); + + if (CI->getFrontendOpts().Inputs.size() > 0) { + auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage(); + if (Lang == Language::Asm || Lang == Language::LLVM_IR) { + elog("Clangd does not support assembly or IR source files"); + return std::nullopt; + } + } + // Command-line parsing sets DisableFree to true by default, but we don't want // to leak memory in clangd. CI->getFrontendOpts().DisableFree = false; diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp index b0d5bea1d3279..ec8132645f81f 100644 --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -13,6 +13,7 @@ #include "../../clang-tidy/ClangTidyCheck.h" #include "AST.h" +#include "CompileCommands.h" #include "Compiler.h" #include "Config.h" #include "Diagnostics.h" @@ -731,6 +732,37 @@ TEST(ParsedASTTest, DiscoversPragmaMarks) { pragmaTrivia(" End"))); } +TEST(ParsedASTTest, GracefulFailureOnAssemblyFile) { + std::string Filename = "TestTU.S"; + std::string Code = R"S( +main: + # test comment + bx lr + )S"; + + // The rest is a simplified version of TestTU::build(). + // Don't call TestTU::build() itself because it would assert on + // failure to build an AST. + MockFS FS; + std::string FullFilename = testPath(Filename); + FS.Files[FullFilename] = Code; + ParseInputs Inputs; + auto &Argv = Inputs.CompileCommand.CommandLine; + Argv = {"clang"}; + Argv.push_back(FullFilename); + Inputs.CompileCommand.Filename = FullFilename; + Inputs.CompileCommand.Directory = testRoot(); + Inputs.Contents = Code; + Inputs.TFS = &FS; + StoreDiags Diags; + auto CI = buildCompilerInvocation(Inputs, Diags); + assert(CI && "Failed to build compilation invocation."); + auto AST = ParsedAST::build(FullFilename, Inputs, std::move(CI), {}, nullptr); + + EXPECT_FALSE(AST.has_value()) + << "Should not try to build AST for assembly source file"; +} + } // namespace } // namespace clangd } // namespace clang