diff options
-rw-r--r-- | clang-tools-extra/clangd/index/SymbolCollector.cpp | 6 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp | 8 |
2 files changed, 14 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index a37ccd22f99..142e0f4cefe 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -285,6 +285,11 @@ bool SymbolCollector::handleDeclOccurence( assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set."); assert(CompletionAllocator && CompletionTUInfo); assert(ASTNode.OrigD); + // Indexing API puts cannonical decl into D, which might not have a valid + // source location for implicit/built-in decls. Fallback to original decl in + // such cases. + if (D->getLocation().isInvalid()) + D = ASTNode.OrigD; // If OrigD is an declaration associated with a friend declaration and it's // not a definition, skip it. Note that OrigD is the occurrence that the // collector is currently visiting. @@ -540,6 +545,7 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID, S.SymInfo = index::getSymbolInfo(&ND); std::string FileURI; auto Loc = findNameLoc(&ND); + assert(Loc.isValid() && "Invalid source location for NamedDecl"); // FIXME: use the result to filter out symbols. shouldIndexFile(SM, SM.getFileID(Loc), Opts, &FilesToIndexCache); if (auto DeclLoc = diff --git a/clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp b/clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp index 5b9e55353ca..bd46cc18520 100644 --- a/clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp +++ b/clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp @@ -1241,6 +1241,14 @@ TEST_F(SymbolCollectorTest, CBuiltins) { EXPECT_THAT(Symbols, Contains(QName("printf"))); } +TEST_F(SymbolCollectorTest, InvalidSourceLoc) { + const char *Header = R"( + void operator delete(void*) + __attribute__((__externally_visible__));)"; + runSymbolCollector(Header, /**/ ""); + EXPECT_THAT(Symbols, Contains(QName("operator delete"))); +} + } // namespace } // namespace clangd } // namespace clang |