Skip to content

Commit 494e4d9

Browse files
committed
Store types in intermediate representation
1 parent 40a4d0e commit 494e4d9

37 files changed

+640
-346
lines changed

bindgen/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ add_executable(bindgen
5454
ir/Variable.h
5555
ir/PossibleVarDefine.cpp
5656
ir/PossibleVarDefine.h
57+
ir/types/Type.cpp
58+
ir/types/Type.h
59+
ir/types/SimpleType.cpp
60+
ir/types/SimpleType.h
61+
ir/types/PointerType.cpp
62+
ir/types/PointerType.h
63+
ir/types/FunctionPointerType.cpp
64+
ir/types/FunctionPointerType.h
65+
ir/types/ArrayType.cpp
66+
ir/types/ArrayType.h
5767
)
5868

5969
set_target_properties(bindgen

bindgen/CycleDetection.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ class CycleDetection {
2828
return;
2929
}
3030

31-
std::string qtpeString = tpeTransl.Translate(qtpe);
31+
Type *type = tpeTransl.translate(qtpe);
32+
if (type == nullptr) {
33+
/* temp fix for function pointer */
34+
return;
35+
}
36+
std::string qtpeString = type->str();
3237

3338
// Add the dependence of qtpe
3439
if (contains(qtpeString)) {

bindgen/TypeTranslator.cpp

Lines changed: 88 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#include "TypeTranslator.h"
22
#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"
37

4-
TypeTranslator::TypeTranslator(clang::ASTContext *ctx_) : ctx(ctx_), typeMap() {
8+
TypeTranslator::TypeTranslator(clang::ASTContext *ctx_, IR &ir)
9+
: ctx(ctx_), ir(ir), typeMap() {
510

611
// Native Types
712
typeMap["void"] = "Unit";
@@ -29,35 +34,22 @@ TypeTranslator::TypeTranslator(clang::ASTContext *ctx_) : ctx(ctx_), typeMap() {
2934
typeMap["double"] = "native.CDouble";
3035
}
3136

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>();
3740
const clang::QualType &inner = ptr->getPointeeType();
3841

3942
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;
4546

4647
for (const clang::QualType &param : fc->param_types()) {
47-
params += Translate(param, avoid);
48-
params += ", ";
49-
counter++;
48+
parametersTypes.push_back(translate(param, avoid));
5049
}
5150

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());
6153

6254
} else {
6355
llvm::errs() << "Unsupported function pointer type: "
@@ -67,107 +59,143 @@ TypeTranslator::TranslateFunctionPointer(const clang::QualType &qtpe,
6759
}
6860
}
6961

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) {
7264

7365
if (pte->isBuiltinType()) {
7466
const clang::BuiltinType *as = pte->getAs<clang::BuiltinType>();
7567

7668
// Take care of void*
7769
if (as->getKind() == clang::BuiltinType::Void) {
78-
return "native.Ptr[Byte]";
70+
return new PointerType(new SimpleType("Byte"));
7971
}
8072

8173
// Take care of char*
8274
if (as->getKind() == clang::BuiltinType::Char_S ||
8375
as->getKind() == clang::BuiltinType::SChar) {
84-
return "native.CString";
76+
return new SimpleType("native.CString");
8577
}
8678
}
8779

88-
return std::string("native.Ptr[") + Translate(pte, avoid) +
89-
std::string("]");
80+
return new PointerType(translate(pte, avoid));
9081
}
9182

92-
std::string
93-
TypeTranslator::TranslateStructOrUnion(const clang::QualType &qtpe) {
83+
Type *TypeTranslator::translateStruct(const clang::QualType &qtpe) {
9484
if (qtpe->hasUnnamedOrLocalType()) {
9585
// TODO: Verify that the local part is not a problem
9686
uint64_t size = ctx->getTypeSize(qtpe);
97-
return "native.CArray[Byte, " + uint64ToScalaNat(size) + "]";
87+
return new ArrayType(new SimpleType("Byte"), size);
9888
}
9989

10090
std::string name = qtpe.getUnqualifiedType().getAsString();
10191

10292
// TODO: do it properly
10393
size_t f = name.find(std::string("struct __dirstream"));
10494
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);
10696
}
10797

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;
111103
}
112-
return name;
104+
/* type has typedef alias */
105+
return ir.getTypeDefWithName(name);
113106
}
114107

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+
116115
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;
120122
}
121-
return name;
123+
/* type has typedef alias */
124+
return ir.getTypeDefWithName(name);
122125
}
123126

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) {
127142
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);
131144
}
132145

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) {
135148

136149
const clang::Type *tpe = qtpe.getTypePtr();
137150

138151
if (typeEquals(tpe, avoid)) {
139152
// 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
141154
uint64_t size = ctx->getTypeSize(tpe);
142-
return "native.CArray[Byte, " + uint64ToScalaNat(size) + "]";
155+
return new ArrayType(new SimpleType("Byte"), size);
143156
}
144157

145158
if (tpe->isFunctionPointerType()) {
146-
return TranslateFunctionPointer(qtpe, avoid);
159+
return translateFunctionPointer(qtpe, avoid);
147160

148161
} else if (tpe->isPointerType()) {
149162
return TranslatePointer(
150163
tpe->getAs<clang::PointerType>()->getPointeeType(), avoid);
151164

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);
154170

155171
} else if (qtpe->isEnumeralType()) {
156-
return TranslateEnum(qtpe);
172+
return translateEnum(qtpe);
157173

158174
} else if (qtpe->isConstantArrayType()) {
159-
return TranslateConstantArray(ctx->getAsConstantArrayType(qtpe), avoid);
175+
return translateConstantArray(ctx->getAsConstantArrayType(qtpe), avoid);
160176
} else if (qtpe->isArrayType()) {
161177
return TranslatePointer(ctx->getAsArrayType(qtpe)->getElementType(),
162178
avoid);
163179
} else {
164180

165181
auto found = typeMap.find(qtpe.getUnqualifiedType().getAsString());
166182
if (found != typeMap.end()) {
167-
return handleReservedWords(found->second);
183+
return new SimpleType(found->second);
168184
} else {
169-
// TODO: Properly handle non-default types
170-
return handleReservedWords(qtpe.getUnqualifiedType().getAsString());
185+
return ir.getTypeDefWithName(
186+
qtpe.getUnqualifiedType().getAsString());
171187
}
172188
}
173189
}
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+
}

