forked from checkedc/checkedc-clang
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathDuplicate.cpp
More file actions
80 lines (68 loc) · 2.23 KB
/
Duplicate.cpp
File metadata and controls
80 lines (68 loc) · 2.23 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "clang/3C/Duplicate.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/3C/ProgramInfo.h"
#include "clang/Rewrite/Core/Rewriter.h"
using namespace clang;
using namespace llvm;
using namespace std;
// Recursive Visitor
class FindVarDecl : public RecursiveASTVisitor<FindVarDecl> {
public:
explicit FindVarDecl(ASTContext &Context, Rewriter &R,
ProgramInfo &I, selector P)
: Context(Context), R(R), Info(I), P(P) {}
bool VisitVarDecl(VarDecl *VD) {
// If the selctor matches execute the duplicate function
// and store the new name in the optional
if(P(VD)){
auto NewName = addDuplicate(VD);
Replacement = { NewName };
return false;
} else {
return true;
}
}
Option<string> didReplace(void) {
return Replacement;
}
private:
// Insert the duplicate into the rewriter
// Returns the new var's name
string addDuplicate(VarDecl *VD) {
SourceLocation End = VD->getEndLoc();
auto Dup = createDuplicateString(VD);
R.InsertTextAfterToken(End, Dup.second);
return Dup.first;
}
// Create the text for the new variable
// Returns a pair containing the new name
// and the new line containing declaration and assignment
pair<string,string> createDuplicateString(VarDecl *VD) {
auto CV = Info.getVariable(VD, &Context);
auto Type =
CV.hasValue() ?
CV.getValue()
.mkString(Info.getConstraints().getVariables(),
false)
: VD->getType().getAsString();
auto TargetName = VD->getNameAsString();
auto NewName = "__" + TargetName + "_copy";
return make_pair(NewName, ";\n" + Type + " " + NewName + "= " + TargetName + "");
}
ASTContext &Context;
Rewriter &R;
ProgramInfo &Info;
// Predicate for finding the variable to duplicate
selector P;
// Duplicate's name or none if var not found
Option<string> Replacement = {};
};
// Main entrypoint
Option<string> createDuplicate(ASTContext &Context, Rewriter &R,
ProgramInfo &Info,
Decl *FD, selector P) {
auto V = FindVarDecl(Context, R, Info, P);
V.TraverseDecl(FD);
return V.didReplace();
}