Skip to content

Commit 7fccc99

Browse files
author
Eric Liu
committedFeb 24, 2017
[change-namepsace] make it possible to whitelist symbols so they don't get updated.
Reviewers: hokein Reviewed By: hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30328 llvm-svn: 296110
1 parent 4f8a443 commit 7fccc99

File tree

6 files changed

+65
-2
lines changed

6 files changed

+65
-2
lines changed
 

‎clang-tools-extra/change-namespace/ChangeNamespace.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ AST_MATCHER(EnumDecl, isScoped) {
290290

291291
ChangeNamespaceTool::ChangeNamespaceTool(
292292
llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern,
293+
llvm::ArrayRef<std::string> WhiteListedSymbolPatterns,
293294
std::map<std::string, tooling::Replacements> *FileToReplacements,
294295
llvm::StringRef FallbackStyle)
295296
: FallbackStyle(FallbackStyle), FileToReplacements(*FileToReplacements),
@@ -308,6 +309,9 @@ ChangeNamespaceTool::ChangeNamespaceTool(
308309
}
309310
DiffOldNamespace = joinNamespaces(OldNsSplitted);
310311
DiffNewNamespace = joinNamespaces(NewNsSplitted);
312+
313+
for (const auto &Pattern : WhiteListedSymbolPatterns)
314+
WhiteListedSymbolRegexes.emplace_back(Pattern);
311315
}
312316

313317
void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
@@ -736,6 +740,9 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext(
736740
Result.SourceManager->getSpellingLoc(End)),
737741
*Result.SourceManager, Result.Context->getLangOpts());
738742
std::string FromDeclName = FromDecl->getQualifiedNameAsString();
743+
for (llvm::Regex &RE : WhiteListedSymbolRegexes)
744+
if (RE.match(FromDeclName))
745+
return;
739746
std::string ReplaceName =
740747
getShortestQualifiedNameInNamespace(FromDeclName, NewNs);
741748
// Checks if there is any using namespace declarations that can shorten the

‎clang-tools-extra/change-namespace/ChangeNamespace.h

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class ChangeNamespaceTool : public ast_matchers::MatchFinder::MatchCallback {
5050
// files matching `FilePattern`.
5151
ChangeNamespaceTool(
5252
llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern,
53+
llvm::ArrayRef<std::string> WhiteListedSymbolPatterns,
5354
std::map<std::string, tooling::Replacements> *FileToReplacements,
5455
llvm::StringRef FallbackStyle = "LLVM");
5556

@@ -164,6 +165,9 @@ class ChangeNamespaceTool : public ast_matchers::MatchFinder::MatchCallback {
164165
// CallExpr and one as DeclRefExpr), we record all DeclRefExpr's that have
165166
// been processed so that we don't handle them twice.
166167
llvm::SmallPtrSet<const clang::DeclRefExpr*, 16> ProcessedFuncRefs;
168+
// Patterns of symbol names whose references are not expected to be updated
169+
// when changing namespaces around them.
170+
std::vector<llvm::Regex> WhiteListedSymbolRegexes;
167171
};
168172

169173
} // namespace change_namespace

‎clang-tools-extra/change-namespace/tool/ClangChangeNamespace.cpp

+28-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,25 @@ cl::opt<std::string> Style("style",
7373
cl::desc("The style name used for reformatting."),
7474
cl::init("LLVM"), cl::cat(ChangeNamespaceCategory));
7575

76+
cl::opt<std::string> WhiteListFile(
77+
"whitelist_file",
78+
cl::desc("A file containing regexes of symbol names that are not expected "
79+
"to be updated when changing namespaces around them."),
80+
cl::init(""), cl::cat(ChangeNamespaceCategory));
81+
82+
llvm::ErrorOr<std::vector<std::string>> GetWhiteListedSymbolPatterns() {
83+
llvm::SmallVector<StringRef, 8> Lines;
84+
if (!WhiteListFile.empty()) {
85+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
86+
llvm::MemoryBuffer::getFile(WhiteListFile);
87+
if (!File)
88+
return File.getError();
89+
llvm::StringRef Content = File.get()->getBuffer();
90+
Content.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
91+
}
92+
return std::vector<std::string>(Lines.begin(), Lines.end());
93+
}
94+
7695
} // anonymous namespace
7796

7897
int main(int argc, const char **argv) {
@@ -81,8 +100,16 @@ int main(int argc, const char **argv) {
81100
ChangeNamespaceCategory);
82101
const auto &Files = OptionsParser.getSourcePathList();
83102
tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files);
103+
llvm::ErrorOr<std::vector<std::string>> WhiteListPatterns =
104+
GetWhiteListedSymbolPatterns();
105+
if (!WhiteListPatterns) {
106+
llvm::errs() << "Failed to open whitelist file " << WhiteListFile << ". "
107+
<< WhiteListPatterns.getError().message() << "\n";
108+
return 1;
109+
}
84110
change_namespace::ChangeNamespaceTool NamespaceTool(
85-
OldNamespace, NewNamespace, FilePattern, &Tool.getReplacements(), Style);
111+
OldNamespace, NewNamespace, FilePattern, *WhiteListPatterns,
112+
&Tool.getReplacements(), Style);
86113
ast_matchers::MatchFinder Finder;
87114
NamespaceTool.registerMatchers(&Finder);
88115
std::unique_ptr<tooling::FrontendActionFactory> Factory =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace std {
2+
class STD {};
3+
}
4+
5+
using namespace std;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: echo "^std::.*$" > %T/white-list.txt
2+
// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --whitelist_file %T/white-list.txt %s -- | sed 's,// CHECK.*,,' | FileCheck %s
3+
4+
#include "Inputs/fake-std.h"
5+
6+
// CHECK: namespace x {
7+
// CHECK-NEXT: namespace y {
8+
namespace na {
9+
namespace nb {
10+
void f() {
11+
std::STD x1;
12+
STD x2;
13+
// CHECK: {{^}} std::STD x1;{{$}}
14+
// CHECK-NEXT: {{^}} STD x2;{{$}}
15+
}
16+
// CHECK: } // namespace y
17+
// CHECK-NEXT: } // namespace x
18+
}
19+
}

‎clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class ChangeNamespaceTest : public ::testing::Test {
3838

3939
std::map<std::string, tooling::Replacements> FileToReplacements;
4040
change_namespace::ChangeNamespaceTool NamespaceTool(
41-
OldNamespace, NewNamespace, FilePattern, &FileToReplacements);
41+
OldNamespace, NewNamespace, FilePattern,
42+
/*WhiteListedSymbolPatterns*/ {}, &FileToReplacements);
4243
ast_matchers::MatchFinder Finder;
4344
NamespaceTool.registerMatchers(&Finder);
4445
std::unique_ptr<tooling::FrontendActionFactory> Factory =

0 commit comments

Comments
 (0)
Please sign in to comment.