bindgen/TypeTranslator.h

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
#pragma once
22

3+
#include "ir/IR.h"
4+
#include "ir/types/Type.h"
35
#include <clang/AST/AST.h>
46
#include <clang/AST/ASTContext.h>
57
#include <clang/Tooling/Tooling.h>
68

79
class TypeTranslator {
8-
private:
9-
clang::ASTContext *ctx;
10-
std::map<std::string, std::string> typeMap;
11-
1210
public:
13-
explicit TypeTranslator(clang::ASTContext *ctx);
11+
TypeTranslator(clang::ASTContext *ctx, IR &ir);
1412

1513
/**
1614
* @brief Translate the qualified type from c to a scala type
@@ -19,14 +17,31 @@ class TypeTranslator {
1917
* structs, unions, ...
2018
* @return the type translated
2119
*/
22-
std::string Translate(const clang::QualType &tpe,
23-
const std::string * = nullptr);
24-
std::string TranslateFunctionPointer(const clang::QualType &qtpe,
25-
const std::string *avoid);
26-
std::string TranslatePointer(const clang::QualType &pointee,
20+
Type *translate(const clang::QualType &tpe, const std::string * = nullptr);
21+
22+
void addAlias(std::string cName, Type *type);
23+
24+
std::string getTypeFromTypeMap(std::string cType);
25+
26+
private:
27+
clang::ASTContext *ctx;
28+
IR &ir;
29+
std::map<std::string, std::string> typeMap;
30+
31+
std::map<std::string, Type *> aliasesMap;
32+
33+
Type *translateEnum(const clang::QualType &qtpe);
34+
35+
Type *translateStruct(const clang::QualType &qtpe);
36+
37+
Type *translateUnion(const clang::QualType &qtpe);
38+
39+
Type *translateFunctionPointer(const clang::QualType &qtpe,
40+
const std::string *avoid);
41+
42+
Type *TranslatePointer(const clang::QualType &pointee,
43+
const std::string *avoid);
44+
45+
Type *translateConstantArray(const clang::ConstantArrayType *ar,
2746
const std::string *avoid);
28-
std::string TranslateStructOrUnion(const clang::QualType &qtpe);
29-
std::string TranslateEnum(const clang::QualType &qtpe);
30-
std::string TranslateConstantArray(const clang::ConstantArrayType *ar,
31-
const std::string *avoid);
3247
};

bindgen/Utils.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <clang/AST/AST.h>
55

6+
#include "ir/types/Type.h"
67
#include <algorithm>
78
#include <cctype>
89
#include <cinttypes>
@@ -94,15 +95,4 @@ static inline bool startsWith(const std::string &str,
9495
return str.substr(0, prefix.size()) == prefix;
9596
}
9697

97-
/**
98-
* @return true if checkedType uses type
99-
* example: checkedType = native.Ptr[struct_A], type = struct_A
100-
*/
101-
static inline bool typeUsesOtherType(const std::string &checkedType,
102-
const std::string &type) {
103-
// TODO: find better way to check it
104-
return checkedType == type || checkedType == "native.Ptr[" + type + "]" ||
105-
startsWith(checkedType, "native.CArray[" + type + ", ");
106-
}
107-
10898
#endif // UTILS_H

0 commit comments

Comments
 (0)