1
1
#include " TypeTranslator.h"
2
2
#include " Utils.h"
3
+ #include " ir/types/ArrayType.h"
4
+ #include " ir/types/FunctionPointerType.h"
5
+ #include " ir/types/PointerType.h"
6
+ #include " ir/types/SimpleType.h"
3
7
4
- TypeTranslator::TypeTranslator (clang::ASTContext *ctx_) : ctx(ctx_), typeMap() {
8
+ TypeTranslator::TypeTranslator (clang::ASTContext *ctx_, IR &ir)
9
+ : ctx(ctx_), ir(ir), typeMap() {
5
10
6
11
// Native Types
7
12
typeMap[" void" ] = " Unit" ;
@@ -29,35 +34,22 @@ TypeTranslator::TypeTranslator(clang::ASTContext *ctx_) : ctx(ctx_), typeMap() {
29
34
typeMap[" double" ] = " native.CDouble" ;
30
35
}
31
36
32
- std::string
33
- TypeTranslator::TranslateFunctionPointer (const clang::QualType &qtpe,
34
- const std::string *avoid) {
35
- const clang::PointerType *ptr =
36
- qtpe.getTypePtr ()->getAs <clang::PointerType>();
37
+ Type *TypeTranslator::translateFunctionPointer (const clang::QualType &qtpe,
38
+ const std::string *avoid) {
39
+ const auto *ptr = qtpe.getTypePtr ()->getAs <clang::PointerType>();
37
40
const clang::QualType &inner = ptr->getPointeeType ();
38
41
39
42
if (inner->isFunctionProtoType ()) {
40
- const clang::FunctionProtoType *fc =
41
- inner->getAs <clang::FunctionProtoType>();
42
- std::string ret = Translate (fc->getReturnType (), avoid);
43
- std::string params = " " ;
44
- int counter = 0 ;
43
+ const auto *fc = inner->getAs <clang::FunctionProtoType>();
44
+ Type *returnType = translate (fc->getReturnType (), avoid);
45
+ std::vector<Type *> parametersTypes;
45
46
46
47
for (const clang::QualType ¶m : fc->param_types ()) {
47
- params += Translate (param, avoid);
48
- params += " , " ;
49
- counter++;
48
+ parametersTypes.push_back (translate (param, avoid));
50
49
}
51
50
52
- std::string variad = " " ;
53
-
54
- if (fc->isVariadic ()) {
55
- counter++;
56
- variad = " native.CVararg, " ;
57
- }
58
-
59
- return std::string (" native.CFunctionPtr" ) + std::to_string (counter) +
60
- " [" + params + variad + ret + " ]" ;
51
+ return new FunctionPointerType (returnType, parametersTypes,
52
+ fc->isVariadic ());
61
53
62
54
} else {
63
55
llvm::errs () << " Unsupported function pointer type: "
@@ -67,107 +59,143 @@ TypeTranslator::TranslateFunctionPointer(const clang::QualType &qtpe,
67
59
}
68
60
}
69
61
70
- std::string TypeTranslator::TranslatePointer (const clang::QualType &pte,
71
- const std::string *avoid) {
62
+ Type * TypeTranslator::TranslatePointer (const clang::QualType &pte,
63
+ const std::string *avoid) {
72
64
73
65
if (pte->isBuiltinType ()) {
74
66
const clang::BuiltinType *as = pte->getAs <clang::BuiltinType>();
75
67
76
68
// Take care of void*
77
69
if (as->getKind () == clang::BuiltinType::Void) {
78
- return " native.Ptr[ Byte] " ;
70
+ return new PointerType ( new SimpleType ( " Byte" )) ;
79
71
}
80
72
81
73
// Take care of char*
82
74
if (as->getKind () == clang::BuiltinType::Char_S ||
83
75
as->getKind () == clang::BuiltinType::SChar) {
84
- return " native.CString" ;
76
+ return new SimpleType ( " native.CString" ) ;
85
77
}
86
78
}
87
79
88
- return std::string (" native.Ptr[" ) + Translate (pte, avoid) +
89
- std::string (" ]" );
80
+ return new PointerType (translate (pte, avoid));
90
81
}
91
82
92
- std::string
93
- TypeTranslator::TranslateStructOrUnion (const clang::QualType &qtpe) {
83
+ Type *TypeTranslator::translateStruct (const clang::QualType &qtpe) {
94
84
if (qtpe->hasUnnamedOrLocalType ()) {
95
85
// TODO: Verify that the local part is not a problem
96
86
uint64_t size = ctx->getTypeSize (qtpe);
97
- return " native.CArray[ Byte, " + uint64ToScalaNat ( size) + " ] " ;
87
+ return new ArrayType ( new SimpleType ( " Byte" ), size);
98
88
}
99
89
100
90
std::string name = qtpe.getUnqualifiedType ().getAsString ();
101
91
102
92
// TODO: do it properly
103
93
size_t f = name.find (std::string (" struct __dirstream" ));
104
94
if (f != std::string::npos) {
105
- return std::string ( " native.CArray[ Byte, Digit[_3, Digit[_2, _0]]] " );
95
+ return new ArrayType ( new SimpleType ( " Byte" ), 320 );
106
96
}
107
97
108
- f = name.find (" " );
109
- if (f != std::string::npos) {
110
- return name.replace (f, std::string (" " ).length (), " _" );
98
+ auto it = aliasesMap.find (name);
99
+ if (it != aliasesMap.end ()) {
100
+ /* name contains space: struct <name>.
101
+ * Use type alias instead struct type */
102
+ return (*it).second ;
111
103
}
112
- return name;
104
+ /* type has typedef alias */
105
+ return ir.getTypeDefWithName (name);
113
106
}
114
107
115
- std::string TypeTranslator::TranslateEnum (const clang::QualType &qtpe) {
108
+ Type *TypeTranslator::translateUnion (const clang::QualType &qtpe) {
109
+ if (qtpe->hasUnnamedOrLocalType ()) {
110
+ // TODO: Verify that the local part is not a problem
111
+ uint64_t size = ctx->getTypeSize (qtpe);
112
+ return new ArrayType (new SimpleType (" Byte" ), size);
113
+ }
114
+
116
115
std::string name = qtpe.getUnqualifiedType ().getAsString ();
117
- size_t f = name.find (" " );
118
- if (f != std::string::npos) {
119
- return name.replace (f, std::string (" " ).length (), " _" );
116
+
117
+ auto it = aliasesMap.find (name);
118
+ if (it != aliasesMap.end ()) {
119
+ /* name contains space: union <name>.
120
+ * Use type alias instead union type */
121
+ return (*it).second ;
120
122
}
121
- return name;
123
+ /* type has typedef alias */
124
+ return ir.getTypeDefWithName (name);
122
125
}
123
126
124
- std::string
125
- TypeTranslator::TranslateConstantArray (const clang::ConstantArrayType *ar,
126
- const std::string *avoid) {
127
+ Type *TypeTranslator::translateEnum (const clang::QualType &qtpe) {
128
+ std::string name = qtpe.getUnqualifiedType ().getAsString ();
129
+
130
+ auto it = aliasesMap.find (name);
131
+ if (it != aliasesMap.end ()) {
132
+ /* name contains space: enum <name>.
133
+ * Use type alias instead enum type */
134
+ return (*it).second ;
135
+ }
136
+ /* type has typedef alias */
137
+ return ir.getTypeDefWithName (name);
138
+ }
139
+
140
+ Type *TypeTranslator::translateConstantArray (const clang::ConstantArrayType *ar,
141
+ const std::string *avoid) {
127
142
const uint64_t size = ar->getSize ().getZExtValue ();
128
- const std::string nat = uint64ToScalaNat (size);
129
- return " native.CArray[" + Translate (ar->getElementType (), avoid) + " , " +
130
- nat + " ]" ;
143
+ return new ArrayType (translate (ar->getElementType (), avoid), size);
131
144
}
132
145
133
- std::string TypeTranslator::Translate (const clang::QualType &qtpe,
134
- const std::string *avoid) {
146
+ Type * TypeTranslator::translate (const clang::QualType &qtpe,
147
+ const std::string *avoid) {
135
148
136
149
const clang::Type *tpe = qtpe.getTypePtr ();
137
150
138
151
if (typeEquals (tpe, avoid)) {
139
152
// This is a type that we want to avoid the usage.
140
- // Êxample: A struct that has a pointer to itself
153
+ // Êxample: A struct that has a pointer to itself
141
154
uint64_t size = ctx->getTypeSize (tpe);
142
- return " native.CArray[ Byte, " + uint64ToScalaNat ( size) + " ] " ;
155
+ return new ArrayType ( new SimpleType ( " Byte" ), size);
143
156
}
144
157
145
158
if (tpe->isFunctionPointerType ()) {
146
- return TranslateFunctionPointer (qtpe, avoid);
159
+ return translateFunctionPointer (qtpe, avoid);
147
160
148
161
} else if (tpe->isPointerType ()) {
149
162
return TranslatePointer (
150
163
tpe->getAs <clang::PointerType>()->getPointeeType (), avoid);
151
164
152
- } else if (qtpe->isStructureType () || qtpe->isUnionType ()) {
153
- return handleReservedWords (TranslateStructOrUnion (qtpe));
165
+ } else if (qtpe->isStructureType ()) {
166
+ return translateStruct (qtpe);
167
+
168
+ } else if (qtpe->isUnionType ()) {
169
+ return translateUnion (qtpe);
154
170
155
171
} else if (qtpe->isEnumeralType ()) {
156
- return TranslateEnum (qtpe);
172
+ return translateEnum (qtpe);
157
173
158
174
} else if (qtpe->isConstantArrayType ()) {
159
- return TranslateConstantArray (ctx->getAsConstantArrayType (qtpe), avoid);
175
+ return translateConstantArray (ctx->getAsConstantArrayType (qtpe), avoid);
160
176
} else if (qtpe->isArrayType ()) {
161
177
return TranslatePointer (ctx->getAsArrayType (qtpe)->getElementType (),
162
178
avoid);
163
179
} else {
164
180
165
181
auto found = typeMap.find (qtpe.getUnqualifiedType ().getAsString ());
166
182
if (found != typeMap.end ()) {
167
- return handleReservedWords (found->second );
183
+ return new SimpleType (found->second );
168
184
} else {
169
- // TODO: Properly handle non-default types
170
- return handleReservedWords ( qtpe.getUnqualifiedType ().getAsString ());
185
+ return ir. getTypeDefWithName (
186
+ qtpe.getUnqualifiedType ().getAsString ());
171
187
}
172
188
}
173
189
}
190
+
191
+ void TypeTranslator::addAlias (std::string cName, Type *type) {
192
+ aliasesMap[cName] = type;
193
+ }
194
+
195
+ std::string TypeTranslator::getTypeFromTypeMap (std::string cType) {
196
+ auto it = typeMap.find (cType);
197
+ if (it != typeMap.end ()) {
198
+ return (*it).second ;
199
+ }
200
+ return " " ;
201
+ }
0 commit comments