Lookup.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //===--- Lookup.cpp - Framework for clang refactoring tools ---------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines helper methods for clang tools performing name lookup.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/Tooling/Refactoring/Lookup.h"
  13. #include "clang/AST/ASTContext.h"
  14. #include "clang/AST/Decl.h"
  15. #include "clang/AST/DeclCXX.h"
  16. #include "clang/AST/DeclarationName.h"
  17. #include "clang/Basic/SourceLocation.h"
  18. #include "clang/Basic/SourceManager.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. using namespace clang;
  21. using namespace clang::tooling;
  22. // Gets all namespaces that \p Context is in as a vector (ignoring anonymous
  23. // namespaces). The inner namespaces come before outer namespaces in the vector.
  24. // For example, if the context is in the following namespace:
  25. // `namespace a { namespace b { namespace c ( ... ) } }`,
  26. // the vector will be `{c, b, a}`.
  27. static llvm::SmallVector<const NamespaceDecl *, 4>
  28. getAllNamedNamespaces(const DeclContext *Context) {
  29. llvm::SmallVector<const NamespaceDecl *, 4> Namespaces;
  30. auto GetNextNamedNamespace = [](const DeclContext *Context) {
  31. // Look past non-namespaces and anonymous namespaces on FromContext.
  32. while (Context && (!isa<NamespaceDecl>(Context) ||
  33. cast<NamespaceDecl>(Context)->isAnonymousNamespace()))
  34. Context = Context->getParent();
  35. return Context;
  36. };
  37. for (Context = GetNextNamedNamespace(Context); Context != nullptr;
  38. Context = GetNextNamedNamespace(Context->getParent()))
  39. Namespaces.push_back(cast<NamespaceDecl>(Context));
  40. return Namespaces;
  41. }
  42. // Returns true if the context in which the type is used and the context in
  43. // which the type is declared are the same semantical namespace but different
  44. // lexical namespaces.
  45. static bool
  46. usingFromDifferentCanonicalNamespace(const DeclContext *FromContext,
  47. const DeclContext *UseContext) {
  48. // We can skip anonymous namespace because:
  49. // 1. `FromContext` and `UseContext` must be in the same anonymous namespaces
  50. // since referencing across anonymous namespaces is not possible.
  51. // 2. If `FromContext` and `UseContext` are in the same anonymous namespace,
  52. // the function will still return `false` as expected.
  53. llvm::SmallVector<const NamespaceDecl *, 4> FromNamespaces =
  54. getAllNamedNamespaces(FromContext);
  55. llvm::SmallVector<const NamespaceDecl *, 4> UseNamespaces =
  56. getAllNamedNamespaces(UseContext);
  57. // If `UseContext` has fewer level of nested namespaces, it cannot be in the
  58. // same canonical namespace as the `FromContext`.
  59. if (UseNamespaces.size() < FromNamespaces.size())
  60. return false;
  61. unsigned Diff = UseNamespaces.size() - FromNamespaces.size();
  62. auto FromIter = FromNamespaces.begin();
  63. // Only compare `FromNamespaces` with namespaces in `UseNamespaces` that can
  64. // collide, i.e. the top N namespaces where N is the number of namespaces in
  65. // `FromNamespaces`.
  66. auto UseIter = UseNamespaces.begin() + Diff;
  67. for (; FromIter != FromNamespaces.end() && UseIter != UseNamespaces.end();
  68. ++FromIter, ++UseIter) {
  69. // Literally the same namespace, not a collision.
  70. if (*FromIter == *UseIter)
  71. return false;
  72. // Now check the names. If they match we have a different canonical
  73. // namespace with the same name.
  74. if (cast<NamespaceDecl>(*FromIter)->getDeclName() ==
  75. cast<NamespaceDecl>(*UseIter)->getDeclName())
  76. return true;
  77. }
  78. assert(FromIter == FromNamespaces.end() && UseIter == UseNamespaces.end());
  79. return false;
  80. }
  81. static StringRef getBestNamespaceSubstr(const DeclContext *DeclA,
  82. StringRef NewName,
  83. bool HadLeadingColonColon) {
  84. while (true) {
  85. while (DeclA && !isa<NamespaceDecl>(DeclA))
  86. DeclA = DeclA->getParent();
  87. // Fully qualified it is! Leave :: in place if it's there already.
  88. if (!DeclA)
  89. return HadLeadingColonColon ? NewName : NewName.substr(2);
  90. // Otherwise strip off redundant namespace qualifications from the new name.
  91. // We use the fully qualified name of the namespace and remove that part
  92. // from NewName if it has an identical prefix.
  93. std::string NS =
  94. "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() + "::";
  95. if (NewName.startswith(NS))
  96. return NewName.substr(NS.size());
  97. // No match yet. Strip of a namespace from the end of the chain and try
  98. // again. This allows to get optimal qualifications even if the old and new
  99. // decl only share common namespaces at a higher level.
  100. DeclA = DeclA->getParent();
  101. }
  102. }
  103. /// Check if the name specifier begins with a written "::".
  104. static bool isFullyQualified(const NestedNameSpecifier *NNS) {
  105. while (NNS) {
  106. if (NNS->getKind() == NestedNameSpecifier::Global)
  107. return true;
  108. NNS = NNS->getPrefix();
  109. }
  110. return false;
  111. }
  112. // Adds more scope specifier to the spelled name until the spelling is not
  113. // ambiguous. A spelling is ambiguous if the resolution of the symbol is
  114. // ambiguous. For example, if QName is "::y::bar", the spelling is "y::bar", and
  115. // context contains a nested namespace "a::y", then "y::bar" can be resolved to
  116. // ::a::y::bar in the context, which can cause compile error.
  117. // FIXME: consider using namespaces.
  118. static std::string disambiguateSpellingInScope(StringRef Spelling,
  119. StringRef QName,
  120. const DeclContext &UseContext,
  121. SourceLocation UseLoc) {
  122. assert(QName.startswith("::"));
  123. assert(QName.endswith(Spelling));
  124. if (Spelling.startswith("::"))
  125. return std::string(Spelling);
  126. auto UnspelledSpecifier = QName.drop_back(Spelling.size());
  127. llvm::SmallVector<llvm::StringRef, 2> UnspelledScopes;
  128. UnspelledSpecifier.split(UnspelledScopes, "::", /*MaxSplit=*/-1,
  129. /*KeepEmpty=*/false);
  130. llvm::SmallVector<const NamespaceDecl *, 4> EnclosingNamespaces =
  131. getAllNamedNamespaces(&UseContext);
  132. auto &AST = UseContext.getParentASTContext();
  133. StringRef TrimmedQName = QName.substr(2);
  134. const auto &SM = UseContext.getParentASTContext().getSourceManager();
  135. UseLoc = SM.getSpellingLoc(UseLoc);
  136. auto IsAmbiguousSpelling = [&](const llvm::StringRef CurSpelling) {
  137. if (CurSpelling.startswith("::"))
  138. return false;
  139. // Lookup the first component of Spelling in all enclosing namespaces
  140. // and check if there is any existing symbols with the same name but in
  141. // different scope.
  142. StringRef Head = CurSpelling.split("::").first;
  143. for (const auto *NS : EnclosingNamespaces) {
  144. auto LookupRes = NS->lookup(DeclarationName(&AST.Idents.get(Head)));
  145. if (!LookupRes.empty()) {
  146. for (const NamedDecl *Res : LookupRes)
  147. // If `Res` is not visible in `UseLoc`, we don't consider it
  148. // ambiguous. For example, a reference in a header file should not be
  149. // affected by a potentially ambiguous name in some file that includes
  150. // the header.
  151. if (!TrimmedQName.startswith(Res->getQualifiedNameAsString()) &&
  152. SM.isBeforeInTranslationUnit(
  153. SM.getSpellingLoc(Res->getLocation()), UseLoc))
  154. return true;
  155. }
  156. }
  157. return false;
  158. };
  159. // Add more qualifiers until the spelling is not ambiguous.
  160. std::string Disambiguated = std::string(Spelling);
  161. while (IsAmbiguousSpelling(Disambiguated)) {
  162. if (UnspelledScopes.empty()) {
  163. Disambiguated = "::" + Disambiguated;
  164. } else {
  165. Disambiguated = (UnspelledScopes.back() + "::" + Disambiguated).str();
  166. UnspelledScopes.pop_back();
  167. }
  168. }
  169. return Disambiguated;
  170. }
  171. std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
  172. SourceLocation UseLoc,
  173. const DeclContext *UseContext,
  174. const NamedDecl *FromDecl,
  175. StringRef ReplacementString) {
  176. assert(ReplacementString.startswith("::") &&
  177. "Expected fully-qualified name!");
  178. // We can do a raw name replacement when we are not inside the namespace for
  179. // the original class/function and it is not in the global namespace. The
  180. // assumption is that outside the original namespace we must have a using
  181. // statement that makes this work out and that other parts of this refactor
  182. // will automatically fix using statements to point to the new class/function.
  183. // However, if the `FromDecl` is a class forward declaration, the reference is
  184. // still considered as referring to the original definition, so we can't do a
  185. // raw name replacement in this case.
  186. const bool class_name_only = !Use;
  187. const bool in_global_namespace =
  188. isa<TranslationUnitDecl>(FromDecl->getDeclContext());
  189. const bool is_class_forward_decl =
  190. isa<CXXRecordDecl>(FromDecl) &&
  191. !cast<CXXRecordDecl>(FromDecl)->isCompleteDefinition();
  192. if (class_name_only && !in_global_namespace && !is_class_forward_decl &&
  193. !usingFromDifferentCanonicalNamespace(FromDecl->getDeclContext(),
  194. UseContext)) {
  195. auto Pos = ReplacementString.rfind("::");
  196. return std::string(Pos != StringRef::npos
  197. ? ReplacementString.substr(Pos + 2)
  198. : ReplacementString);
  199. }
  200. // We did not match this because of a using statement, so we will need to
  201. // figure out how good a namespace match we have with our destination type.
  202. // We work backwards (from most specific possible namespace to least
  203. // specific).
  204. StringRef Suggested = getBestNamespaceSubstr(UseContext, ReplacementString,
  205. isFullyQualified(Use));
  206. return disambiguateSpellingInScope(Suggested, ReplacementString, *UseContext,
  207. UseLoc);
  208. }