-
Notifications
You must be signed in to change notification settings - Fork 0
/
replace-decls.cpp
65 lines (54 loc) · 2.43 KB
/
replace-decls.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#ifndef REPLACEDECL_H
#define REPLACEDECL_H
#include "common.h"
// matches a field in a namespace
namespace clang { namespace ast_matchers {
AST_MATCHER_P(Decl, inNamespace, internal::Matcher<clang::NamespaceDecl>, InnerMatcher) {
auto ns = llvm::dyn_cast<const clang::NamespaceDecl>(Node.getDeclContext()->getEnclosingNamespaceContext());
return (ns && InnerMatcher.matches(*ns, Finder, Builder));
}
} }
// inspired by http://llvm.org/svn/llvm-project/clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp
struct ReplaceDecls : clang::ast_matchers::MatchFinder {
struct Callback : clang::ast_matchers::MatchFinder::MatchCallback {
clang::tooling::Replacements & replacements;
Callback(clang::tooling::Replacements & replacements) : replacements(replacements) {}
void run(const MatchFinder::MatchResult & result) override {
if(const clang::Decl * decl = result.Nodes.getNodeAs<clang::Decl>("x")) {
auto & sm = *result.SourceManager;
auto start = sm.getSpellingLoc(decl->getLocStart()), end = sm.getSpellingLoc(decl->getLocEnd());
std::string original(
sm.getCharacterData(start),
sm.getDecomposedLoc(clang::Lexer::getLocForEndOfToken(end, 0, sm, clang::LangOptions())).second
- sm.getDecomposedLoc(start).second
);
std::stringstream ss;
ss << original << '_' << original.size();
std::string replacement = ss.str();
//decl->dump();
std::cout << original << " ==> " << replacement << std::endl;
replacements.insert(clang::tooling::Replacement(sm, clang::CharSourceRange::getTokenRange(decl->getSourceRange()), replacement));
}
}
};
static int run(const clang::tooling::CompilationDatabase & db, llvm::ArrayRef<std::string> sources) {
using namespace clang::ast_matchers;
auto match_decl = fieldDecl(inNamespace(hasName("test"))).bind("x");
clang::tooling::RefactoringTool tool(db, sources);
Callback callback(tool.getReplacements());
ReplaceDecls replace_decls;
replace_decls.addMatcher(match_decl, &callback);
auto ret = tool.run(clang::tooling::newFrontendActionFactory(&replace_decls));
std::cout << "\nPatch shown below:" << std::endl;
for(auto & replacement : tool.getReplacements()) {
std::cout << " " << replacement.toString() << std::endl;
}
return ret;
}
};
namespace tools {
int replace_decls(const clang::tooling::CompilationDatabase & db, llvm::ArrayRef<std::string> sources) {
return ReplaceDecls::run(db, sources);
}
}
#endif // REPLACEDECL_H