-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathTreeVisitor.cpp
134 lines (110 loc) · 4.6 KB
/
TreeVisitor.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "TreeVisitor.h"
#include "../Utils.h"
bool TreeVisitor::VisitFunctionDecl(clang::FunctionDecl *func) {
if (!astContext->getSourceManager().isInMainFile(func->getLocation())) {
/* include functions only from the original header */
return true;
}
std::string funcName = func->getNameInfo().getName().getAsString();
std::shared_ptr<Type> retType =
typeTranslator.translate(func->getReturnType());
std::vector<std::shared_ptr<Parameter>> parameters;
int anonCounter = 0;
for (const clang::ParmVarDecl *parm : func->parameters()) {
// Handle default values
std::string pname = parm->getNameAsString();
if (pname.empty()) {
pname = "p" + std::to_string(anonCounter++);
}
std::shared_ptr<Type> ptype = typeTranslator.translate(parm->getType());
parameters.emplace_back(std::make_shared<Parameter>(pname, ptype));
}
ir.addFunction(funcName, std::move(parameters), retType,
func->isVariadic());
return true;
}
bool TreeVisitor::VisitTypedefDecl(clang::TypedefDecl *tpdef) {
std::string name = tpdef->getName();
if (isAliasForAnonymousEnum(tpdef)) {
/* typedef was already created */
return true;
}
std::shared_ptr<Type> type =
typeTranslator.translate(tpdef->getUnderlyingType());
if (type) {
ir.addTypeDef(name, type, typeTranslator.getLocation(tpdef));
}
return true;
}
bool TreeVisitor::isAliasForAnonymousEnum(clang::TypedefDecl *tpdef) const {
clang::QualType underlyingType = tpdef->getUnderlyingType();
if (!underlyingType->isEnumeralType()) {
return false;
}
const clang::EnumType *enumType = underlyingType->getAs<clang::EnumType>();
return enumType->getDecl()->getTypedefNameForAnonDecl();
}
bool TreeVisitor::VisitEnumDecl(clang::EnumDecl *enumDecl) {
std::string name = enumDecl->getNameAsString();
clang::TypedefNameDecl *typedefName = enumDecl->getTypedefNameForAnonDecl();
if (name.empty() && typedefName) {
name = typedefName->getNameAsString();
}
std::vector<Enumerator> enumerators;
for (const clang::EnumConstantDecl *en : enumDecl->enumerators()) {
int64_t value = en->getInitVal().getSExtValue();
enumerators.emplace_back(en->getNameAsString(), value);
}
std::string scalaType = typeTranslator.getTypeFromTypeMap(
enumDecl->getIntegerType().getUnqualifiedType().getAsString());
std::shared_ptr<Location> location = typeTranslator.getLocation(enumDecl);
if (name.empty()) {
name = "anonymous_" + std::to_string(anonymousEnumId++);
}
std::shared_ptr<Enum> e =
ir.addEnum(name, scalaType, std::move(enumerators), location);
if (typedefName) {
/* add alias here because in VisitTypedefDecl it will be difficult to
* match typedef with enum */
ir.addTypeDef(name, e, typeTranslator.getLocation(typedefName));
}
return true;
}
bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record) {
std::string name = record->getNameAsString();
// Handle typedef struct {} x; and typedef union {} y; by getting the name
// from the typedef
if ((record->isStruct() || record->isUnion()) && name.empty() &&
record->getTypedefNameForAnonDecl()) {
name = record->getTypedefNameForAnonDecl()->getNameAsString();
}
if (record->isUnion() && record->isThisDeclarationADefinition() &&
!record->isAnonymousStructOrUnion() && !name.empty()) {
typeTranslator.addUnionDefinition(record, name);
return true;
} else if (record->isStruct() && record->isThisDeclarationADefinition() &&
!record->isAnonymousStructOrUnion() && !name.empty()) {
typeTranslator.addStructDefinition(record, name);
return true;
}
return false;
}
bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) {
if (!astContext->getSourceManager().isInMainFile(varDecl->getLocation())) {
/* include variables only from the original header */
return true;
}
if (!varDecl->isThisDeclarationADefinition()) {
std::string variableName = varDecl->getName().str();
std::shared_ptr<Type> type =
typeTranslator.translate(varDecl->getType());
std::shared_ptr<Variable> variable = ir.addVariable(variableName, type);
/* check if there is a macro for the variable.
* Macros were saved by DefineFinder */
std::string macroName = ir.getDefineForVar(variableName);
if (!macroName.empty()) {
ir.addVarDefine(macroName, variable);
}
}
return true;
}