1
+ #include " clang/AST/ASTConsumer.h"
2
+ #include " clang/AST/RecursiveASTVisitor.h"
3
+ #include " clang/Frontend/CompilerInstance.h"
4
+ #include " clang/Frontend/FrontendPluginRegistry.h"
5
+ #include " clang/Rewrite/Core/Rewriter.h"
6
+
7
+ #include " llvm/ADT/StringRef.h"
8
+ #include " llvm/Support/raw_ostream.h"
9
+
10
+ class RenameVisitor : public clang ::RecursiveASTVisitor<RenameVisitor> {
11
+ private:
12
+ clang::Rewriter Rewriter;
13
+ std::string OldName;
14
+ std::string NewName;
15
+
16
+ public:
17
+ explicit RenameVisitor (clang::Rewriter Rewriter, std::string OldName,
18
+ std::string NewName)
19
+ : Rewriter(Rewriter), OldName(OldName), NewName(NewName){};
20
+
21
+ bool VisitFunctionDecl (clang::FunctionDecl *FD) {
22
+ std::string Name = FD->getNameAsString ();
23
+
24
+ if (Name == OldName) {
25
+ Rewriter.ReplaceText (FD->getNameInfo ().getSourceRange (), NewName);
26
+ Rewriter.overwriteChangedFiles ();
27
+ }
28
+
29
+ return true ;
30
+ }
31
+
32
+ bool VisitDeclRefExpr (clang::DeclRefExpr *DRE) {
33
+ std::string Name = DRE->getNameInfo ().getAsString ();
34
+
35
+ if (Name == OldName) {
36
+ Rewriter.ReplaceText (DRE->getNameInfo ().getSourceRange (), NewName);
37
+ Rewriter.overwriteChangedFiles ();
38
+ }
39
+
40
+ return true ;
41
+ }
42
+
43
+ bool VisitVarDecl (clang::VarDecl *VD) {
44
+ std::string Name = VD->getNameAsString ();
45
+
46
+ if (Name == OldName) {
47
+ Rewriter.ReplaceText (VD->getLocation (), Name.size (), NewName);
48
+ Rewriter.overwriteChangedFiles ();
49
+ }
50
+
51
+ if (VD->getType ().getAsString () == OldName + " *" ||
52
+ VD->getType ().getAsString () == OldName) {
53
+ Rewriter.ReplaceText (VD->getTypeSourceInfo ()->getTypeLoc ().getBeginLoc (),
54
+ Name.size (), NewName);
55
+ Rewriter.overwriteChangedFiles ();
56
+ }
57
+
58
+ return true ;
59
+ }
60
+
61
+ bool VisitCXXRecordDecl (clang::CXXRecordDecl *CXXRD) {
62
+ std::string Name = CXXRD->getNameAsString ();
63
+
64
+ if (Name == OldName) {
65
+ Rewriter.ReplaceText (CXXRD->getLocation (), Name.size (), NewName);
66
+
67
+ const clang::CXXDestructorDecl *CXXDD = CXXRD->getDestructor ();
68
+ if (CXXDD)
69
+ Rewriter.ReplaceText (CXXDD->getLocation (), Name.size () + 1 ,
70
+ " ~" + NewName);
71
+
72
+ Rewriter.overwriteChangedFiles ();
73
+ }
74
+
75
+ return true ;
76
+ }
77
+
78
+ bool VisitCXXNewExpr (clang::CXXNewExpr *CXXNE) {
79
+ std::string Name = CXXNE->getConstructExpr ()->getType ().getAsString ();
80
+
81
+ if (Name == OldName) {
82
+ Rewriter.ReplaceText (CXXNE->getExprLoc (), Name.size () + 4 ,
83
+ " new " + NewName);
84
+ Rewriter.overwriteChangedFiles ();
85
+ }
86
+
87
+ return true ;
88
+ }
89
+ };
90
+
91
+ class RenameIdConsumer : public clang ::ASTConsumer {
92
+ RenameVisitor visitor;
93
+
94
+ public:
95
+ explicit RenameIdConsumer (clang::CompilerInstance &CI, std::string OldName,
96
+ std::string NewName)
97
+ : visitor(clang::Rewriter(CI.getSourceManager(), CI.getLangOpts()),
98
+ OldName, NewName) {}
99
+
100
+ void HandleTranslationUnit (clang::ASTContext &Context) override {
101
+ visitor.TraverseDecl (Context.getTranslationUnitDecl ());
102
+ }
103
+ };
104
+
105
+ class RenameIdPlugin : public clang ::PluginASTAction {
106
+ private:
107
+ std::string OldName;
108
+ std::string NewName;
109
+
110
+ protected:
111
+ bool ParseArgs (const clang::CompilerInstance &Compiler,
112
+ const std::vector<std::string> &args) override {
113
+ OldName = args[0 ];
114
+ NewName = args[1 ];
115
+
116
+ if (OldName.find (" =" ) == 0 || OldName.find (" =" ) == std::string::npos) {
117
+ llvm::errs () << " Error entering the `OldName` parameter."
118
+ << " \n " ;
119
+ }
120
+ if (NewName.find (" =" ) == 0 || NewName.find (" =" ) == std::string::npos) {
121
+ llvm::errs () << " Error entering the `NewName` parameter."
122
+ << " \n " ;
123
+ }
124
+
125
+ OldName = OldName.substr (OldName.find (" =" ) + 1 );
126
+ NewName = NewName.substr (NewName.find (" =" ) + 1 );
127
+
128
+ return true ;
129
+ }
130
+
131
+ public:
132
+ std::unique_ptr<clang::ASTConsumer>
133
+ CreateASTConsumer (clang::CompilerInstance &Compiler,
134
+ llvm::StringRef InFile) override {
135
+ return std::make_unique<RenameIdConsumer>(Compiler, OldName, NewName);
136
+ }
137
+ };
138
+
139
+ static clang::FrontendPluginRegistry::Add<RenameIdPlugin>
140
+ X (" renamed-id" , " Idetificator was renamed." );
0 commit comments