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

Reply via email to