diff options
| author | Sam McCall <sam.mccall@gmail.com> | 2018-01-19 21:58:58 +0000 |
|---|---|---|
| committer | Sam McCall <sam.mccall@gmail.com> | 2018-01-19 21:58:58 +0000 |
| commit | 1a8c55ecc6d28c8103f1825cd3ef03be58e350b7 (patch) | |
| tree | 8ab608893c9cf60d7e3bb0162eab8c73a6e3d28e /clang-tools-extra/clangd | |
| parent | 563799b3a6cf23fa56c4fcdc91d3d2cf45b015b0 (diff) | |
| download | bcm5719-llvm-1a8c55ecc6d28c8103f1825cd3ef03be58e350b7.tar.gz bcm5719-llvm-1a8c55ecc6d28c8103f1825cd3ef03be58e350b7.zip | |
[clangd] Change index scope convention from "outer::inner" to "outer::inner::"
Global scope is "" (was "")
Top-level namespace scope is "ns::" (was "ns")
Nested namespace scope is "ns::ns::" (was "ns::ns")
This composes more naturally:
- qname = scope + name
- full scope = resolved scope + unresolved scope (D42073 was the trigger)
It removes a wart from the old way: "foo::" has one more separator than "".
Another alternative that has these properties is "::ns", but that lacks
the property that both the scope and the name are substrings of the
qname as produced by clang.
llvm-svn: 322996
Diffstat (limited to 'clang-tools-extra/clangd')
| -rw-r--r-- | clang-tools-extra/clangd/CodeComplete.cpp | 14 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/index/Index.h | 14 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/index/SymbolCollector.cpp | 8 |
3 files changed, 15 insertions, 21 deletions
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 1a95b6ba6bf..ab8a22d6b45 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -313,7 +313,7 @@ llvm::Optional<SymbolID> getSymbolID(const CodeCompletionResult &R) { /// completion (e.g. "ns::ab?"). struct SpecifiedScope { /// The scope specifier as written. For example, for completion "ns::ab?", the - /// written scope specifier is "ns". + /// written scope specifier is "ns::". Doesn't include leading "::". std::string Written; // If this scope specifier is recognized in Sema (e.g. as a namespace // context), this will be set to the fully qualfied name of the corresponding @@ -321,8 +321,7 @@ struct SpecifiedScope { std::string Resolved; llvm::StringRef forIndex() { - llvm::StringRef Chosen = Resolved.empty() ? Written : Resolved; - return Chosen.trim(':'); + return Resolved.empty() ? Written.ltrim('::') : Resolved; } }; @@ -631,15 +630,14 @@ SpecifiedScope getSpecifiedScope(Sema &S, const CXXScopeSpec &SS) { auto SpecifierRange = SS.getRange(); Info.Written = Lexer::getSourceText( CharSourceRange::getCharRange(SpecifierRange), SM, clang::LangOptions()); + if (!Info.Written.empty()) + Info.Written += "::"; // Sema excludes the trailing ::. if (SS.isValid()) { DeclContext *DC = S.computeDeclContext(SS); if (auto *NS = llvm::dyn_cast<NamespaceDecl>(DC)) { - Info.Resolved = NS->getQualifiedNameAsString(); + Info.Resolved = NS->getQualifiedNameAsString() + "::"; } else if (llvm::dyn_cast<TranslationUnitDecl>(DC) != nullptr) { - Info.Resolved = "::"; - // Sema does not include the suffix "::" in the range of SS, so we add - // it back here. - Info.Written = "::"; + Info.Resolved = ""; } } return Info; diff --git a/clang-tools-extra/clangd/index/Index.h b/clang-tools-extra/clangd/index/Index.h index a70d38b768f..a3eb298fdc5 100644 --- a/clang-tools-extra/clangd/index/Index.h +++ b/clang-tools-extra/clangd/index/Index.h @@ -114,10 +114,9 @@ struct Symbol { SymbolID ID; // The symbol information, like symbol kind. index::SymbolInfo SymInfo; - // The unqualified name of the symbol, e.g. "bar" (for "n1::n2::bar"). + // The unqualified name of the symbol, e.g. "bar" (for ns::bar). llvm::StringRef Name; - // The scope (e.g. namespace) of the symbol, e.g. "n1::n2" (for - // "n1::n2::bar"). + // The containing namespace. e.g. "" (global), "ns::" (top-level namespace). llvm::StringRef Scope; // The location of the canonical declaration of the symbol. // @@ -221,12 +220,11 @@ struct FuzzyFindRequest { /// un-qualified identifiers and should not contain qualifiers like "::". std::string Query; /// \brief If this is non-empty, symbols must be in at least one of the scopes - /// (e.g. namespaces) excluding nested scopes. For example, if a scope "xyz" - /// is provided, the matched symbols must be defined in scope "xyz" but not - /// "xyz::abc". + /// (e.g. namespaces) excluding nested scopes. For example, if a scope "xyz::" + /// is provided, the matched symbols must be defined in namespace xyz but not + /// namespace xyz::abc. /// - /// A scope must be fully qualified without leading or trailing "::" e.g. - /// "n1::n2". "" is interpreted as the global namespace, and "::" is invalid. + /// The global scope is "", a top level scope is "foo::", etc. std::vector<std::string> Scopes; /// \brief The number of top candidates to return. The index may choose to /// return more than this, e.g. if it doesn't know which candidates are best. diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index 92402c5ec6c..e7fae173a16 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -56,14 +56,14 @@ std::string makeAbsolutePath(const SourceManager &SM, StringRef Path) { return AbsolutePath.str(); } -// "a::b::c", return {"a::b", "c"}. Scope is empty if it doesn't exist. +// "a::b::c", return {"a::b::", "c"}. Scope is empty if there's no qualifier. std::pair<llvm::StringRef, llvm::StringRef> splitQualifiedName(llvm::StringRef QName) { assert(!QName.startswith("::") && "Qualified names should not start with ::"); size_t Pos = QName.rfind("::"); if (Pos == llvm::StringRef::npos) return {StringRef(), QName}; - return {QName.substr(0, Pos), QName.substr(Pos + 2)}; + return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)}; } bool shouldFilterDecl(const NamedDecl *ND, ASTContext *ASTCtx, @@ -147,12 +147,10 @@ bool SymbolCollector::handleDeclOccurence( SymbolLocation Location = {FilePath, SM.getFileOffset(D->getLocStart()), SM.getFileOffset(D->getLocEnd())}; std::string QName = ND->getQualifiedNameAsString(); - auto ScopeAndName = splitQualifiedName(QName); Symbol S; S.ID = std::move(ID); - S.Scope = ScopeAndName.first; - S.Name = ScopeAndName.second; + std::tie(S.Scope, S.Name) = splitQualifiedName(QName); S.SymInfo = index::getSymbolInfo(D); S.CanonicalDeclaration = Location; |

