summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2018-01-19 21:58:58 +0000
committerSam McCall <sam.mccall@gmail.com>2018-01-19 21:58:58 +0000
commit1a8c55ecc6d28c8103f1825cd3ef03be58e350b7 (patch)
tree8ab608893c9cf60d7e3bb0162eab8c73a6e3d28e /clang-tools-extra/clangd
parent563799b3a6cf23fa56c4fcdc91d3d2cf45b015b0 (diff)
downloadbcm5719-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.cpp14
-rw-r--r--clang-tools-extra/clangd/index/Index.h14
-rw-r--r--clang-tools-extra/clangd/index/SymbolCollector.cpp8
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;
OpenPOWER on IntegriCloud