Skip to content

Commit 5f1958d

Browse files
committed
Create TypeDef with nullptr for types that are not yet defined
1 parent fb3c4de commit 5f1958d

20 files changed

+169
-35
lines changed

bindgen/TypeTranslator.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ TypeTranslator::TypeTranslator(clang::ASTContext *ctx_, IR &ir)
3030
typeMap["char32_t"] = "native.CChar32";
3131
typeMap["float"] = "native.CFloat";
3232
typeMap["double"] = "native.CDouble";
33+
typeMap["long double"] = "native.CDouble";
3334
}
3435

3536
std::shared_ptr<Type>
@@ -93,8 +94,16 @@ TypeTranslator::translateStructOrUnionOrEnum(const clang::QualType &qtpe) {
9394
* Use type alias instead struct type */
9495
return (*it).second;
9596
}
96-
/* type has typedef alias */
97-
return ir.getTypeDefWithName(name);
97+
std::shared_ptr<TypeDef> typeDef = ir.getTypeDefWithName(name);
98+
if (typeDef) {
99+
/* type has typedef alias */
100+
return typeDef;
101+
}
102+
/* type is not yet defined.
103+
* nullptr will be replaced by actual type */
104+
typeDef = ir.addTypeDef(replaceChar(name, " ", "_"), nullptr);
105+
addAlias(name, typeDef);
106+
return typeDef;
98107
}
99108

100109
std::shared_ptr<Type>
@@ -138,6 +147,10 @@ std::shared_ptr<Type> TypeTranslator::translate(const clang::QualType &qtpe,
138147
std::make_shared<PrimitiveType>("Byte"), sizeInBits / 8);
139148
}
140149

