Author: ioeric Date: Fri Feb 2 02:31:42 2018 New Revision: 324065 URL: http://llvm.org/viewvc/llvm-project?rev=324065&view=rev Log: [clangd] Skip inline namespace when collecting scopes for index symbols.
Summary: Some STL symbols are defined in inline namespaces. For example, ``` namespace std { inline namespace __cxx11 { typedef ... string; } } ``` Currently, this will be `std::__cxx11::string`; however, `std::string` is desired. Inline namespaces are treated as transparent scopes. This reflects the way they're most commonly used for lookup. Ideally we'd include them, but at query time it's hard to find all the inline namespaces to query: the preamble doesn't have a dedicated list. Reviewers: sammccall, hokein Reviewed By: sammccall Subscribers: klimek, ilya-biryukov, jkorous-apple, cfe-commits Differential Revision: https://reviews.llvm.org/D42796 Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp?rev=324065&r1=324064&r2=324065&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original) +++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Fri Feb 2 02:31:42 2018 @@ -9,6 +9,7 @@ #include "SymbolCollector.h" #include "../CodeCompletionStrings.h" +#include "Logger.h" #include "clang/AST/DeclCXX.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/SourceManager.h" @@ -97,8 +98,8 @@ bool shouldFilterDecl(const NamedDecl *N // * symbols in namespaces or translation unit scopes (e.g. no class // members) // * enum constants in unscoped enum decl (e.g. "red" in "enum {red};") - auto InTopLevelScope = - hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())); + auto InTopLevelScope = hasDeclContext( + anyOf(namespaceDecl(), translationUnitDecl(), linkageSpecDecl())); if (match(decl(allOf(Opts.IndexMainFiles ? decl() : decl(unless(isExpansionInMainFile())), @@ -180,7 +181,17 @@ bool SymbolCollector::handleDeclOccurenc return true; auto &SM = ND->getASTContext().getSourceManager(); - std::string QName = ND->getQualifiedNameAsString(); + + std::string QName; + llvm::raw_string_ostream OS(QName); + PrintingPolicy Policy(ASTCtx->getLangOpts()); + // Note that inline namespaces are treated as transparent scopes. This + // reflects the way they're most commonly used for lookup. Ideally we'd + // include them, but at query time it's hard to find all the inline + // namespaces to query: the preamble doesn't have a dedicated list. + Policy.SuppressUnwrittenScope = true; + ND->printQualifiedName(OS, Policy); + OS.flush(); Symbol S; S.ID = std::move(ID); Modified: clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp?rev=324065&r1=324064&r2=324065&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp Fri Feb 2 02:31:42 2018 @@ -198,8 +198,7 @@ TEST_F(SymbolCollectorTest, IncludeEnums runSymbolCollector(Header, /*Main=*/""); EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Red"), QName("Color"), QName("Green"), QName("Color2"), - QName("ns"), - QName("ns::Black"))); + QName("ns"), QName("ns::Black"))); } TEST_F(SymbolCollectorTest, IgnoreNamelessSymbols) { @@ -321,6 +320,53 @@ TEST_F(SymbolCollectorTest, IgnoreClassM EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Foo"))); } +TEST_F(SymbolCollectorTest, Scopes) { + const std::string Header = R"( + namespace na { + class Foo {}; + namespace nb { + class Bar {}; + } + } + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, + UnorderedElementsAre(QName("na"), QName("na::nb"), + QName("na::Foo"), QName("na::nb::Bar"))); +} + +TEST_F(SymbolCollectorTest, ExternC) { + const std::string Header = R"( + extern "C" { class Foo {}; } + namespace na { + extern "C" { class Bar {}; } + } + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, + UnorderedElementsAre(QName("na"), QName("Foo"), QName("Bar"))); +} + +TEST_F(SymbolCollectorTest, SkipInlineNamespace) { + const std::string Header = R"( + namespace na { + inline namespace nb { + class Foo {}; + } + } + namespace na { + // This is still inlined. + namespace nb { + class Bar {}; + } + } + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, + UnorderedElementsAre(QName("na"), QName("na::nb"), + QName("na::Foo"), QName("na::Bar"))); +} + TEST_F(SymbolCollectorTest, SymbolWithDocumentation) { const std::string Header = R"( namespace nx { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits