Home | History | Annotate | Line # | Download | only in Rename
      1 //===--- USRLocFinder.cpp - Clang refactoring library ---------------------===//
      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 /// \file
     10 /// Methods for finding all instances of a USR. Our strategy is very
     11 /// simple; we just compare the USR at every relevant AST node with the one
     12 /// provided.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
     17 #include "clang/AST/ASTContext.h"
     18 #include "clang/AST/ParentMapContext.h"
     19 #include "clang/AST/RecursiveASTVisitor.h"
     20 #include "clang/Basic/LLVM.h"
     21 #include "clang/Basic/SourceLocation.h"
     22 #include "clang/Basic/SourceManager.h"
     23 #include "clang/Lex/Lexer.h"
     24 #include "clang/Tooling/Refactoring/Lookup.h"
     25 #include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
     26 #include "clang/Tooling/Refactoring/Rename/SymbolName.h"
     27 #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
     28 #include "llvm/ADT/StringRef.h"
     29 #include "llvm/Support/Casting.h"
     30 #include <cstddef>
     31 #include <set>
     32 #include <string>
     33 #include <vector>
     34 
     35 using namespace llvm;
     36 
     37 namespace clang {
     38 namespace tooling {
     39 
     40 namespace {
     41 
     42 // Returns true if the given Loc is valid for edit. We don't edit the
     43 // SourceLocations that are valid or in temporary buffer.
     44 bool IsValidEditLoc(const clang::SourceManager& SM, clang::SourceLocation Loc) {
     45   if (Loc.isInvalid())
     46     return false;
     47   const clang::FullSourceLoc FullLoc(Loc, SM);
     48   std::pair<clang::FileID, unsigned> FileIdAndOffset =
     49       FullLoc.getSpellingLoc().getDecomposedLoc();
     50   return SM.getFileEntryForID(FileIdAndOffset.first) != nullptr;
     51 }
     52 
     53 // This visitor recursively searches for all instances of a USR in a
     54 // translation unit and stores them for later usage.
     55 class USRLocFindingASTVisitor
     56     : public RecursiveSymbolVisitor<USRLocFindingASTVisitor> {
     57 public:
     58   explicit USRLocFindingASTVisitor(const std::vector<std::string> &USRs,
     59                                    StringRef PrevName,
     60                                    const ASTContext &Context)
     61       : RecursiveSymbolVisitor(Context.getSourceManager(),
     62                                Context.getLangOpts()),
     63         USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
     64   }
     65 
     66   bool visitSymbolOccurrence(const NamedDecl *ND,
     67                              ArrayRef<SourceRange> NameRanges) {
     68     if (USRSet.find(getUSRForDecl(ND)) != USRSet.end()) {
     69       assert(NameRanges.size() == 1 &&
     70              "Multiple name pieces are not supported yet!");
     71       SourceLocation Loc = NameRanges[0].getBegin();
     72       const SourceManager &SM = Context.getSourceManager();
     73       // TODO: Deal with macro occurrences correctly.
     74       if (Loc.isMacroID())
     75         Loc = SM.getSpellingLoc(Loc);
     76       checkAndAddLocation(Loc);
     77     }
     78     return true;
     79   }
     80 
     81   // Non-visitors:
     82 
     83   /// Returns a set of unique symbol occurrences. Duplicate or
     84   /// overlapping occurrences are erroneous and should be reported!
     85   SymbolOccurrences takeOccurrences() { return std::move(Occurrences); }
     86 
     87 private:
     88   void checkAndAddLocation(SourceLocation Loc) {
     89     const SourceLocation BeginLoc = Loc;
     90     const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
     91         BeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
     92     StringRef TokenName =
     93         Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
     94                              Context.getSourceManager(), Context.getLangOpts());
     95     size_t Offset = TokenName.find(PrevName.getNamePieces()[0]);
     96 
     97     // The token of the source location we find actually has the old
     98     // name.
     99     if (Offset != StringRef::npos)
    100       Occurrences.emplace_back(PrevName, SymbolOccurrence::MatchingSymbol,
    101                                BeginLoc.getLocWithOffset(Offset));
    102   }
    103 
    104   const std::set<std::string> USRSet;
    105   const SymbolName PrevName;
    106   SymbolOccurrences Occurrences;
    107   const ASTContext &Context;
    108 };
    109 
    110 SourceLocation StartLocationForType(TypeLoc TL) {
    111   // For elaborated types (e.g. `struct a::A`) we want the portion after the
    112   // `struct` but including the namespace qualifier, `a::`.
    113   if (auto ElaboratedTypeLoc = TL.getAs<clang::ElaboratedTypeLoc>()) {
    114     NestedNameSpecifierLoc NestedNameSpecifier =
    115         ElaboratedTypeLoc.getQualifierLoc();
    116     if (NestedNameSpecifier.getNestedNameSpecifier())
    117       return NestedNameSpecifier.getBeginLoc();
    118     TL = TL.getNextTypeLoc();
    119   }
    120   return TL.getBeginLoc();
    121 }
    122 
    123 SourceLocation EndLocationForType(TypeLoc TL) {
    124   // Dig past any namespace or keyword qualifications.
    125   while (TL.getTypeLocClass() == TypeLoc::Elaborated ||
    126          TL.getTypeLocClass() == TypeLoc::Qualified)
    127     TL = TL.getNextTypeLoc();
    128 
    129   // The location for template specializations (e.g. Foo<int>) includes the
    130   // templated types in its location range.  We want to restrict this to just
    131   // before the `<` character.
    132   if (TL.getTypeLocClass() == TypeLoc::TemplateSpecialization) {
    133     return TL.castAs<TemplateSpecializationTypeLoc>()
    134         .getLAngleLoc()
    135         .getLocWithOffset(-1);
    136   }
    137   return TL.getEndLoc();
    138 }
    139 
    140 NestedNameSpecifier *GetNestedNameForType(TypeLoc TL) {
    141   // Dig past any keyword qualifications.
    142   while (TL.getTypeLocClass() == TypeLoc::Qualified)
    143     TL = TL.getNextTypeLoc();
    144 
    145   // For elaborated types (e.g. `struct a::A`) we want the portion after the
    146   // `struct` but including the namespace qualifier, `a::`.
    147   if (auto ElaboratedTypeLoc = TL.getAs<clang::ElaboratedTypeLoc>())
    148     return ElaboratedTypeLoc.getQualifierLoc().getNestedNameSpecifier();
    149   return nullptr;
    150 }
    151 
    152 // Find all locations identified by the given USRs for rename.
    153 //
    154 // This class will traverse the AST and find every AST node whose USR is in the
    155 // given USRs' set.
    156 class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
    157 public:
    158   RenameLocFinder(llvm::ArrayRef<std::string> USRs, ASTContext &Context)
    159       : USRSet(USRs.begin(), USRs.end()), Context(Context) {}
    160 
    161   // A structure records all information of a symbol reference being renamed.
    162   // We try to add as few prefix qualifiers as possible.
    163   struct RenameInfo {
    164     // The begin location of a symbol being renamed.
    165     SourceLocation Begin;
    166     // The end location of a symbol being renamed.
    167     SourceLocation End;
    168     // The declaration of a symbol being renamed (can be nullptr).
    169     const NamedDecl *FromDecl;
    170     // The declaration in which the nested name is contained (can be nullptr).
    171     const Decl *Context;
    172     // The nested name being replaced (can be nullptr).
    173     const NestedNameSpecifier *Specifier;
    174     // Determine whether the prefix qualifiers of the NewName should be ignored.
    175     // Normally, we set it to true for the symbol declaration and definition to
    176     // avoid adding prefix qualifiers.
    177     // For example, if it is true and NewName is "a::b::foo", then the symbol
    178     // occurrence which the RenameInfo points to will be renamed to "foo".
    179     bool IgnorePrefixQualifers;
    180   };
    181 
    182   bool VisitNamedDecl(const NamedDecl *Decl) {
    183     // UsingDecl has been handled in other place.
    184     if (llvm::isa<UsingDecl>(Decl))
    185       return true;
    186 
    187     // DestructorDecl has been handled in Typeloc.
    188     if (llvm::isa<CXXDestructorDecl>(Decl))
    189       return true;
    190 
    191     if (Decl->isImplicit())
    192       return true;
    193 
    194     if (isInUSRSet(Decl)) {
    195       // For the case of renaming an alias template, we actually rename the
    196       // underlying alias declaration of the template.
    197       if (const auto* TAT = dyn_cast<TypeAliasTemplateDecl>(Decl))
    198         Decl = TAT->getTemplatedDecl();
    199 
    200       auto StartLoc = Decl->getLocation();
    201       auto EndLoc = StartLoc;
    202       if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
    203         RenameInfo Info = {StartLoc,
    204                            EndLoc,
    205                            /*FromDecl=*/nullptr,
    206                            /*Context=*/nullptr,
    207                            /*Specifier=*/nullptr,
    208                            /*IgnorePrefixQualifers=*/true};
    209         RenameInfos.push_back(Info);
    210       }
    211     }
    212     return true;
    213   }
    214 
    215   bool VisitMemberExpr(const MemberExpr *Expr) {
    216     const NamedDecl *Decl = Expr->getFoundDecl();
    217     auto StartLoc = Expr->getMemberLoc();
    218     auto EndLoc = Expr->getMemberLoc();
    219     if (isInUSRSet(Decl)) {
    220       RenameInfos.push_back({StartLoc, EndLoc,
    221                             /*FromDecl=*/nullptr,
    222                             /*Context=*/nullptr,
    223                             /*Specifier=*/nullptr,
    224                             /*IgnorePrefixQualifiers=*/true});
    225     }
    226     return true;
    227   }
    228 
    229   bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
    230     for (const DesignatedInitExpr::Designator &D : E->designators()) {
    231       if (D.isFieldDesignator() && D.getField()) {
    232         const FieldDecl *Decl = D.getField();
    233         if (isInUSRSet(Decl)) {
    234           auto StartLoc = D.getFieldLoc();
    235           auto EndLoc = D.getFieldLoc();
    236           RenameInfos.push_back({StartLoc, EndLoc,
    237                                  /*FromDecl=*/nullptr,
    238                                  /*Context=*/nullptr,
    239                                  /*Specifier=*/nullptr,
    240                                  /*IgnorePrefixQualifiers=*/true});
    241         }
    242       }
    243     }
    244     return true;
    245   }
    246 
    247   bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
    248     // Fix the constructor initializer when renaming class members.
    249     for (const auto *Initializer : CD->inits()) {
    250       // Ignore implicit initializers.
    251       if (!Initializer->isWritten())
    252         continue;
    253 
    254       if (const FieldDecl *FD = Initializer->getMember()) {
    255         if (isInUSRSet(FD)) {
    256           auto Loc = Initializer->getSourceLocation();
    257           RenameInfos.push_back({Loc, Loc,
    258                                  /*FromDecl=*/nullptr,
    259                                  /*Context=*/nullptr,
    260                                  /*Specifier=*/nullptr,
    261                                  /*IgnorePrefixQualifiers=*/true});
    262         }
    263       }
    264     }
    265     return true;
    266   }
    267 
    268   bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
    269     const NamedDecl *Decl = Expr->getFoundDecl();
    270     // Get the underlying declaration of the shadow declaration introduced by a
    271     // using declaration.
    272     if (auto *UsingShadow = llvm::dyn_cast<UsingShadowDecl>(Decl)) {
    273       Decl = UsingShadow->getTargetDecl();
    274     }
    275 
    276     auto StartLoc = Expr->getBeginLoc();
    277     // For template function call expressions like `foo<int>()`, we want to
    278     // restrict the end of location to just before the `<` character.
    279     SourceLocation EndLoc = Expr->hasExplicitTemplateArgs()
    280                                 ? Expr->getLAngleLoc().getLocWithOffset(-1)
    281                                 : Expr->getEndLoc();
    282 
    283     if (const auto *MD = llvm::dyn_cast<CXXMethodDecl>(Decl)) {
    284       if (isInUSRSet(MD)) {
    285         // Handle renaming static template class methods, we only rename the
    286         // name without prefix qualifiers and restrict the source range to the
    287         // name.
    288         RenameInfos.push_back({EndLoc, EndLoc,
    289                                /*FromDecl=*/nullptr,
    290                                /*Context=*/nullptr,
    291                                /*Specifier=*/nullptr,
    292                                /*IgnorePrefixQualifiers=*/true});
    293         return true;
    294       }
    295     }
    296 
    297     // In case of renaming an enum declaration, we have to explicitly handle
    298     // unscoped enum constants referenced in expressions (e.g.
    299     // "auto r = ns1::ns2::Green" where Green is an enum constant of an unscoped
    300     // enum decl "ns1::ns2::Color") as these enum constants cannot be caught by
    301     // TypeLoc.
    302     if (const auto *T = llvm::dyn_cast<EnumConstantDecl>(Decl)) {
    303       // FIXME: Handle the enum constant without prefix qualifiers (`a = Green`)
    304       // when renaming an unscoped enum declaration with a new namespace.
    305       if (!Expr->hasQualifier())
    306         return true;
    307 
    308       if (const auto *ED =
    309               llvm::dyn_cast_or_null<EnumDecl>(getClosestAncestorDecl(*T))) {
    310         if (ED->isScoped())
    311           return true;
    312         Decl = ED;
    313       }
    314       // The current fix would qualify "ns1::ns2::Green" as
    315       // "ns1::ns2::Color::Green".
    316       //
    317       // Get the EndLoc of the replacement by moving 1 character backward (
    318       // to exclude the last '::').
    319       //
    320       //    ns1::ns2::Green;
    321       //    ^      ^^
    322       // BeginLoc  |EndLoc of the qualifier
    323       //           new EndLoc
    324       EndLoc = Expr->getQualifierLoc().getEndLoc().getLocWithOffset(-1);
    325       assert(EndLoc.isValid() &&
    326              "The enum constant should have prefix qualifers.");
    327     }
    328     if (isInUSRSet(Decl) &&
    329         IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
    330       RenameInfo Info = {StartLoc,
    331                          EndLoc,
    332                          Decl,
    333                          getClosestAncestorDecl(*Expr),
    334                          Expr->getQualifier(),
    335                          /*IgnorePrefixQualifers=*/false};
    336       RenameInfos.push_back(Info);
    337     }
    338 
    339     return true;
    340   }
    341 
    342   bool VisitUsingDecl(const UsingDecl *Using) {
    343     for (const auto *UsingShadow : Using->shadows()) {
    344       if (isInUSRSet(UsingShadow->getTargetDecl())) {
    345         UsingDecls.push_back(Using);
    346         break;
    347       }
    348     }
    349     return true;
    350   }
    351 
    352   bool VisitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
    353     if (!NestedLoc.getNestedNameSpecifier()->getAsType())
    354       return true;
    355 
    356     if (const auto *TargetDecl =
    357             getSupportedDeclFromTypeLoc(NestedLoc.getTypeLoc())) {
    358       if (isInUSRSet(TargetDecl)) {
    359         RenameInfo Info = {NestedLoc.getBeginLoc(),
    360                            EndLocationForType(NestedLoc.getTypeLoc()),
    361                            TargetDecl,
    362                            getClosestAncestorDecl(NestedLoc),
    363                            NestedLoc.getNestedNameSpecifier()->getPrefix(),
    364                            /*IgnorePrefixQualifers=*/false};
    365         RenameInfos.push_back(Info);
    366       }
    367     }
    368     return true;
    369   }
    370 
    371   bool VisitTypeLoc(TypeLoc Loc) {
    372     auto Parents = Context.getParents(Loc);
    373     TypeLoc ParentTypeLoc;
    374     if (!Parents.empty()) {
    375       // Handle cases of nested name specificier locations.
    376       //
    377       // The VisitNestedNameSpecifierLoc interface is not impelmented in
    378       // RecursiveASTVisitor, we have to handle it explicitly.
    379       if (const auto *NSL = Parents[0].get<NestedNameSpecifierLoc>()) {
    380         VisitNestedNameSpecifierLocations(*NSL);
    381         return true;
    382       }
    383 
    384       if (const auto *TL = Parents[0].get<TypeLoc>())
    385         ParentTypeLoc = *TL;
    386     }
    387 
    388     // Handle the outermost TypeLoc which is directly linked to the interesting
    389     // declaration and don't handle nested name specifier locations.
    390     if (const auto *TargetDecl = getSupportedDeclFromTypeLoc(Loc)) {
    391       if (isInUSRSet(TargetDecl)) {
    392         // Only handle the outermost typeLoc.
    393         //
    394         // For a type like "a::Foo", there will be two typeLocs for it.
    395         // One ElaboratedType, the other is RecordType:
    396         //
    397         //   ElaboratedType 0x33b9390 'a::Foo' sugar
    398         //   `-RecordType 0x338fef0 'class a::Foo'
    399         //     `-CXXRecord 0x338fe58 'Foo'
    400         //
    401         // Skip if this is an inner typeLoc.
    402         if (!ParentTypeLoc.isNull() &&
    403             isInUSRSet(getSupportedDeclFromTypeLoc(ParentTypeLoc)))
    404           return true;
    405 
    406         auto StartLoc = StartLocationForType(Loc);
    407         auto EndLoc = EndLocationForType(Loc);
    408         if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
    409           RenameInfo Info = {StartLoc,
    410                              EndLoc,
    411                              TargetDecl,
    412                              getClosestAncestorDecl(Loc),
    413                              GetNestedNameForType(Loc),
    414                              /*IgnorePrefixQualifers=*/false};
    415           RenameInfos.push_back(Info);
    416         }
    417         return true;
    418       }
    419     }
    420 
    421     // Handle specific template class specialiation cases.
    422     if (const auto *TemplateSpecType =
    423             dyn_cast<TemplateSpecializationType>(Loc.getType())) {
    424       TypeLoc TargetLoc = Loc;
    425       if (!ParentTypeLoc.isNull()) {
    426         if (llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
    427           TargetLoc = ParentTypeLoc;
    428       }
    429 
    430       if (isInUSRSet(TemplateSpecType->getTemplateName().getAsTemplateDecl())) {
    431         TypeLoc TargetLoc = Loc;
    432         // FIXME: Find a better way to handle this case.
    433         // For the qualified template class specification type like
    434         // "ns::Foo<int>" in "ns::Foo<int>& f();", we want the parent typeLoc
    435         // (ElaboratedType) of the TemplateSpecializationType in order to
    436         // catch the prefix qualifiers "ns::".
    437         if (!ParentTypeLoc.isNull() &&
    438             llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
    439           TargetLoc = ParentTypeLoc;
    440 
    441         auto StartLoc = StartLocationForType(TargetLoc);
    442         auto EndLoc = EndLocationForType(TargetLoc);
    443         if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
    444           RenameInfo Info = {
    445               StartLoc,
    446               EndLoc,
    447               TemplateSpecType->getTemplateName().getAsTemplateDecl(),
    448               getClosestAncestorDecl(DynTypedNode::create(TargetLoc)),
    449               GetNestedNameForType(TargetLoc),
    450               /*IgnorePrefixQualifers=*/false};
    451           RenameInfos.push_back(Info);
    452         }
    453       }
    454     }
    455     return true;
    456   }
    457 
    458   // Returns a list of RenameInfo.
    459   const std::vector<RenameInfo> &getRenameInfos() const { return RenameInfos; }
    460 
    461   // Returns a list of using declarations which are needed to update.
    462   const std::vector<const UsingDecl *> &getUsingDecls() const {
    463     return UsingDecls;
    464   }
    465 
    466 private:
    467   // Get the supported declaration from a given typeLoc. If the declaration type
    468   // is not supported, returns nullptr.
    469   const NamedDecl *getSupportedDeclFromTypeLoc(TypeLoc Loc) {
    470     if (const auto* TT = Loc.getType()->getAs<clang::TypedefType>())
    471       return TT->getDecl();
    472     if (const auto *RD = Loc.getType()->getAsCXXRecordDecl())
    473       return RD;
    474     if (const auto *ED =
    475             llvm::dyn_cast_or_null<EnumDecl>(Loc.getType()->getAsTagDecl()))
    476       return ED;
    477     return nullptr;
    478   }
    479 
    480   // Get the closest ancester which is a declaration of a given AST node.
    481   template <typename ASTNodeType>
    482   const Decl *getClosestAncestorDecl(const ASTNodeType &Node) {
    483     auto Parents = Context.getParents(Node);
    484     // FIXME: figure out how to handle it when there are multiple parents.
    485     if (Parents.size() != 1)
    486       return nullptr;
    487     if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(Parents[0].getNodeKind()))
    488       return Parents[0].template get<Decl>();
    489     return getClosestAncestorDecl(Parents[0]);
    490   }
    491 
    492   // Get the parent typeLoc of a given typeLoc. If there is no such parent,
    493   // return nullptr.
    494   const TypeLoc *getParentTypeLoc(TypeLoc Loc) const {
    495     auto Parents = Context.getParents(Loc);
    496     // FIXME: figure out how to handle it when there are multiple parents.
    497     if (Parents.size() != 1)
    498       return nullptr;
    499     return Parents[0].get<TypeLoc>();
    500   }
    501 
    502   // Check whether the USR of a given Decl is in the USRSet.
    503   bool isInUSRSet(const Decl *Decl) const {
    504     auto USR = getUSRForDecl(Decl);
    505     if (USR.empty())
    506       return false;
    507     return llvm::is_contained(USRSet, USR);
    508   }
    509 
    510   const std::set<std::string> USRSet;
    511   ASTContext &Context;
    512   std::vector<RenameInfo> RenameInfos;
    513   // Record all interested using declarations which contains the using-shadow
    514   // declarations of the symbol declarations being renamed.
    515   std::vector<const UsingDecl *> UsingDecls;
    516 };
    517 
    518 } // namespace
    519 
    520 SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs,
    521                                        StringRef PrevName, Decl *Decl) {
    522   USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
    523   Visitor.TraverseDecl(Decl);
    524   return Visitor.takeOccurrences();
    525 }
    526 
    527 std::vector<tooling::AtomicChange>
    528 createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
    529                           llvm::StringRef NewName, Decl *TranslationUnitDecl) {
    530   RenameLocFinder Finder(USRs, TranslationUnitDecl->getASTContext());
    531   Finder.TraverseDecl(TranslationUnitDecl);
    532 
    533   const SourceManager &SM =
    534       TranslationUnitDecl->getASTContext().getSourceManager();
    535 
    536   std::vector<tooling::AtomicChange> AtomicChanges;
    537   auto Replace = [&](SourceLocation Start, SourceLocation End,
    538                      llvm::StringRef Text) {
    539     tooling::AtomicChange ReplaceChange = tooling::AtomicChange(SM, Start);
    540     llvm::Error Err = ReplaceChange.replace(
    541         SM, CharSourceRange::getTokenRange(Start, End), Text);
    542     if (Err) {
    543       llvm::errs() << "Failed to add replacement to AtomicChange: "
    544                    << llvm::toString(std::move(Err)) << "\n";
    545       return;
    546     }
    547     AtomicChanges.push_back(std::move(ReplaceChange));
    548   };
    549 
    550   for (const auto &RenameInfo : Finder.getRenameInfos()) {
    551     std::string ReplacedName = NewName.str();
    552     if (RenameInfo.IgnorePrefixQualifers) {
    553       // Get the name without prefix qualifiers from NewName.
    554       size_t LastColonPos = NewName.find_last_of(':');
    555       if (LastColonPos != std::string::npos)
    556         ReplacedName = std::string(NewName.substr(LastColonPos + 1));
    557     } else {
    558       if (RenameInfo.FromDecl && RenameInfo.Context) {
    559         if (!llvm::isa<clang::TranslationUnitDecl>(
    560                 RenameInfo.Context->getDeclContext())) {
    561           ReplacedName = tooling::replaceNestedName(
    562               RenameInfo.Specifier, RenameInfo.Begin,
    563               RenameInfo.Context->getDeclContext(), RenameInfo.FromDecl,
    564               NewName.startswith("::") ? NewName.str()
    565                                        : ("::" + NewName).str());
    566         } else {
    567           // This fixes the case where type `T` is a parameter inside a function
    568           // type (e.g. `std::function<void(T)>`) and the DeclContext of `T`
    569           // becomes the translation unit. As a workaround, we simply use
    570           // fully-qualified name here for all references whose `DeclContext` is
    571           // the translation unit and ignore the possible existence of
    572           // using-decls (in the global scope) that can shorten the replaced
    573           // name.
    574           llvm::StringRef ActualName = Lexer::getSourceText(
    575               CharSourceRange::getTokenRange(
    576                   SourceRange(RenameInfo.Begin, RenameInfo.End)),
    577               SM, TranslationUnitDecl->getASTContext().getLangOpts());
    578           // Add the leading "::" back if the name written in the code contains
    579           // it.
    580           if (ActualName.startswith("::") && !NewName.startswith("::")) {
    581             ReplacedName = "::" + NewName.str();
    582           }
    583         }
    584       }
    585       // If the NewName contains leading "::", add it back.
    586       if (NewName.startswith("::") && NewName.substr(2) == ReplacedName)
    587         ReplacedName = NewName.str();
    588     }
    589     Replace(RenameInfo.Begin, RenameInfo.End, ReplacedName);
    590   }
    591 
    592   // Hanlde using declarations explicitly as "using a::Foo" don't trigger
    593   // typeLoc for "a::Foo".
    594   for (const auto *Using : Finder.getUsingDecls())
    595     Replace(Using->getBeginLoc(), Using->getEndLoc(), "using " + NewName.str());
    596 
    597   return AtomicChanges;
    598 }
    599 
    600 } // end namespace tooling
    601 } // end namespace clang
    602