150+
if (tpe->isFunctionType()) {
151+
return nullptr;
152+
}
153+
141154
if (tpe->isFunctionPointerType()) {
142155
return translateFunctionPointer(qtpe, avoid);
143156

bindgen/TypeTranslator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class TypeTranslator {
1212
* @param tpe The type to translate
1313
* @param avoid A type to avoid, useful to avoid cyclic definitions inside
1414
* structs, unions, ...
15-
* @return the type translated
15+
* @return the type translated or nullptr if type is function type.
1616
*/
1717
std::shared_ptr<Type> translate(const clang::QualType &tpe,
1818
const std::string * = nullptr);

bindgen/Utils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,13 @@ template <typename T, typename PT> static inline bool isInstanceOf(PT *type) {
100100
return p != nullptr;
101101
}
102102

103+
static inline std::string replaceChar(std::string str, const std::string &c1,
104+
const std::string &c2) {
105+
auto f = str.find(c1);
106+
if (f != std::string::npos) {
107+
return str.replace(f, c1.length(), c2);
108+
}
109+
return str;
110+
}
111+
103112
#endif // UTILS_H

bindgen/ir/Function.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Parameter::Parameter(std::string name, std::shared_ptr<Type> type)
77
Function::Function(const std::string &name, std::vector<Parameter *> parameters,
88
std::shared_ptr<Type> retType, bool isVariadic)
99
: name(name), scalaName(name), parameters(std::move(parameters)),
10-
retType(retType), isVariadic(isVariadic) {}
10+
retType(std::move(retType)), isVariadic(isVariadic) {}
1111

1212
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Function &func) {
1313
if (func.scalaName != func.name) {

bindgen/ir/IR.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ void IR::addFunction(std::string name, std::vector<Parameter *> parameters,
1212
retType, isVariadic));
1313
}
1414

15-
void IR::addTypeDef(std::string name, std::shared_ptr<Type> type) {
15+
std::shared_ptr<TypeDef> IR::addTypeDef(std::string name,
16+
std::shared_ptr<Type> type) {
1617
typeDefs.push_back(std::make_shared<TypeDef>(std::move(name), type));
18+
return typeDefs.back();
1719
}
1820

1921
std::shared_ptr<Type> IR::addEnum(std::string name, const std::string &type,
@@ -38,6 +40,14 @@ std::shared_ptr<Type> IR::addStruct(std::string name,
3840
return typeDefs.back();
3941
}
4042

43+
void IR::addStruct(std::string name, std::vector<Field *> fields,
44+
uint64_t typeSize, const std::shared_ptr<TypeDef> &typeDef) {
45+
std::shared_ptr<Struct> s =
46+
std::make_shared<Struct>(std::move(name), std::move(fields), typeSize);
47+
structs.push_back(s);
48+
typeDef.get()->setType(s);
49+
}
50+
4151
std::shared_ptr<Type>
4252
IR::addUnion(std::string name, std::vector<Field *> fields, uint64_t maxSize) {
4353
std::shared_ptr<Union> u =
@@ -47,6 +57,14 @@ IR::addUnion(std::string name, std::vector<Field *> fields, uint64_t maxSize) {
4757
return typeDefs.back();
4858
}
4959

60+
void IR::addUnion(std::string name, std::vector<Field *> fields,
61+
uint64_t maxSize, const std::shared_ptr<TypeDef> &typeDef) {
62+
std::shared_ptr<Union> u =
63+
std::make_shared<Union>(std::move(name), std::move(fields), maxSize);
64+
unions.push_back(u);
65+
typeDef.get()->setType(u);
66+
}
67+
5068
void IR::addLiteralDefine(std::string name, std::string literal,
5169
std::shared_ptr<Type> type) {
5270
literalDefines.push_back(std::make_shared<LiteralDefine>(
@@ -317,7 +335,6 @@ T IR::getDeclarationWithName(std::vector<T> &declarations,
317335
return declaration;
318336
}
319337
}
320-
llvm::errs() << "Failed to get declaration for " << name << "\n";
321338
return nullptr;
322339
}
323340

@@ -331,4 +348,4 @@ IR::~IR() {
331348
possibleVarDefines.clear();
332349
variables.clear();
333350
varDefines.clear();
334-
}
351+
}

bindgen/ir/IR.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class IR {
2222
void addFunction(std::string name, std::vector<Parameter *> parameters,
2323
std::shared_ptr<Type> retType, bool isVariadic);
2424

25-
void addTypeDef(std::string name, std::shared_ptr<Type> type);
25+
std::shared_ptr<TypeDef> addTypeDef(std::string name,
26+
std::shared_ptr<Type> type);
2627

2728
/**
2829
* @return type alias for the enum
@@ -36,12 +37,24 @@ class IR {
3637
std::shared_ptr<Type>
3738
addStruct(std::string name, std::vector<Field *> fields, uint64_t typeSize);
3839

40+
/**
41+
* Add struct for which TypeDef already exists
42+
*/
43+
void addStruct(std::string name, std::vector<Field *> fields,
44+
uint64_t typeSize, const std::shared_ptr<TypeDef> &typeDef);
45+
3946
/**
4047
* @return type alias for the union
4148
*/
4249
std::shared_ptr<Type>
4350
addUnion(std::string name, std::vector<Field *> fields, uint64_t maxSize);
4451

52+
/**
53+
* Add union for which TypeDef already exists
54+
*/
55+
void addUnion(std::string name, std::vector<Field *> fields,
56+
uint64_t maxSize, const std::shared_ptr<TypeDef> &typeDef);
57+
4558
void addLiteralDefine(std::string name, std::string literal,
4659
std::shared_ptr<Type> type);
4760

@@ -138,8 +151,6 @@ class IR {
138151
T getDeclarationWithName(std::vector<T> &declarations,
139152
const std::string &name);
140153

141-
template <typename T> void clearVector(std::vector<T> v);
142-
143154
std::string libName; // name of the library
144155
std::string linkName; // name of the library to link with
145156
std::string objectName; // name of Scala object

bindgen/ir/Struct.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "types/ArrayType.h"
44
#include "types/PrimitiveType.h"
55
#include <sstream>
6-
#include <utility>
76

87
Field::Field(std::string name, std::shared_ptr<Type> type)
98
: TypeAndName(std::move(name), std::move(type)) {}

bindgen/ir/TypeAndName.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <clang/Tooling/Tooling.h>
33

44
TypeAndName::TypeAndName(std::string name, std::shared_ptr<Type> type)
5-
: name(std::move(name)), type(type) {}
5+
: name(std::move(name)), type(std::move(type)) {}
66

77
std::shared_ptr<Type> TypeAndName::getType() const { return type; }
88

bindgen/ir/TypeDef.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
#include "../Utils.h"
33

44
TypeDef::TypeDef(std::string name, std::shared_ptr<Type> type)
5-
: TypeAndName(std::move(name), type) {}
5+
: TypeAndName(std::move(name), std::move(type)) {}
66

77
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const TypeDef &typeDef) {
8+
if (!typeDef.getType()) {
9+
llvm::errs() << "Error: type declaration for " << typeDef.getName()
10+
<< " was not found.\n";
11+
llvm::errs().flush();
12+
return s;
13+
}
814
s << " type " + handleReservedWords(typeDef.name) + " = " +
915
typeDef.getType()->str() + "\n";
1016
return s;

bindgen/ir/types/ArrayType.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "../../Utils.h"
33

44
ArrayType::ArrayType(std::shared_ptr<Type> elementsType, uint64_t size)
5-
: size(size), elementsType(elementsType) {}
5+
: size(size), elementsType(std::move(elementsType)) {}
66

77
std::string ArrayType::str() const {
88
return "native.CArray[" + elementsType->str() + ", " +
@@ -12,5 +12,3 @@ std::string ArrayType::str() const {
1212
bool ArrayType::usesType(std::shared_ptr<Type> type) const {
1313
return this == type.get() || elementsType == type;
1414
}
15-
16-
ArrayType::~ArrayType() {}

bindgen/ir/types/ArrayType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class ArrayType : public Type {
77
public:
88
ArrayType(std::shared_ptr<Type> elementsType, uint64_t size);
99

10-
~ArrayType() override;
10+
~ArrayType() override = default;
1111

1212
bool usesType(std::shared_ptr<Type> type) const override;
1313

bindgen/ir/types/FunctionPointerType.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
FunctionPointerType::FunctionPointerType(
55
std::shared_ptr<Type> returnType,
66
const std::vector<std::shared_ptr<Type>> &parametersTypes, bool isVariadic)
7-
: returnType(returnType), parametersTypes(parametersTypes),
7+
: returnType(std::move(returnType)), parametersTypes(parametersTypes),
88
isVariadic(isVariadic) {}
99

1010
std::string FunctionPointerType::str() const {
@@ -30,12 +30,10 @@ bool FunctionPointerType::usesType(std::shared_ptr<Type> type) const {
3030
return true;
3131
}
3232

33-
for (auto parameterType : parametersTypes) {
33+
for (const auto &parameterType : parametersTypes) {
3434
if (parameterType == type) {
3535
return true;
3636
}
3737
}
3838
return false;
3939
}
40-
41-
FunctionPointerType::~FunctionPointerType() {}

bindgen/ir/types/FunctionPointerType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class FunctionPointerType : public Type {
1111
const std::vector<std::shared_ptr<Type>> &parametersTypes,
1212
bool isVariadic);
1313

14-
~FunctionPointerType() override;
14+
~FunctionPointerType() override = default;
1515

1616
bool usesType(std::shared_ptr<Type> type) const override;
1717

bindgen/ir/types/PointerType.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "PointerType.h"
22

3-
PointerType::PointerType(std::shared_ptr<Type> type) : type(type) {}
3+
PointerType::PointerType(std::shared_ptr<Type> type) : type(std::move(type)) {}
44

55
std::string PointerType::str() const {
66
return "native.Ptr[" + type->str() + "]";
@@ -12,5 +12,3 @@ bool PointerType::usesType(std::shared_ptr<Type> type) const {
1212
}
1313
return this->type == type;
1414
}
15-
16-
PointerType::~PointerType() {}

bindgen/ir/types/PointerType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class PointerType : public Type {
77
public:
88
explicit PointerType(std::shared_ptr<Type> type);
99

10-
~PointerType() override;
10+
~PointerType() override = default;
1111

1212
bool usesType(std::shared_ptr<Type> type) const override;
1313

bindgen/ir/types/Type.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@
33
std::string Type::str() const { return ""; }
44

55
bool Type::usesType(std::shared_ptr<Type> type) const { return false; }
6-
7-
Type::~Type() = default;

bindgen/ir/types/Type.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
class Type {
1111
public:
12-
virtual ~Type();
12+
virtual ~Type() = default;
1313

1414
virtual std::string str() const;
1515

bindgen/visitor/TreeVisitor.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ bool TreeVisitor::VisitTypedefDecl(clang::TypedefDecl *tpdef) {
4646

4747
std::shared_ptr<Type> type =
4848
typeTranslator.translate(tpdef->getUnderlyingType());
49-
ir.addTypeDef(name, type);
49+
if (type) {
50+
ir.addTypeDef(name, type);
51+
}
5052
return true;
5153
}
5254

@@ -86,8 +88,8 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record) {
8688
name = record->getTypedefNameForAnonDecl()->getNameAsString();
8789
}
8890

89-
if (record->isUnion() && !record->isAnonymousStructOrUnion() &&
90-
!name.empty()) {
91+
if (record->isUnion() && record->isThisDeclarationADefinition() &&
92+
!record->isAnonymousStructOrUnion() && !name.empty()) {
9193
handleUnion(record, name);
9294
return true;
9395

@@ -115,7 +117,16 @@ void TreeVisitor::handleUnion(clang::RecordDecl *record, std::string name) {
115117
fields.push_back(new Field(fname, ftype));
116118
}
117119

118-
std::shared_ptr<Type> alias = ir.addUnion(name, std::move(fields), maxSize);
120+
std::shared_ptr<Type> alias = nullptr;
121+
122+
std::shared_ptr<TypeDef> typeDef = ir.getTypeDefWithName("union_" + name);
123+
if (typeDef) {
124+
/* typedef for this union already exists */
125+
ir.addUnion(name, std::move(fields), maxSize, typeDef);
126+
alias = typeDef;
127+
} else {
128+
alias = ir.addUnion(name, std::move(fields), maxSize);
129+
}
119130

120131
typeTranslator.addAlias("union " + name, alias);
121132
}
@@ -155,8 +166,16 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) {
155166

156167
uint64_t sizeInBits = astContext->getTypeSize(record->getTypeForDecl());
157168
assert(sizeInBits % 8 == 0);
158-
std::shared_ptr<Type> alias =
159-
ir.addStruct(name, std::move(fields), sizeInBits / 8);
169+
std::shared_ptr<Type> alias = nullptr;
170+
171+
std::shared_ptr<TypeDef> typeDef = ir.getTypeDefWithName(newName);
172+
if (typeDef) {
173+
/* typedef for this struct already exists */
174+
alias = typeDef;
175+
ir.addStruct(name, std::move(fields), sizeInBits / 8, typeDef);
176+
} else {
177+
alias = ir.addStruct(name, std::move(fields), sizeInBits / 8);
178+
}
160179

161180
typeTranslator.addAlias("struct " + name, alias);
162181
}

tests/samples/OpaqueTypes.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
struct point;
2+
struct point *move(struct point *point, int x, int y);
3+
4+
typedef struct points points;
5+
typedef union u u;
6+
7+
union u *processPoints(points *p);
8+
9+
union u {
10+
int i;
11+
float f;
12+
};
13+
14+
struct points {
15+
struct point *point1;
16+
struct point *point2;
17+
};
18+
19+
struct point {
20+
int x;
21+
int y;
22+
};

0 commit comments

Comments
 (0)