20#include "llvm/ADT/SmallVector.h"
32 auto GetNextNamedNamespace = [](
const DeclContext *Context) {
36 Context = Context->getParent();
39 for (Context = GetNextNamedNamespace(Context); Context !=
nullptr;
40 Context = GetNextNamedNamespace(Context->getParent()))
62 if (UseNamespaces.size() < FromNamespaces.size())
64 unsigned Diff = UseNamespaces.size() - FromNamespaces.size();
65 auto FromIter = FromNamespaces.begin();
69 auto UseIter = UseNamespaces.begin() + Diff;
70 for (; FromIter != FromNamespaces.end() && UseIter != UseNamespaces.end();
71 ++FromIter, ++UseIter) {
73 if (*FromIter == *UseIter)
81 assert(FromIter == FromNamespaces.end() && UseIter == UseNamespaces.end());
87 bool HadLeadingColonColon) {
94 return HadLeadingColonColon ? NewName : NewName.substr(2);
101 if (NewName.consume_front(NS))
121 assert(QName.starts_with(
"::"));
122 assert(QName.ends_with(Spelling));
123 if (Spelling.starts_with(
"::"))
124 return std::string(Spelling);
126 auto UnspelledSpecifier = QName.drop_back(Spelling.size());
128 UnspelledSpecifier.split(UnspelledScopes,
"::", -1,
134 StringRef TrimmedQName = QName.substr(2);
136 UseLoc =
SM.getSpellingLoc(UseLoc);
138 auto IsAmbiguousSpelling = [&](
const llvm::StringRef CurSpelling) {
139 if (CurSpelling.starts_with(
"::"))
144 StringRef Head = CurSpelling.split(
"::").first;
145 for (
const auto *NS : EnclosingNamespaces) {
147 if (!LookupRes.empty()) {
153 if (!TrimmedQName.starts_with(Res->getQualifiedNameAsString()) &&
154 SM.isBeforeInTranslationUnit(
155 SM.getSpellingLoc(Res->getLocation()), UseLoc))
163 std::string Disambiguated = std::string(Spelling);
164 while (IsAmbiguousSpelling(Disambiguated)) {
165 if (UnspelledScopes.empty()) {
166 Disambiguated =
"::" + Disambiguated;
168 Disambiguated = (UnspelledScopes.back() +
"::" + Disambiguated).str();
169 UnspelledScopes.pop_back();
172 return Disambiguated;
179 StringRef ReplacementString) {
180 assert(ReplacementString.starts_with(
"::") &&
181 "Expected fully-qualified name!");
191 const bool class_name_only = !Use;
192 const bool in_global_namespace =
194 const bool is_class_forward_decl =
197 if (class_name_only && !in_global_namespace && !is_class_forward_decl &&
200 auto Pos = ReplacementString.rfind(
"::");
201 return std::string(Pos != StringRef::npos
202 ? ReplacementString.substr(Pos + 2)
203 : ReplacementString);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static llvm::SmallVector< const NamespaceDecl *, 4 > getAllNamedNamespaces(const DeclContext *Context)
static bool usingFromDifferentCanonicalNamespace(const DeclContext *FromContext, const DeclContext *UseContext)
static StringRef getBestNamespaceSubstr(const DeclContext *DeclA, StringRef NewName, bool HadLeadingColonColon)
static std::string disambiguateSpellingInScope(StringRef Spelling, StringRef QName, const DeclContext &UseContext, SourceLocation UseLoc)
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
SourceManager & getSourceManager()
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
ASTContext & getParentASTContext() const
DeclContext * getDeclContext()
The name of a declaration.
This represents a decl that may have a name.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isFullyQualified() const
Whether this nested name specifier starts with a '::'.
Encodes a location in the source.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)