Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp =================================================================== --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp @@ -676,19 +676,18 @@ const NamedDecl *FwdDecl) { SourceLocation Start = FwdDecl->getLocStart(); SourceLocation End = FwdDecl->getLocEnd(); + const SourceManager &SM = *Result.SourceManager; SourceLocation AfterSemi = Lexer::findLocationAfterToken( - End, tok::semi, *Result.SourceManager, Result.Context->getLangOpts(), + End, tok::semi, SM, Result.Context->getLangOpts(), /*SkipTrailingWhitespaceAndNewLine=*/true); if (AfterSemi.isValid()) End = AfterSemi.getLocWithOffset(-1); // Delete the forward declaration from the code to be moved. - addReplacementOrDie(Start, End, "", *Result.SourceManager, - &FileToReplacements); + addReplacementOrDie(Start, End, "", SM, &FileToReplacements); llvm::StringRef Code = Lexer::getSourceText( - CharSourceRange::getTokenRange( - Result.SourceManager->getSpellingLoc(Start), - Result.SourceManager->getSpellingLoc(End)), - *Result.SourceManager, Result.Context->getLangOpts()); + CharSourceRange::getTokenRange(SM.getSpellingLoc(Start), + SM.getSpellingLoc(End)), + SM, Result.Context->getLangOpts()); // Insert the forward declaration back into the old namespace after moving the // code from old namespace to new namespace. // Insertion information is stored in `InsertFwdDecls` and actual @@ -697,8 +696,9 @@ const auto *NsDecl = Result.Nodes.getNodeAs("ns_decl"); // The namespace contains the forward declaration, so it must not be empty. assert(!NsDecl->decls_empty()); - const auto Insertion = createInsertion(NsDecl->decls_begin()->getLocStart(), - Code, *Result.SourceManager); + const auto Insertion = createInsertion( + getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()), + Code, SM); InsertForwardDeclaration InsertFwd; InsertFwd.InsertionOffset = Insertion.getOffset(); InsertFwd.ForwardDeclText = Insertion.getReplacementText().str(); Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -375,6 +375,36 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, InsertForwardDeclsProperly) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "\n" + "class FWD;\n" + "class FWD2;\n" + "class A {\n" + " FWD *fwd;\n" + "};\n" + "\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "class FWD2;\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "\n" + "class A {\n" + " ::na::nb::FWD *fwd;\n" + "};\n" + "\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) { std::string Code = "namespace na {\n" "namespace nb {\n"