Index: change-namespace/ChangeNamespace.h =================================================================== --- change-namespace/ChangeNamespace.h +++ change-namespace/ChangeNamespace.h @@ -50,6 +50,7 @@ // files matching `FilePattern`. ChangeNamespaceTool( llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, + llvm::ArrayRef WhiteListedSymbolPatterns, std::map *FileToReplacements, llvm::StringRef FallbackStyle = "LLVM"); @@ -164,6 +165,9 @@ // CallExpr and one as DeclRefExpr), we record all DeclRefExpr's that have // been processed so that we don't handle them twice. llvm::SmallPtrSet ProcessedFuncRefs; + // Patterns of symbol names whose references are not expected to be updated + // when changing namespaces around them. + std::vector WhiteListedSymbolRegexes; }; } // namespace change_namespace Index: change-namespace/ChangeNamespace.cpp =================================================================== --- change-namespace/ChangeNamespace.cpp +++ change-namespace/ChangeNamespace.cpp @@ -290,6 +290,7 @@ ChangeNamespaceTool::ChangeNamespaceTool( llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, + llvm::ArrayRef WhiteListedSymbolPatterns, std::map *FileToReplacements, llvm::StringRef FallbackStyle) : FallbackStyle(FallbackStyle), FileToReplacements(*FileToReplacements), @@ -308,6 +309,11 @@ } DiffOldNamespace = joinNamespaces(OldNsSplitted); DiffNewNamespace = joinNamespaces(NewNsSplitted); + + for (const char *Pattern : WhiteListedSymbolPatterns) { + llvm::errs() << "Whitelisting " << Pattern << "\n"; + WhiteListedSymbolRegexes.emplace_back(Pattern); + } } void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { @@ -736,6 +742,9 @@ Result.SourceManager->getSpellingLoc(End)), *Result.SourceManager, Result.Context->getLangOpts()); std::string FromDeclName = FromDecl->getQualifiedNameAsString(); + for (llvm::Regex &RE : WhiteListedSymbolRegexes) + if (RE.match(FromDeclName)) + return; std::string ReplaceName = getShortestQualifiedNameInNamespace(FromDeclName, NewNs); // Checks if there is any using namespace declarations that can shorten the Index: change-namespace/tool/ClangChangeNamespace.cpp =================================================================== --- change-namespace/tool/ClangChangeNamespace.cpp +++ change-namespace/tool/ClangChangeNamespace.cpp @@ -73,6 +73,10 @@ cl::desc("The style name used for reformatting."), cl::init("LLVM"), cl::cat(ChangeNamespaceCategory)); +// Patterns of symbol names whose references are not expected to be updated when +// changing namespaces around them. +constexpr const char *WhiteListedSymbolPatterns[] = {"^std::.*$"}; + } // anonymous namespace int main(int argc, const char **argv) { @@ -82,7 +86,8 @@ const auto &Files = OptionsParser.getSourcePathList(); tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files); change_namespace::ChangeNamespaceTool NamespaceTool( - OldNamespace, NewNamespace, FilePattern, &Tool.getReplacements(), Style); + OldNamespace, NewNamespace, FilePattern, WhiteListedSymbolPatterns, + &Tool.getReplacements(), Style); ast_matchers::MatchFinder Finder; NamespaceTool.registerMatchers(&Finder); std::unique_ptr Factory = Index: test/change-namespace/Inputs/fake-std.h =================================================================== --- /dev/null +++ test/change-namespace/Inputs/fake-std.h @@ -0,0 +1,5 @@ +namespace std { + class STD {}; +} + +using namespace std; Index: test/change-namespace/white-list.cpp =================================================================== --- /dev/null +++ test/change-namespace/white-list.cpp @@ -0,0 +1,18 @@ +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- | sed 's,// CHECK.*,,' | FileCheck %s + +#include "Inputs/fake-std.h" + +// CHECK: namespace x { +// CHECK-NEXT: namespace y { +namespace na { +namespace nb { +void f() { + std::STD x1; + STD x2; +// CHECK: {{^}} std::STD x1;{{$}} +// CHECK-NEXT: {{^}} STD x2;{{$}} +} +// CHECK: } // namespace y +// CHECK-NEXT: } // namespace x +} +} Index: unittests/change-namespace/ChangeNamespaceTests.cpp =================================================================== --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ unittests/change-namespace/ChangeNamespaceTests.cpp @@ -37,8 +37,10 @@ clang::FileID ID = Context.createInMemoryFile(FileName, Code); std::map FileToReplacements; + constexpr const char *WhiteListedSymbolPatterns[] = {"^std::.*$"}; change_namespace::ChangeNamespaceTool NamespaceTool( - OldNamespace, NewNamespace, FilePattern, &FileToReplacements); + OldNamespace, NewNamespace, FilePattern, WhiteListedSymbolPatterns, + &FileToReplacements); ast_matchers::MatchFinder Finder; NamespaceTool.registerMatchers(&Finder); std::unique_ptr Factory =