xref: /llvm-project/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (revision d2a96d170a4faa0a6c42fe5f23c073891d6118b8)
1 //===-- ChangeNamespace.cpp - Change namespace implementation -------------===//
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 #include "ChangeNamespace.h"
9 #include "clang/AST/ASTContext.h"
10 #include "clang/Format/Format.h"
11 #include "clang/Lex/Lexer.h"
12 #include "llvm/Support/Casting.h"
13 #include "llvm/Support/ErrorHandling.h"
14 
15 using namespace clang::ast_matchers;
16 
17 namespace clang {
18 namespace change_namespace {
19 
20 namespace {
21 
22 inline std::string joinNamespaces(ArrayRef<StringRef> Namespaces) {
23   return llvm::join(Namespaces, "::");
24 }
25 
26 // Given "a::b::c", returns {"a", "b", "c"}.
27 llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
28   llvm::SmallVector<llvm::StringRef, 4> Splitted;
29   Name.split(Splitted, "::", /*MaxSplit=*/-1,
30              /*KeepEmpty=*/false);
31   return Splitted;
32 }
33 
34 SourceLocation startLocationForType(TypeLoc TLoc) {
35   // For elaborated types (e.g. `struct a::A`) we want the portion after the
36   // `struct` but including the namespace qualifier, `a::`.
37   if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
38     NestedNameSpecifierLoc NestedNameSpecifier =
39         TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
40     if (NestedNameSpecifier.getNestedNameSpecifier())
41       return NestedNameSpecifier.getBeginLoc();
42     TLoc = TLoc.getNextTypeLoc();
43   }
44   return TLoc.getBeginLoc();
45 }
46 
47 SourceLocation endLocationForType(TypeLoc TLoc) {
48   // Dig past any namespace or keyword qualifications.
49   while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
50          TLoc.getTypeLocClass() == TypeLoc::Qualified)
51     TLoc = TLoc.getNextTypeLoc();
52 
53   // The location for template specializations (e.g. Foo<int>) includes the
54   // templated types in its location range.  We want to restrict this to just
55   // before the `<` character.
56   if (TLoc.getTypeLocClass() == TypeLoc::TemplateSpecialization)
57     return TLoc.castAs<TemplateSpecializationTypeLoc>()
58         .getLAngleLoc()
59         .getLocWithOffset(-1);
60   return TLoc.getEndLoc();
61 }
62 
63 // Returns the containing namespace of `InnerNs` by skipping `PartialNsName`.
64 // If the `InnerNs` does not have `PartialNsName` as suffix, or `PartialNsName`
65 // is empty, nullptr is returned.
66 // For example, if `InnerNs` is "a::b::c" and `PartialNsName` is "b::c", then
67 // the NamespaceDecl of namespace "a" will be returned.
68 const NamespaceDecl *getOuterNamespace(const NamespaceDecl *InnerNs,
69                                        llvm::StringRef PartialNsName) {
70   if (!InnerNs || PartialNsName.empty())
71     return nullptr;
72   const auto *CurrentContext = llvm::cast<DeclContext>(InnerNs);
73   const auto *CurrentNs = InnerNs;
74   auto PartialNsNameSplitted = splitSymbolName(PartialNsName);
75   while (!PartialNsNameSplitted.empty()) {
76     // Get the inner-most namespace in CurrentContext.
77     while (CurrentContext && !llvm::isa<NamespaceDecl>(CurrentContext))
78       CurrentContext = CurrentContext->getParent();
79     if (!CurrentContext)
80       return nullptr;
81     CurrentNs = llvm::cast<NamespaceDecl>(CurrentContext);
82     if (PartialNsNameSplitted.back() != CurrentNs->getNameAsString())
83       return nullptr;
84     PartialNsNameSplitted.pop_back();
85     CurrentContext = CurrentContext->getParent();
86   }
87   return CurrentNs;
88 }
89 
90 static std::unique_ptr<Lexer>
91 getLexerStartingFromLoc(SourceLocation Loc, const SourceManager &SM,
92                         const LangOptions &LangOpts) {
93   if (Loc.isMacroID() &&
94       !Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
95     return nullptr;
96   // Break down the source location.
97   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
98   // Try to load the file buffer.
99   bool InvalidTemp = false;
100   llvm::StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
101   if (InvalidTemp)
102     return nullptr;
103 
104   const char *TokBegin = File.data() + LocInfo.second;
105   // Lex from the start of the given location.
106   return std::make_unique<Lexer>(SM.getLocForStartOfFile(LocInfo.first),
107                                   LangOpts, File.begin(), TokBegin, File.end());
108 }
109 
110 // FIXME: get rid of this helper function if this is supported in clang-refactor
111 // library.
112 static SourceLocation getStartOfNextLine(SourceLocation Loc,
113                                          const SourceManager &SM,
114                                          const LangOptions &LangOpts) {
115   std::unique_ptr<Lexer> Lex = getLexerStartingFromLoc(Loc, SM, LangOpts);
116   if (!Lex.get())
117     return SourceLocation();
118   llvm::SmallVector<char, 16> Line;
119   // FIXME: this is a bit hacky to get ReadToEndOfLine work.
120   Lex->setParsingPreprocessorDirective(true);
121   Lex->ReadToEndOfLine(&Line);
122   auto End = Loc.getLocWithOffset(Line.size());
123   return SM.getLocForEndOfFile(SM.getDecomposedLoc(Loc).first) == End
124              ? End
125              : End.getLocWithOffset(1);
126 }
127 
128 // Returns `R` with new range that refers to code after `Replaces` being
129 // applied.
130 tooling::Replacement
131 getReplacementInChangedCode(const tooling::Replacements &Replaces,
132                             const tooling::Replacement &R) {
133   unsigned NewStart = Replaces.getShiftedCodePosition(R.getOffset());
134   unsigned NewEnd =
135       Replaces.getShiftedCodePosition(R.getOffset() + R.getLength());
136   return tooling::Replacement(R.getFilePath(), NewStart, NewEnd - NewStart,
137                               R.getReplacementText());
138 }
139 
140 // Adds a replacement `R` into `Replaces` or merges it into `Replaces` by
141 // applying all existing Replaces first if there is conflict.
142 void addOrMergeReplacement(const tooling::Replacement &R,
143                            tooling::Replacements *Replaces) {
144   auto Err = Replaces->add(R);
145   if (Err) {
146     llvm::consumeError(std::move(Err));
147     auto Replace = getReplacementInChangedCode(*Replaces, R);
148     *Replaces = Replaces->merge(tooling::Replacements(Replace));
149   }
150 }
151 
152 tooling::Replacement createReplacement(SourceLocation Start, SourceLocation End,
153                                        llvm::StringRef ReplacementText,
154                                        const SourceManager &SM) {
155   if (!Start.isValid() || !End.isValid()) {
156     llvm::errs() << "start or end location were invalid\n";
157     return tooling::Replacement();
158   }
159   if (SM.getDecomposedLoc(Start).first != SM.getDecomposedLoc(End).first) {
160     llvm::errs()
161         << "start or end location were in different macro expansions\n";
162     return tooling::Replacement();
163   }
164   Start = SM.getSpellingLoc(Start);
165   End = SM.getSpellingLoc(End);
166   if (SM.getFileID(Start) != SM.getFileID(End)) {
167     llvm::errs() << "start or end location were in different files\n";
168     return tooling::Replacement();
169   }
170   return tooling::Replacement(
171       SM, CharSourceRange::getTokenRange(SM.getSpellingLoc(Start),
172                                          SM.getSpellingLoc(End)),
173       ReplacementText);
174 }
175 
176 void addReplacementOrDie(
177     SourceLocation Start, SourceLocation End, llvm::StringRef ReplacementText,
178     const SourceManager &SM,
179     std::map<std::string, tooling::Replacements> *FileToReplacements) {
180   const auto R = createReplacement(Start, End, ReplacementText, SM);
181   auto Err = (*FileToReplacements)[std::string(R.getFilePath())].add(R);
182   if (Err)
183     llvm_unreachable(llvm::toString(std::move(Err)).c_str());
184 }
185 
186 tooling::Replacement createInsertion(SourceLocation Loc,
187                                      llvm::StringRef InsertText,
188                                      const SourceManager &SM) {
189   if (Loc.isInvalid()) {
190     llvm::errs() << "insert Location is invalid.\n";
191     return tooling::Replacement();
192   }
193   Loc = SM.getSpellingLoc(Loc);
194   return tooling::Replacement(SM, Loc, 0, InsertText);
195 }
196 
197 // Returns the shortest qualified name for declaration `DeclName` in the
198 // namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName`
199 // is "a::c::d", then "b::X" will be returned.
200 // Note that if `DeclName` is `::b::X` and `NsName` is `::a::b`, this returns
201 // "::b::X" instead of "b::X" since there will be a name conflict otherwise.
202 // \param DeclName A fully qualified name, "::a::b::X" or "a::b::X".
203 // \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace
204 //        will have empty name.
205 std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName,
206                                                 llvm::StringRef NsName) {
207   DeclName = DeclName.ltrim(':');
208   NsName = NsName.ltrim(':');
209   if (!DeclName.contains(':'))
210     return std::string(DeclName);
211 
212   auto NsNameSplitted = splitSymbolName(NsName);
213   auto DeclNsSplitted = splitSymbolName(DeclName);
214   llvm::StringRef UnqualifiedDeclName = DeclNsSplitted.pop_back_val();
215   // If the Decl is in global namespace, there is no need to shorten it.
216   if (DeclNsSplitted.empty())
217     return std::string(UnqualifiedDeclName);
218   // If NsName is the global namespace, we can simply use the DeclName sans
219   // leading "::".
220   if (NsNameSplitted.empty())
221     return std::string(DeclName);
222 
223   if (NsNameSplitted.front() != DeclNsSplitted.front()) {
224     // The DeclName must be fully-qualified, but we still need to decide if a
225     // leading "::" is necessary. For example, if `NsName` is "a::b::c" and the
226     // `DeclName` is "b::X", then the reference must be qualified as "::b::X"
227     // to avoid conflict.
228     if (llvm::is_contained(NsNameSplitted, DeclNsSplitted.front()))
229       return ("::" + DeclName).str();
230     return std::string(DeclName);
231   }
232   // Since there is already an overlap namespace, we know that `DeclName` can be
233   // shortened, so we reduce the longest common prefix.
234   auto DeclI = DeclNsSplitted.begin();
235   auto DeclE = DeclNsSplitted.end();
236   auto NsI = NsNameSplitted.begin();
237   auto NsE = NsNameSplitted.end();
238   for (; DeclI != DeclE && NsI != NsE && *DeclI == *NsI; ++DeclI, ++NsI) {
239   }
240   return (DeclI == DeclE)
241              ? UnqualifiedDeclName.str()
242              : (llvm::join(DeclI, DeclE, "::") + "::" + UnqualifiedDeclName)
243                    .str();
244 }
245 
246 std::string wrapCodeInNamespace(StringRef NestedNs, std::string Code) {
247   if (Code.back() != '\n')
248     Code += "\n";
249   auto NsSplitted = splitSymbolName(NestedNs);
250   while (!NsSplitted.empty()) {
251     // FIXME: consider code style for comments.
252     Code = ("namespace " + NsSplitted.back() + " {\n" + Code +
253             "} // namespace " + NsSplitted.back() + "\n")
254                .str();
255     NsSplitted.pop_back();
256   }
257   return Code;
258 }
259 
260 // Returns true if \p D is a nested DeclContext in \p Context
261 bool isNestedDeclContext(const DeclContext *D, const DeclContext *Context) {
262   while (D) {
263     if (D == Context)
264       return true;
265     D = D->getParent();
266   }
267   return false;
268 }
269 
270 // Returns true if \p D is visible at \p Loc with DeclContext \p DeclCtx.
271 bool isDeclVisibleAtLocation(const SourceManager &SM, const Decl *D,
272                              const DeclContext *DeclCtx, SourceLocation Loc) {
273   SourceLocation DeclLoc = SM.getSpellingLoc(D->getBeginLoc());
274   Loc = SM.getSpellingLoc(Loc);
275   return SM.isBeforeInTranslationUnit(DeclLoc, Loc) &&
276          (SM.getFileID(DeclLoc) == SM.getFileID(Loc) &&
277           isNestedDeclContext(DeclCtx, D->getDeclContext()));
278 }
279 
280 // Given a qualified symbol name, returns true if the symbol will be
281 // incorrectly qualified without leading "::". For example, a symbol
282 // "nx::ny::Foo" in namespace "na::nx::ny" without leading "::"; a symbol
283 // "util::X" in namespace "na" can potentially conflict with "na::util" (if this
284 // exists).
285 bool conflictInNamespace(const ASTContext &AST, llvm::StringRef QualifiedSymbol,
286                          llvm::StringRef Namespace) {
287   auto SymbolSplitted = splitSymbolName(QualifiedSymbol.trim(":"));
288   assert(!SymbolSplitted.empty());
289   SymbolSplitted.pop_back();  // We are only interested in namespaces.
290 
291   if (SymbolSplitted.size() >= 1 && !Namespace.empty()) {
292     auto SymbolTopNs = SymbolSplitted.front();
293     auto NsSplitted = splitSymbolName(Namespace.trim(":"));
294     assert(!NsSplitted.empty());
295 
296     auto LookupDecl = [&AST](const Decl &Scope,
297                              llvm::StringRef Name) -> const NamedDecl * {
298       const auto *DC = llvm::dyn_cast<DeclContext>(&Scope);
299       if (!DC)
300         return nullptr;
301       auto LookupRes = DC->lookup(DeclarationName(&AST.Idents.get(Name)));
302       if (LookupRes.empty())
303         return nullptr;
304       return LookupRes.front();
305     };
306     // We do not check the outermost namespace since it would not be a
307     // conflict if it equals to the symbol's outermost namespace and the
308     // symbol name would have been shortened.
309     const NamedDecl *Scope =
310         LookupDecl(*AST.getTranslationUnitDecl(), NsSplitted.front());
311     for (const auto &I : llvm::drop_begin(NsSplitted)) {
312       if (I == SymbolTopNs) // Handles "::ny" in "::nx::ny" case.
313         return true;
314       // Handles "::util" and "::nx::util" conflicts.
315       if (Scope) {
316         if (LookupDecl(*Scope, SymbolTopNs))
317           return true;
318         Scope = LookupDecl(*Scope, I);
319       }
320     }
321     if (Scope && LookupDecl(*Scope, SymbolTopNs))
322       return true;
323   }
324   return false;
325 }
326 
327 bool isTemplateParameter(TypeLoc Type) {
328   while (!Type.isNull()) {
329     if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm)
330       return true;
331     Type = Type.getNextTypeLoc();
332   }
333   return false;
334 }
335 
336 } // anonymous namespace
337 
338 ChangeNamespaceTool::ChangeNamespaceTool(
339     llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern,
340     llvm::ArrayRef<std::string> AllowedSymbolPatterns,
341     std::map<std::string, tooling::Replacements> *FileToReplacements,
342     llvm::StringRef FallbackStyle)
343     : FallbackStyle(FallbackStyle), FileToReplacements(*FileToReplacements),
344       OldNamespace(OldNs.ltrim(':')), NewNamespace(NewNs.ltrim(':')),
345       FilePattern(FilePattern), FilePatternRE(FilePattern) {
346   FileToReplacements->clear();
347   auto OldNsSplitted = splitSymbolName(OldNamespace);
348   auto NewNsSplitted = splitSymbolName(NewNamespace);
349   // Calculates `DiffOldNamespace` and `DiffNewNamespace`.
350   while (!OldNsSplitted.empty() && !NewNsSplitted.empty() &&
351          OldNsSplitted.front() == NewNsSplitted.front()) {
352     OldNsSplitted.erase(OldNsSplitted.begin());
353     NewNsSplitted.erase(NewNsSplitted.begin());
354   }
355   DiffOldNamespace = joinNamespaces(OldNsSplitted);
356   DiffNewNamespace = joinNamespaces(NewNsSplitted);
357 
358   for (const auto &Pattern : AllowedSymbolPatterns)
359     AllowedSymbolRegexes.emplace_back(Pattern);
360 }
361 
362 void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
363   std::string FullOldNs = "::" + OldNamespace;
364   // Prefix is the outer-most namespace in DiffOldNamespace. For example, if the
365   // OldNamespace is "a::b::c" and DiffOldNamespace is "b::c", then Prefix will
366   // be "a::b". Declarations in this namespace will not be visible in the new
367   // namespace. If DiffOldNamespace is empty, Prefix will be a invalid name "-".
368   llvm::SmallVector<llvm::StringRef, 4> DiffOldNsSplitted;
369   llvm::StringRef(DiffOldNamespace)
370       .split(DiffOldNsSplitted, "::", /*MaxSplit=*/-1,
371              /*KeepEmpty=*/false);
372   std::string Prefix = "-";
373   if (!DiffOldNsSplitted.empty())
374     Prefix = (StringRef(FullOldNs).drop_back(DiffOldNamespace.size()) +
375               DiffOldNsSplitted.front())
376                  .str();
377   auto IsInMovedNs =
378       allOf(hasAncestor(namespaceDecl(hasName(FullOldNs)).bind("ns_decl")),
379             isExpansionInFileMatching(FilePattern));
380   auto IsVisibleInNewNs = anyOf(
381       IsInMovedNs, unless(hasAncestor(namespaceDecl(hasName(Prefix)))));
382   // Match using declarations.
383   Finder->addMatcher(
384       usingDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs)
385           .bind("using"),
386       this);
387   // Match using namespace declarations.
388   Finder->addMatcher(usingDirectiveDecl(isExpansionInFileMatching(FilePattern),
389                                         IsVisibleInNewNs)
390                          .bind("using_namespace"),
391                      this);
392   // Match namespace alias declarations.
393   Finder->addMatcher(namespaceAliasDecl(isExpansionInFileMatching(FilePattern),
394                                         IsVisibleInNewNs)
395                          .bind("namespace_alias"),
396                      this);
397 
398   // Match old namespace blocks.
399   Finder->addMatcher(
400       namespaceDecl(hasName(FullOldNs), isExpansionInFileMatching(FilePattern))
401           .bind("old_ns"),
402       this);
403 
404   // Match class forward-declarations in the old namespace.
405   // Note that forward-declarations in classes are not matched.
406   Finder->addMatcher(cxxRecordDecl(unless(anyOf(isImplicit(), isDefinition())),
407                                    IsInMovedNs, hasParent(namespaceDecl()))
408                          .bind("class_fwd_decl"),
409                      this);
410 
411   // Match template class forward-declarations in the old namespace.
412   Finder->addMatcher(
413       classTemplateDecl(unless(hasDescendant(cxxRecordDecl(isDefinition()))),
414                         IsInMovedNs, hasParent(namespaceDecl()))
415           .bind("template_class_fwd_decl"),
416       this);
417 
418   // Match references to types that are not defined in the old namespace.
419   // Forward-declarations in the old namespace are also matched since they will
420   // be moved back to the old namespace.
421   auto DeclMatcher = namedDecl(
422       hasAncestor(namespaceDecl()),
423       unless(anyOf(
424           isImplicit(), hasAncestor(namespaceDecl(isAnonymous())),
425           hasAncestor(cxxRecordDecl()),
426           allOf(IsInMovedNs, unless(cxxRecordDecl(unless(isDefinition())))))));
427 
428   // Using shadow declarations in classes always refers to base class, which
429   // does not need to be qualified since it can be inferred from inheritance.
430   // Note that this does not match using alias declarations.
431   auto UsingShadowDeclInClass =
432       usingDecl(hasAnyUsingShadowDecl(decl()), hasParent(cxxRecordDecl()));
433 
434   // Match TypeLocs on the declaration. Carefully match only the outermost
435   // TypeLoc and template specialization arguments (which are not outermost)
436   // that are directly linked to types matching `DeclMatcher`. Nested name
437   // specifier locs are handled separately below.
438   Finder->addMatcher(
439       typeLoc(IsInMovedNs,
440               loc(qualType(hasDeclaration(DeclMatcher.bind("from_decl")))),
441               unless(anyOf(hasParent(typeLoc(loc(qualType(
442                                hasDeclaration(DeclMatcher),
443                                unless(templateSpecializationType()))))),
444                            hasParent(nestedNameSpecifierLoc()),
445                            hasAncestor(decl(isImplicit())),
446                            hasAncestor(UsingShadowDeclInClass),
447                            hasAncestor(functionDecl(isDefaulted())))),
448               hasAncestor(decl().bind("dc")))
449           .bind("type"),
450       this);
451 
452   // Types in `UsingShadowDecl` is not matched by `typeLoc` above, so we need to
453   // special case it.
454   // Since using declarations inside classes must have the base class in the
455   // nested name specifier, we leave it to the nested name specifier matcher.
456   Finder->addMatcher(usingDecl(IsInMovedNs, hasAnyUsingShadowDecl(decl()),
457                                unless(UsingShadowDeclInClass))
458                          .bind("using_with_shadow"),
459                      this);
460 
461   // Handle types in nested name specifier. Specifiers that are in a TypeLoc
462   // matched above are not matched, e.g. "A::" in "A::A" is not matched since
463   // "A::A" would have already been fixed.
464   Finder->addMatcher(
465       nestedNameSpecifierLoc(
466           hasAncestor(decl(IsInMovedNs).bind("dc")),
467           loc(nestedNameSpecifier(
468               specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"))))),
469           unless(anyOf(hasAncestor(decl(isImplicit())),
470                        hasAncestor(UsingShadowDeclInClass),
471                        hasAncestor(functionDecl(isDefaulted())),
472                        hasAncestor(typeLoc(loc(qualType(hasDeclaration(
473                            decl(equalsBoundNode("from_decl"))))))))))
474           .bind("nested_specifier_loc"),
475       this);
476 
477   // Matches base class initializers in constructors. TypeLocs of base class
478   // initializers do not need to be fixed. For example,
479   //    class X : public a::b::Y {
480   //      public:
481   //        X() : Y::Y() {} // Y::Y do not need namespace specifier.
482   //    };
483   Finder->addMatcher(
484       cxxCtorInitializer(isBaseInitializer()).bind("base_initializer"), this);
485 
486   // Handle function.
487   // Only handle functions that are defined in a namespace excluding member
488   // function, static methods (qualified by nested specifier), and functions
489   // defined in the global namespace.
490   // Note that the matcher does not exclude calls to out-of-line static method
491   // definitions, so we need to exclude them in the callback handler.
492   auto FuncMatcher =
493       functionDecl(unless(anyOf(cxxMethodDecl(), IsInMovedNs,
494                                 hasAncestor(namespaceDecl(isAnonymous())),
495                                 hasAncestor(cxxRecordDecl()))),
496                    hasParent(namespaceDecl()));
497   Finder->addMatcher(expr(hasAncestor(decl().bind("dc")), IsInMovedNs,
498                           unless(hasAncestor(decl(isImplicit()))),
499                           anyOf(callExpr(callee(FuncMatcher)).bind("call"),
500                                 declRefExpr(to(FuncMatcher.bind("func_decl")))
501                                     .bind("func_ref"))),
502                      this);
503 
504   auto GlobalVarMatcher = varDecl(
505       hasGlobalStorage(), hasParent(namespaceDecl()),
506       unless(anyOf(IsInMovedNs, hasAncestor(namespaceDecl(isAnonymous())))));
507   Finder->addMatcher(declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")),
508                                  to(GlobalVarMatcher.bind("var_decl")))
509                          .bind("var_ref"),
510                      this);
511 
512   // Handle unscoped enum constant.
513   auto UnscopedEnumMatcher = enumConstantDecl(hasParent(enumDecl(
514       hasParent(namespaceDecl()),
515       unless(anyOf(isScoped(), IsInMovedNs, hasAncestor(cxxRecordDecl()),
516                    hasAncestor(namespaceDecl(isAnonymous())))))));
517   Finder->addMatcher(
518       declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")),
519                   to(UnscopedEnumMatcher.bind("enum_const_decl")))
520           .bind("enum_const_ref"),
521       this);
522 }
523 
524 void ChangeNamespaceTool::run(
525     const ast_matchers::MatchFinder::MatchResult &Result) {
526   if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
527     UsingDecls.insert(Using);
528   } else if (const auto *UsingNamespace =
529                  Result.Nodes.getNodeAs<UsingDirectiveDecl>(
530                      "using_namespace")) {
531     UsingNamespaceDecls.insert(UsingNamespace);
532   } else if (const auto *NamespaceAlias =
533                  Result.Nodes.getNodeAs<NamespaceAliasDecl>(
534                      "namespace_alias")) {
535     NamespaceAliasDecls.insert(NamespaceAlias);
536   } else if (const auto *NsDecl =
537                  Result.Nodes.getNodeAs<NamespaceDecl>("old_ns")) {
538     moveOldNamespace(Result, NsDecl);
539   } else if (const auto *FwdDecl =
540                  Result.Nodes.getNodeAs<CXXRecordDecl>("class_fwd_decl")) {
541     moveClassForwardDeclaration(Result, cast<NamedDecl>(FwdDecl));
542   } else if (const auto *TemplateFwdDecl =
543                  Result.Nodes.getNodeAs<ClassTemplateDecl>(
544                      "template_class_fwd_decl")) {
545     moveClassForwardDeclaration(Result, cast<NamedDecl>(TemplateFwdDecl));
546   } else if (const auto *UsingWithShadow =
547                  Result.Nodes.getNodeAs<UsingDecl>("using_with_shadow")) {
548     fixUsingShadowDecl(Result, UsingWithShadow);
549   } else if (const auto *Specifier =
550                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
551                      "nested_specifier_loc")) {
552     SourceLocation Start = Specifier->getBeginLoc();
553     SourceLocation End = endLocationForType(Specifier->getTypeLoc());
554     fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
555   } else if (const auto *BaseInitializer =
556                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
557                      "base_initializer")) {
558     BaseCtorInitializerTypeLocs.push_back(
559         BaseInitializer->getTypeSourceInfo()->getTypeLoc());
560   } else if (const auto *TLoc = Result.Nodes.getNodeAs<TypeLoc>("type")) {
561     // This avoids fixing types with record types as qualifier, which is not
562     // filtered by matchers in some cases, e.g. the type is templated. We should
563     // handle the record type qualifier instead.
564     TypeLoc Loc = *TLoc;
565     while (Loc.getTypeLocClass() == TypeLoc::Qualified)
566       Loc = Loc.getNextTypeLoc();
567     if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
568       NestedNameSpecifierLoc NestedNameSpecifier =
569           Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
570       // FIXME: avoid changing injected class names.
571       if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
572         const Type *SpecifierType = NNS->getAsType();
573         if (SpecifierType && SpecifierType->isRecordType())
574           return;
575       }
576     }
577     fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
578   } else if (const auto *VarRef =
579                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
580     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
581     assert(Var);
582     if (Var->getCanonicalDecl()->isStaticDataMember())
583       return;
584     const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
585     assert(Context && "Empty decl context.");
586     fixDeclRefExpr(Result, Context->getDeclContext(),
587                    llvm::cast<NamedDecl>(Var), VarRef);
588   } else if (const auto *EnumConstRef =
589                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
590     // Do not rename the reference if it is already scoped by the EnumDecl name.
591     if (EnumConstRef->hasQualifier() &&
592         EnumConstRef->getQualifier()->getKind() ==
593             NestedNameSpecifier::SpecifierKind::TypeSpec &&
594         EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
595       return;
596     const auto *EnumConstDecl =
597         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
598     assert(EnumConstDecl);
599     const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
600     assert(Context && "Empty decl context.");
601     // FIXME: this would qualify "ns::VALUE" as "ns::EnumValue::VALUE". Fix it
602     // if it turns out to be an issue.
603     fixDeclRefExpr(Result, Context->getDeclContext(),
604                    llvm::cast<NamedDecl>(EnumConstDecl), EnumConstRef);
605   } else if (const auto *FuncRef =
606                  Result.Nodes.getNodeAs<DeclRefExpr>("func_ref")) {
607     // If this reference has been processed as a function call, we do not
608     // process it again.
609     if (!ProcessedFuncRefs.insert(FuncRef).second)
610       return;
611     const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func_decl");
612     assert(Func);
613     const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
614     assert(Context && "Empty decl context.");
615     fixDeclRefExpr(Result, Context->getDeclContext(),
616                    llvm::cast<NamedDecl>(Func), FuncRef);
617   } else {
618     const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
619     assert(Call != nullptr && "Expecting callback for CallExpr.");
620     const auto *CalleeFuncRef =
621         llvm::cast<DeclRefExpr>(Call->getCallee()->IgnoreImplicit());
622     ProcessedFuncRefs.insert(CalleeFuncRef);
623     const FunctionDecl *Func = Call->getDirectCallee();
624     assert(Func != nullptr);
625     // FIXME: ignore overloaded operators. This would miss cases where operators
626     // are called by qualified names (i.e. "ns::operator <"). Ignore such
627     // cases for now.
628     if (Func->isOverloadedOperator())
629       return;
630     // Ignore out-of-line static methods since they will be handled by nested
631     // name specifiers.
632     if (Func->getCanonicalDecl()->getStorageClass() ==
633             StorageClass::SC_Static &&
634         Func->isOutOfLine())
635       return;
636     const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
637     assert(Context && "Empty decl context.");
638     SourceRange CalleeRange = Call->getCallee()->getSourceRange();
639     replaceQualifiedSymbolInDeclContext(
640         Result, Context->getDeclContext(), CalleeRange.getBegin(),
641         CalleeRange.getEnd(), llvm::cast<NamedDecl>(Func));
642   }
643 }
644 
645 static SourceLocation getLocAfterNamespaceLBrace(const NamespaceDecl *NsDecl,
646                                                  const SourceManager &SM,
647                                                  const LangOptions &LangOpts) {
648   std::unique_ptr<Lexer> Lex =
649       getLexerStartingFromLoc(NsDecl->getBeginLoc(), SM, LangOpts);
650   assert(Lex.get() &&
651          "Failed to create lexer from the beginning of namespace.");
652   if (!Lex.get())
653     return SourceLocation();
654   Token Tok;
655   while (!Lex->LexFromRawLexer(Tok) && Tok.isNot(tok::TokenKind::l_brace)) {
656   }
657   return Tok.isNot(tok::TokenKind::l_brace)
658              ? SourceLocation()
659              : Tok.getEndLoc().getLocWithOffset(1);
660 }
661 
662 // Stores information about a moved namespace in `MoveNamespaces` and leaves
663 // the actual movement to `onEndOfTranslationUnit()`.
664 void ChangeNamespaceTool::moveOldNamespace(
665     const ast_matchers::MatchFinder::MatchResult &Result,
666     const NamespaceDecl *NsDecl) {
667   // If the namespace is empty, do nothing.
668   if (Decl::castToDeclContext(NsDecl)->decls_empty())
669     return;
670 
671   const SourceManager &SM = *Result.SourceManager;
672   // Get the range of the code in the old namespace.
673   SourceLocation Start =
674       getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts());
675   assert(Start.isValid() && "Can't find l_brace for namespace.");
676   MoveNamespace MoveNs;
677   MoveNs.Offset = SM.getFileOffset(Start);
678   // The range of the moved namespace is from the location just past the left
679   // brace to the location right before the right brace.
680   MoveNs.Length = SM.getFileOffset(NsDecl->getRBraceLoc()) - MoveNs.Offset;
681 
682   // Insert the new namespace after `DiffOldNamespace`. For example, if
683   // `OldNamespace` is "a::b::c" and `NewNamespace` is `a::x::y`, then
684   // "x::y" will be inserted inside the existing namespace "a" and after "a::b".
685   // `OuterNs` is the first namespace in `DiffOldNamespace`, e.g. "namespace b"
686   // in the above example.
687   // If there is no outer namespace (i.e. DiffOldNamespace is empty), the new
688   // namespace will be a nested namespace in the old namespace.
689   const NamespaceDecl *OuterNs = getOuterNamespace(NsDecl, DiffOldNamespace);
690   SourceLocation InsertionLoc = Start;
691   if (OuterNs) {
692     SourceLocation LocAfterNs = getStartOfNextLine(
693         OuterNs->getRBraceLoc(), SM, Result.Context->getLangOpts());
694     assert(LocAfterNs.isValid() &&
695            "Failed to get location after DiffOldNamespace");
696     InsertionLoc = LocAfterNs;
697   }
698   MoveNs.InsertionOffset = SM.getFileOffset(SM.getSpellingLoc(InsertionLoc));
699   MoveNs.FID = SM.getFileID(Start);
700   MoveNs.SourceMgr = Result.SourceManager;
701   MoveNamespaces[std::string(SM.getFilename(Start))].push_back(MoveNs);
702 }
703 
704 // Removes a class forward declaration from the code in the moved namespace and
705 // creates an `InsertForwardDeclaration` to insert the forward declaration back
706 // into the old namespace after moving code from the old namespace to the new
707 // namespace.
708 // For example, changing "a" to "x":
709 // Old code:
710 //   namespace a {
711 //   class FWD;
712 //   class A { FWD *fwd; }
713 //   }  // a
714 // New code:
715 //   namespace a {
716 //   class FWD;
717 //   }  // a
718 //   namespace x {
719 //   class A { a::FWD *fwd; }
720 //   }  // x
721 void ChangeNamespaceTool::moveClassForwardDeclaration(
722     const ast_matchers::MatchFinder::MatchResult &Result,
723     const NamedDecl *FwdDecl) {
724   SourceLocation Start = FwdDecl->getBeginLoc();
725   SourceLocation End = FwdDecl->getEndLoc();
726   const SourceManager &SM = *Result.SourceManager;
727   SourceLocation AfterSemi = Lexer::findLocationAfterToken(
728       End, tok::semi, SM, Result.Context->getLangOpts(),
729       /*SkipTrailingWhitespaceAndNewLine=*/true);
730   if (AfterSemi.isValid())
731     End = AfterSemi.getLocWithOffset(-1);
732   // Delete the forward declaration from the code to be moved.
733   addReplacementOrDie(Start, End, "", SM, &FileToReplacements);
734   llvm::StringRef Code = Lexer::getSourceText(
735       CharSourceRange::getTokenRange(SM.getSpellingLoc(Start),
736                                      SM.getSpellingLoc(End)),
737       SM, Result.Context->getLangOpts());
738   // Insert the forward declaration back into the old namespace after moving the
739   // code from old namespace to new namespace.
740   // Insertion information is stored in `InsertFwdDecls` and actual
741   // insertion will be performed in `onEndOfTranslationUnit`.
742   // Get the (old) namespace that contains the forward declaration.
743   const auto *NsDecl = Result.Nodes.getNodeAs<NamespaceDecl>("ns_decl");
744   // The namespace contains the forward declaration, so it must not be empty.
745   assert(!NsDecl->decls_empty());
746   const auto Insertion = createInsertion(
747       getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()),
748       Code, SM);
749   InsertForwardDeclaration InsertFwd;
750   InsertFwd.InsertionOffset = Insertion.getOffset();
751   InsertFwd.ForwardDeclText = Insertion.getReplacementText().str();
752   InsertFwdDecls[std::string(Insertion.getFilePath())].push_back(InsertFwd);
753 }
754 
755 // Replaces a qualified symbol (in \p DeclCtx) that refers to a declaration \p
756 // FromDecl with the shortest qualified name possible when the reference is in
757 // `NewNamespace`.
758 void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext(
759     const ast_matchers::MatchFinder::MatchResult &Result,
760     const DeclContext *DeclCtx, SourceLocation Start, SourceLocation End,
761     const NamedDecl *FromDecl) {
762   const auto *NsDeclContext = DeclCtx->getEnclosingNamespaceContext();
763   if (llvm::isa<TranslationUnitDecl>(NsDeclContext)) {
764     // This should not happen in usual unless the TypeLoc is in function type
765     // parameters, e.g `std::function<void(T)>`. In this case, DeclContext of
766     // `T` will be the translation unit. We simply use fully-qualified name
767     // here.
768     // Note that `FromDecl` must not be defined in the old namespace (according
769     // to `DeclMatcher`), so its fully-qualified name will not change after
770     // changing the namespace.
771     addReplacementOrDie(Start, End, FromDecl->getQualifiedNameAsString(),
772                         *Result.SourceManager, &FileToReplacements);
773     return;
774   }
775   const auto *NsDecl = llvm::cast<NamespaceDecl>(NsDeclContext);
776   // Calculate the name of the `NsDecl` after it is moved to new namespace.
777   std::string OldNs = NsDecl->getQualifiedNameAsString();
778   llvm::StringRef Postfix = OldNs;
779   bool Consumed = Postfix.consume_front(OldNamespace);
780   assert(Consumed && "Expect OldNS to start with OldNamespace.");
781   (void)Consumed;
782   const std::string NewNs = (NewNamespace + Postfix).str();
783 
784   llvm::StringRef NestedName = Lexer::getSourceText(
785       CharSourceRange::getTokenRange(
786           Result.SourceManager->getSpellingLoc(Start),
787           Result.SourceManager->getSpellingLoc(End)),
788       *Result.SourceManager, Result.Context->getLangOpts());
789   std::string FromDeclName = FromDecl->getQualifiedNameAsString();
790   for (llvm::Regex &RE : AllowedSymbolRegexes)
791     if (RE.match(FromDeclName))
792       return;
793   std::string ReplaceName =
794       getShortestQualifiedNameInNamespace(FromDeclName, NewNs);
795   // Checks if there is any using namespace declarations that can shorten the
796   // qualified name.
797   for (const auto *UsingNamespace : UsingNamespaceDecls) {
798     if (!isDeclVisibleAtLocation(*Result.SourceManager, UsingNamespace, DeclCtx,
799                                  Start))
800       continue;
801     StringRef FromDeclNameRef = FromDeclName;
802     if (FromDeclNameRef.consume_front(UsingNamespace->getNominatedNamespace()
803                                           ->getQualifiedNameAsString())) {
804       FromDeclNameRef = FromDeclNameRef.drop_front(2);
805       if (FromDeclNameRef.size() < ReplaceName.size())
806         ReplaceName = std::string(FromDeclNameRef);
807     }
808   }
809   // Checks if there is any namespace alias declarations that can shorten the
810   // qualified name.
811   for (const auto *NamespaceAlias : NamespaceAliasDecls) {
812     if (!isDeclVisibleAtLocation(*Result.SourceManager, NamespaceAlias, DeclCtx,
813                                  Start))
814       continue;
815     StringRef FromDeclNameRef = FromDeclName;
816     if (FromDeclNameRef.consume_front(
817             NamespaceAlias->getNamespace()->getQualifiedNameAsString() +
818             "::")) {
819       std::string AliasName = NamespaceAlias->getNameAsString();
820       std::string AliasQualifiedName =
821           NamespaceAlias->getQualifiedNameAsString();
822       // We only consider namespace aliases define in the global namespace or
823       // in namespaces that are directly visible from the reference, i.e.
824       // ancestor of the `OldNs`. Note that declarations in ancestor namespaces
825       // but not visible in the new namespace is filtered out by
826       // "IsVisibleInNewNs" matcher.
827       if (AliasQualifiedName != AliasName) {
828         // The alias is defined in some namespace.
829         assert(StringRef(AliasQualifiedName).ends_with("::" + AliasName));
830         llvm::StringRef AliasNs =
831             StringRef(AliasQualifiedName).drop_back(AliasName.size() + 2);
832         if (!llvm::StringRef(OldNs).starts_with(AliasNs))
833           continue;
834       }
835       std::string NameWithAliasNamespace =
836           (AliasName + "::" + FromDeclNameRef).str();
837       if (NameWithAliasNamespace.size() < ReplaceName.size())
838         ReplaceName = NameWithAliasNamespace;
839     }
840   }
841   // Checks if there is any using shadow declarations that can shorten the
842   // qualified name.
843   bool Matched = false;
844   for (const UsingDecl *Using : UsingDecls) {
845     if (Matched)
846       break;
847     if (isDeclVisibleAtLocation(*Result.SourceManager, Using, DeclCtx, Start)) {
848       for (const auto *UsingShadow : Using->shadows()) {
849         const auto *TargetDecl = UsingShadow->getTargetDecl();
850         if (TargetDecl->getQualifiedNameAsString() ==
851             FromDecl->getQualifiedNameAsString()) {
852           ReplaceName = FromDecl->getNameAsString();
853           Matched = true;
854           break;
855         }
856       }
857     }
858   }
859   bool Conflict = conflictInNamespace(DeclCtx->getParentASTContext(),
860                                       ReplaceName, NewNamespace);
861   // If the new nested name in the new namespace is the same as it was in the
862   // old namespace, we don't create replacement unless there can be ambiguity.
863   if ((NestedName == ReplaceName && !Conflict) ||
864       (NestedName.starts_with("::") && NestedName.drop_front(2) == ReplaceName))
865     return;
866   // If the reference need to be fully-qualified, add a leading "::" unless
867   // NewNamespace is the global namespace.
868   if (ReplaceName == FromDeclName && !NewNamespace.empty() && Conflict)
869     ReplaceName = "::" + ReplaceName;
870   addReplacementOrDie(Start, End, ReplaceName, *Result.SourceManager,
871                       &FileToReplacements);
872 }
873 
874 // Replace the [Start, End] of `Type` with the shortest qualified name when the
875 // `Type` is in `NewNamespace`.
876 void ChangeNamespaceTool::fixTypeLoc(
877     const ast_matchers::MatchFinder::MatchResult &Result, SourceLocation Start,
878     SourceLocation End, TypeLoc Type) {
879   // FIXME: do not rename template parameter.
880   if (Start.isInvalid() || End.isInvalid())
881     return;
882   // Types of CXXCtorInitializers do not need to be fixed.
883   if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type))
884     return;
885   if (isTemplateParameter(Type))
886     return;
887   // The declaration which this TypeLoc refers to.
888   const auto *FromDecl = Result.Nodes.getNodeAs<NamedDecl>("from_decl");
889   // `hasDeclaration` gives underlying declaration, but if the type is
890   // a typedef type, we need to use the typedef type instead.
891   auto IsInMovedNs = [&](const NamedDecl *D) {
892     if (!llvm::StringRef(D->getQualifiedNameAsString())
893              .starts_with(OldNamespace + "::"))
894       return false;
895     auto ExpansionLoc = Result.SourceManager->getExpansionLoc(D->getBeginLoc());
896     if (ExpansionLoc.isInvalid())
897       return false;
898     llvm::StringRef Filename = Result.SourceManager->getFilename(ExpansionLoc);
899     return FilePatternRE.match(Filename);
900   };
901   // Make `FromDecl` the immediate declaration that `Type` refers to, i.e. if
902   // `Type` is an alias type, we make `FromDecl` the type alias declaration.
903   // Also, don't fix the \p Type if it refers to a type alias decl in the moved
904   // namespace since the alias decl will be moved along with the type reference.
905   if (auto *Typedef = Type.getType()->getAs<TypedefType>()) {
906     FromDecl = Typedef->getDecl();
907     if (IsInMovedNs(FromDecl))
908       return;
909   } else if (auto *TemplateType =
910                  Type.getType()->getAs<TemplateSpecializationType>()) {
911     if (TemplateType->isTypeAlias()) {
912       FromDecl = TemplateType->getTemplateName().getAsTemplateDecl();
913       if (IsInMovedNs(FromDecl))
914         return;
915     }
916   }
917   const auto *DeclCtx = Result.Nodes.getNodeAs<Decl>("dc");
918   assert(DeclCtx && "Empty decl context.");
919   replaceQualifiedSymbolInDeclContext(Result, DeclCtx->getDeclContext(), Start,
920                                       End, FromDecl);
921 }
922 
923 void ChangeNamespaceTool::fixUsingShadowDecl(
924     const ast_matchers::MatchFinder::MatchResult &Result,
925     const UsingDecl *UsingDeclaration) {
926   SourceLocation Start = UsingDeclaration->getBeginLoc();
927   SourceLocation End = UsingDeclaration->getEndLoc();
928   if (Start.isInvalid() || End.isInvalid())
929     return;
930 
931   assert(UsingDeclaration->shadow_size() > 0);
932   // FIXME: it might not be always accurate to use the first using-decl.
933   const NamedDecl *TargetDecl =
934       UsingDeclaration->shadow_begin()->getTargetDecl();
935   std::string TargetDeclName = TargetDecl->getQualifiedNameAsString();
936   // FIXME: check if target_decl_name is in moved ns, which doesn't make much
937   // sense. If this happens, we need to use name with the new namespace.
938   // Use fully qualified name in UsingDecl for now.
939   addReplacementOrDie(Start, End, "using ::" + TargetDeclName,
940                       *Result.SourceManager, &FileToReplacements);
941 }
942 
943 void ChangeNamespaceTool::fixDeclRefExpr(
944     const ast_matchers::MatchFinder::MatchResult &Result,
945     const DeclContext *UseContext, const NamedDecl *From,
946     const DeclRefExpr *Ref) {
947   SourceRange RefRange = Ref->getSourceRange();
948   replaceQualifiedSymbolInDeclContext(Result, UseContext, RefRange.getBegin(),
949                                       RefRange.getEnd(), From);
950 }
951 
952 void ChangeNamespaceTool::onEndOfTranslationUnit() {
953   // Move namespace blocks and insert forward declaration to old namespace.
954   for (const auto &FileAndNsMoves : MoveNamespaces) {
955     auto &NsMoves = FileAndNsMoves.second;
956     if (NsMoves.empty())
957       continue;
958     const std::string &FilePath = FileAndNsMoves.first;
959     auto &Replaces = FileToReplacements[FilePath];
960     auto &SM = *NsMoves.begin()->SourceMgr;
961     llvm::StringRef Code = SM.getBufferData(NsMoves.begin()->FID);
962     auto ChangedCode = tooling::applyAllReplacements(Code, Replaces);
963     if (!ChangedCode) {
964       llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
965       continue;
966     }
967     // Replacements on the changed code for moving namespaces and inserting
968     // forward declarations to old namespaces.
969     tooling::Replacements NewReplacements;
970     // Cut the changed code from the old namespace and paste the code in the new
971     // namespace.
972     for (const auto &NsMove : NsMoves) {
973       // Calculate the range of the old namespace block in the changed
974       // code.
975       const unsigned NewOffset = Replaces.getShiftedCodePosition(NsMove.Offset);
976       const unsigned NewLength =
977           Replaces.getShiftedCodePosition(NsMove.Offset + NsMove.Length) -
978           NewOffset;
979       tooling::Replacement Deletion(FilePath, NewOffset, NewLength, "");
980       std::string MovedCode = ChangedCode->substr(NewOffset, NewLength);
981       std::string MovedCodeWrappedInNewNs =
982           wrapCodeInNamespace(DiffNewNamespace, MovedCode);
983       // Calculate the new offset at which the code will be inserted in the
984       // changed code.
985       unsigned NewInsertionOffset =
986           Replaces.getShiftedCodePosition(NsMove.InsertionOffset);
987       tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0,
988                                      MovedCodeWrappedInNewNs);
989       addOrMergeReplacement(Deletion, &NewReplacements);
990       addOrMergeReplacement(Insertion, &NewReplacements);
991     }
992     // After moving namespaces, insert forward declarations back to old
993     // namespaces.
994     const auto &FwdDeclInsertions = InsertFwdDecls[FilePath];
995     for (const auto &FwdDeclInsertion : FwdDeclInsertions) {
996       unsigned NewInsertionOffset =
997           Replaces.getShiftedCodePosition(FwdDeclInsertion.InsertionOffset);
998       tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0,
999                                      FwdDeclInsertion.ForwardDeclText);
1000       addOrMergeReplacement(Insertion, &NewReplacements);
1001     }
1002     // Add replacements referring to the changed code to existing replacements,
1003     // which refers to the original code.
1004     Replaces = Replaces.merge(NewReplacements);
1005     auto Style =
1006         format::getStyle(format::DefaultFormatStyle, FilePath, FallbackStyle);
1007     if (!Style) {
1008       llvm::errs() << llvm::toString(Style.takeError()) << "\n";
1009       continue;
1010     }
1011     // Clean up old namespaces if there is nothing in it after moving.
1012     auto CleanReplacements =
1013         format::cleanupAroundReplacements(Code, Replaces, *Style);
1014     if (!CleanReplacements) {
1015       llvm::errs() << llvm::toString(CleanReplacements.takeError()) << "\n";
1016       continue;
1017     }
1018     FileToReplacements[FilePath] = *CleanReplacements;
1019   }
1020 
1021   // Make sure we don't generate replacements for files that do not match
1022   // FilePattern.
1023   for (auto &Entry : FileToReplacements)
1024     if (!FilePatternRE.match(Entry.first))
1025       Entry.second.clear();
1026 }
1027 
1028 } // namespace change_namespace
1029 } // namespace clang
1030