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()) {
232         if (const FieldDecl *Decl = D.getFieldDecl()) {
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     }
245     return true;
246   }
247 
248   bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
249     // Fix the constructor initializer when renaming class members.
250     for (const auto *Initializer : CD->inits()) {
251       // Ignore implicit initializers.
252       if (!Initializer->isWritten())
253         continue;
254 
255       if (const FieldDecl *FD = Initializer->getMember()) {
256         if (isInUSRSet(FD)) {
257           auto Loc = Initializer->getSourceLocation();
258           RenameInfos.push_back({Loc, Loc,
259                                  /*FromDecl=*/nullptr,
260                                  /*Context=*/nullptr,
261                                  /*Specifier=*/nullptr,
262                                  /*IgnorePrefixQualifiers=*/true});
263         }
264       }
265     }
266     return true;
267   }
268 
269   bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
270     const NamedDecl *Decl = Expr->getFoundDecl();
271     // Get the underlying declaration of the shadow declaration introduced by a
272     // using declaration.
273     if (auto *UsingShadow = llvm::dyn_cast<UsingShadowDecl>(Decl)) {
274       Decl = UsingShadow->getTargetDecl();
275     }
276 
277     auto StartLoc = Expr->getBeginLoc();
278     // For template function call expressions like `foo<int>()`, we want to
279     // restrict the end of location to just before the `<` character.
280     SourceLocation EndLoc = Expr->hasExplicitTemplateArgs()
281                                 ? Expr->getLAngleLoc().getLocWithOffset(-1)
282                                 : Expr->getEndLoc();
283 
284     if (const auto *MD = llvm::dyn_cast<CXXMethodDecl>(Decl)) {
285       if (isInUSRSet(MD)) {
286         // Handle renaming static template class methods, we only rename the
287         // name without prefix qualifiers and restrict the source range to the
288         // name.
289         RenameInfos.push_back({EndLoc, EndLoc,
290                                /*FromDecl=*/nullptr,
291                                /*Context=*/nullptr,
292                                /*Specifier=*/nullptr,
293                                /*IgnorePrefixQualifiers=*/true});
294         return true;
295       }
296     }
297 
298     // In case of renaming an enum declaration, we have to explicitly handle
299     // unscoped enum constants referenced in expressions (e.g.
300     // "auto r = ns1::ns2::Green" where Green is an enum constant of an unscoped
301     // enum decl "ns1::ns2::Color") as these enum constants cannot be caught by
302     // TypeLoc.
303     if (const auto *T = llvm::dyn_cast<EnumConstantDecl>(Decl)) {
304       // FIXME: Handle the enum constant without prefix qualifiers (`a = Green`)
305       // when renaming an unscoped enum declaration with a new namespace.
306       if (!Expr->hasQualifier())
307         return true;
308 
309       if (const auto *ED =
310               llvm::dyn_cast_or_null<EnumDecl>(getClosestAncestorDecl(*T))) {
311         if (ED->isScoped())
312           return true;
313         Decl = ED;
314       }
315       // The current fix would qualify "ns1::ns2::Green" as
316       // "ns1::ns2::Color::Green".
317       //
318       // Get the EndLoc of the replacement by moving 1 character backward (
319       // to exclude the last '::').
320       //
321       //    ns1::ns2::Green;
322       //    ^      ^^
323       // BeginLoc  |EndLoc of the qualifier
324       //           new EndLoc
325       EndLoc = Expr->getQualifierLoc().getEndLoc().getLocWithOffset(-1);
326       assert(EndLoc.isValid() &&
327              "The enum constant should have prefix qualifers.");
328     }
329     if (isInUSRSet(Decl) &&
330         IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
331       RenameInfo Info = {StartLoc,
332                          EndLoc,
333                          Decl,
334                          getClosestAncestorDecl(*Expr),
335                          Expr->getQualifier(),
336                          /*IgnorePrefixQualifers=*/false};
337       RenameInfos.push_back(Info);
338     }
339 
340     return true;
341   }
342 
343   bool VisitUsingDecl(const UsingDecl *Using) {
344     for (const auto *UsingShadow : Using->shadows()) {
345       if (isInUSRSet(UsingShadow->getTargetDecl())) {
346         UsingDecls.push_back(Using);
347         break;
348       }
349     }
350     return true;
351   }
352 
353   bool VisitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
354     if (!NestedLoc.getNestedNameSpecifier()->getAsType())
355       return true;
356 
357     if (const auto *TargetDecl =
358             getSupportedDeclFromTypeLoc(NestedLoc.getTypeLoc())) {
359       if (isInUSRSet(TargetDecl)) {
360         RenameInfo Info = {NestedLoc.getBeginLoc(),
361                            EndLocationForType(NestedLoc.getTypeLoc()),
362                            TargetDecl,
363                            getClosestAncestorDecl(NestedLoc),
364                            NestedLoc.getNestedNameSpecifier()->getPrefix(),
365                            /*IgnorePrefixQualifers=*/false};
366         RenameInfos.push_back(Info);
367       }
368     }
369     return true;
370   }
371 
372   bool VisitTypeLoc(TypeLoc Loc) {
373     auto Parents = Context.getParents(Loc);
374     TypeLoc ParentTypeLoc;
375     if (!Parents.empty()) {
376       // Handle cases of nested name specificier locations.
377       //
378       // The VisitNestedNameSpecifierLoc interface is not impelmented in
379       // RecursiveASTVisitor, we have to handle it explicitly.
380       if (const auto *NSL = Parents[0].get<NestedNameSpecifierLoc>()) {
381         VisitNestedNameSpecifierLocations(*NSL);
382         return true;
383       }
384 
385       if (const auto *TL = Parents[0].get<TypeLoc>())
386         ParentTypeLoc = *TL;
387     }
388 
389     // Handle the outermost TypeLoc which is directly linked to the interesting
390     // declaration and don't handle nested name specifier locations.
391     if (const auto *TargetDecl = getSupportedDeclFromTypeLoc(Loc)) {
392       if (isInUSRSet(TargetDecl)) {
393         // Only handle the outermost typeLoc.
394         //
395         // For a type like "a::Foo", there will be two typeLocs for it.
396         // One ElaboratedType, the other is RecordType:
397         //
398         //   ElaboratedType 0x33b9390 'a::Foo' sugar
399         //   `-RecordType 0x338fef0 'class a::Foo'
400         //     `-CXXRecord 0x338fe58 'Foo'
401         //
402         // Skip if this is an inner typeLoc.
403         if (!ParentTypeLoc.isNull() &&
404             isInUSRSet(getSupportedDeclFromTypeLoc(ParentTypeLoc)))
405           return true;
406 
407         auto StartLoc = StartLocationForType(Loc);
408         auto EndLoc = EndLocationForType(Loc);
409         if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
410           RenameInfo Info = {StartLoc,
411                              EndLoc,
412                              TargetDecl,
413                              getClosestAncestorDecl(Loc),
414                              GetNestedNameForType(Loc),
415                              /*IgnorePrefixQualifers=*/false};
416           RenameInfos.push_back(Info);
417         }
418         return true;
419       }
420     }
421 
422     // Handle specific template class specialiation cases.
423     if (const auto *TemplateSpecType =
424             dyn_cast<TemplateSpecializationType>(Loc.getType())) {
425       TypeLoc TargetLoc = Loc;
426       if (!ParentTypeLoc.isNull()) {
427         if (llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
428           TargetLoc = ParentTypeLoc;
429       }
430 
431       if (isInUSRSet(TemplateSpecType->getTemplateName().getAsTemplateDecl())) {
432         TypeLoc TargetLoc = Loc;
433         // FIXME: Find a better way to handle this case.
434         // For the qualified template class specification type like
435         // "ns::Foo<int>" in "ns::Foo<int>& f();", we want the parent typeLoc
436         // (ElaboratedType) of the TemplateSpecializationType in order to
437         // catch the prefix qualifiers "ns::".
438         if (!ParentTypeLoc.isNull() &&
439             llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
440           TargetLoc = ParentTypeLoc;
441 
442         auto StartLoc = StartLocationForType(TargetLoc);
443         auto EndLoc = EndLocationForType(TargetLoc);
444         if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
445           RenameInfo Info = {
446               StartLoc,
447               EndLoc,
448               TemplateSpecType->getTemplateName().getAsTemplateDecl(),
449               getClosestAncestorDecl(DynTypedNode::create(TargetLoc)),
450               GetNestedNameForType(TargetLoc),
451               /*IgnorePrefixQualifers=*/false};
452           RenameInfos.push_back(Info);
453         }
454       }
455     }
456     return true;
457   }
458 
459   // Returns a list of RenameInfo.
460   const std::vector<RenameInfo> &getRenameInfos() const { return RenameInfos; }
461 
462   // Returns a list of using declarations which are needed to update.
463   const std::vector<const UsingDecl *> &getUsingDecls() const {
464     return UsingDecls;
465   }
466 
467 private:
468   // Get the supported declaration from a given typeLoc. If the declaration type
469   // is not supported, returns nullptr.
470   const NamedDecl *getSupportedDeclFromTypeLoc(TypeLoc Loc) {
471     if (const auto* TT = Loc.getType()->getAs<clang::TypedefType>())
472       return TT->getDecl();
473     if (const auto *RD = Loc.getType()->getAsCXXRecordDecl())
474       return RD;
475     if (const auto *ED =
476             llvm::dyn_cast_or_null<EnumDecl>(Loc.getType()->getAsTagDecl()))
477       return ED;
478     return nullptr;
479   }
480 
481   // Get the closest ancester which is a declaration of a given AST node.
482   template <typename ASTNodeType>
483   const Decl *getClosestAncestorDecl(const ASTNodeType &Node) {
484     auto Parents = Context.getParents(Node);
485     // FIXME: figure out how to handle it when there are multiple parents.
486     if (Parents.size() != 1)
487       return nullptr;
488     if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(Parents[0].getNodeKind()))
489       return Parents[0].template get<Decl>();
490     return getClosestAncestorDecl(Parents[0]);
491   }
492 
493   // Get the parent typeLoc of a given typeLoc. If there is no such parent,
494   // return nullptr.
495   const TypeLoc *getParentTypeLoc(TypeLoc Loc) const {
496     auto Parents = Context.getParents(Loc);
497     // FIXME: figure out how to handle it when there are multiple parents.
498     if (Parents.size() != 1)
499       return nullptr;
500     return Parents[0].get<TypeLoc>();
501   }
502 
503   // Check whether the USR of a given Decl is in the USRSet.
504   bool isInUSRSet(const Decl *Decl) const {
505     auto USR = getUSRForDecl(Decl);
506     if (USR.empty())
507       return false;
508     return llvm::is_contained(USRSet, USR);
509   }
510 
511   const std::set<std::string> USRSet;
512   ASTContext &Context;
513   std::vector<RenameInfo> RenameInfos;
514   // Record all interested using declarations which contains the using-shadow
515   // declarations of the symbol declarations being renamed.
516   std::vector<const UsingDecl *> UsingDecls;
517 };
518 
519 } // namespace
520 
521 SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs,
522                                        StringRef PrevName, Decl *Decl) {
523   USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
524   Visitor.TraverseDecl(Decl);
525   return Visitor.takeOccurrences();
526 }
527 
528 std::vector<tooling::AtomicChange>
529 createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
530                           llvm::StringRef NewName, Decl *TranslationUnitDecl) {
531   RenameLocFinder Finder(USRs, TranslationUnitDecl->getASTContext());
532   Finder.TraverseDecl(TranslationUnitDecl);
533 
534   const SourceManager &SM =
535       TranslationUnitDecl->getASTContext().getSourceManager();
536 
537   std::vector<tooling::AtomicChange> AtomicChanges;
538   auto Replace = [&](SourceLocation Start, SourceLocation End,
539                      llvm::StringRef Text) {
540     tooling::AtomicChange ReplaceChange = tooling::AtomicChange(SM, Start);
541     llvm::Error Err = ReplaceChange.replace(
542         SM, CharSourceRange::getTokenRange(Start, End), Text);
543     if (Err) {
544       llvm::errs() << "Failed to add replacement to AtomicChange: "
545                    << llvm::toString(std::move(Err)) << "\n";
546       return;
547     }
548     AtomicChanges.push_back(std::move(ReplaceChange));
549   };
550 
551   for (const auto &RenameInfo : Finder.getRenameInfos()) {
552     std::string ReplacedName = NewName.str();
553     if (RenameInfo.IgnorePrefixQualifers) {
554       // Get the name without prefix qualifiers from NewName.
555       size_t LastColonPos = NewName.find_last_of(':');
556       if (LastColonPos != std::string::npos)
557         ReplacedName = std::string(NewName.substr(LastColonPos + 1));
558     } else {
559       if (RenameInfo.FromDecl && RenameInfo.Context) {
560         if (!llvm::isa<clang::TranslationUnitDecl>(
561                 RenameInfo.Context->getDeclContext())) {
562           ReplacedName = tooling::replaceNestedName(
563               RenameInfo.Specifier, RenameInfo.Begin,
564               RenameInfo.Context->getDeclContext(), RenameInfo.FromDecl,
565               NewName.startswith("::") ? NewName.str()
566                                        : ("::" + NewName).str());
567         } else {
568           // This fixes the case where type `T` is a parameter inside a function
569           // type (e.g. `std::function<void(T)>`) and the DeclContext of `T`
570           // becomes the translation unit. As a workaround, we simply use
571           // fully-qualified name here for all references whose `DeclContext` is
572           // the translation unit and ignore the possible existence of
573           // using-decls (in the global scope) that can shorten the replaced
574           // name.
575           llvm::StringRef ActualName = Lexer::getSourceText(
576               CharSourceRange::getTokenRange(
577                   SourceRange(RenameInfo.Begin, RenameInfo.End)),
578               SM, TranslationUnitDecl->getASTContext().getLangOpts());
579           // Add the leading "::" back if the name written in the code contains
580           // it.
581           if (ActualName.startswith("::") && !NewName.startswith("::")) {
582             ReplacedName = "::" + NewName.str();
583           }
584         }
585       }
586       // If the NewName contains leading "::", add it back.
587       if (NewName.startswith("::") && NewName.substr(2) == ReplacedName)
588         ReplacedName = NewName.str();
589     }
590     Replace(RenameInfo.Begin, RenameInfo.End, ReplacedName);
591   }
592 
593   // Hanlde using declarations explicitly as "using a::Foo" don't trigger
594   // typeLoc for "a::Foo".
595   for (const auto *Using : Finder.getUsingDecls())
596     Replace(Using->getBeginLoc(), Using->getEndLoc(), "using " + NewName.str());
597 
598   return AtomicChanges;
599 }
600 
601 } // end namespace tooling
602 } // end namespace clang
603