18 #include "llvm/ADT/SmallVector.h" 19 using namespace clang;
30 auto GetNextNamedNamespace = [](
const DeclContext *Context) {
32 while (Context && (!isa<NamespaceDecl>(Context) ||
33 cast<NamespaceDecl>(Context)->isAnonymousNamespace()))
37 for (Context = GetNextNamedNamespace(Context); Context !=
nullptr;
38 Context = GetNextNamedNamespace(Context->
getParent()))
39 Namespaces.push_back(cast<NamespaceDecl>(Context));
60 if (UseNamespaces.size() < FromNamespaces.size())
62 unsigned Diff = UseNamespaces.size() - FromNamespaces.size();
63 auto FromIter = FromNamespaces.begin();
67 auto UseIter = UseNamespaces.begin() + Diff;
68 for (; FromIter != FromNamespaces.end() && UseIter != UseNamespaces.end();
69 ++FromIter, ++UseIter) {
71 if (*FromIter == *UseIter)
75 if (cast<NamespaceDecl>(*FromIter)->getDeclName() ==
76 cast<NamespaceDecl>(*UseIter)->getDeclName())
79 assert(FromIter == FromNamespaces.end() && UseIter == UseNamespaces.end());
85 bool HadLeadingColonColon) {
87 while (DeclA && !isa<NamespaceDecl>(DeclA))
92 return HadLeadingColonColon ? NewName : NewName.substr(2);
98 "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() +
"::";
99 if (NewName.startswith(NS))
100 return NewName.substr(NS.size());
129 assert(QName.startswith(
"::"));
130 assert(QName.endswith(Spelling));
131 if (Spelling.startswith(
"::"))
134 auto UnspelledSpecifier = QName.drop_back(Spelling.size());
136 UnspelledSpecifier.split(UnspelledScopes,
"::", -1,
142 StringRef TrimmedQName = QName.substr(2);
146 auto IsAmbiguousSpelling = [&](
const llvm::StringRef CurSpelling) {
147 if (CurSpelling.startswith(
"::"))
152 StringRef Head = CurSpelling.split(
"::").first;
153 for (
const auto *NS : EnclosingNamespaces) {
155 if (!LookupRes.empty()) {
161 if (!TrimmedQName.startswith(Res->getQualifiedNameAsString()) &&
171 std::string Disambiguated = Spelling;
172 while (IsAmbiguousSpelling(Disambiguated)) {
173 if (UnspelledScopes.empty()) {
174 Disambiguated =
"::" + Disambiguated;
176 Disambiguated = (UnspelledScopes.back() +
"::" + Disambiguated).str();
177 UnspelledScopes.pop_back();
180 return Disambiguated;
187 StringRef ReplacementString) {
188 assert(ReplacementString.startswith(
"::") &&
189 "Expected fully-qualified name!");
199 const bool class_name_only = !Use;
200 const bool in_global_namespace =
202 const bool is_class_forward_decl =
204 !cast<CXXRecordDecl>(FromDecl)->isCompleteDefinition();
205 if (class_name_only && !in_global_namespace && !is_class_forward_decl &&
208 auto Pos = ReplacementString.rfind(
"::");
209 return Pos != StringRef::npos ? ReplacementString.substr(Pos + 2)
static std::string disambiguateSpellingInScope(StringRef Spelling, StringRef QName, const DeclContext &UseContext, SourceLocation UseLoc)
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
static bool isFullyQualified(const NestedNameSpecifier *NNS)
Check if the name specifier begins with a written "::".
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
static StringRef getBestNamespaceSubstr(const DeclContext *DeclA, StringRef NewName, bool HadLeadingColonColon)
DeclContext * getDeclContext()
static llvm::SmallVector< const NamespaceDecl *, 4 > getAllNamedNamespaces(const DeclContext *Context)
DeclContext * getParent()
getParent - Returns the containing DeclContext.
const NamedDecl * FromDecl
Encodes a location in the source.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
The name of a declaration.
static bool usingFromDifferentCanonicalNamespace(const DeclContext *FromContext, const DeclContext *UseContext)
SourceManager & getSourceManager()
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Defines the clang::SourceLocation class and associated facilities.
ASTContext & getParentASTContext() const
This represents a decl that may have a name.
The global specifier '::'. There is no stored value.