Skip to content

Commit 3a792b8

Browse files
committed
Replace opaque type with CStruct0
1 parent 355a0a8 commit 3a792b8

26 files changed

+124
-277
lines changed

bindgen/ir/Function.cpp

+4-26
Original file line numberDiff line numberDiff line change
@@ -75,39 +75,17 @@ bool Function::isLegalScalaNativeFunction() const {
7575
* in this case is always represented as a pointer to element type */
7676
auto *typeDef = dynamic_cast<TypeDef *>(retType.get());
7777
if (typeDef &&
78-
(typeDef->isAliasFor<Struct>() || typeDef->isAliasFor<ArrayType>())) {
78+
(typeDef->isAliasFor<Struct>() || typeDef->isAliasFor<ArrayType>() ||
79+
typeDef->isAliasForOpaqueType())) {
7980
return false;
8081
}
8182
for (const auto &parameter : parameters) {
8283
typeDef = dynamic_cast<TypeDef *>(parameter->getType().get());
8384
if (typeDef && (typeDef->isAliasFor<Struct>() ||
84-
typeDef->isAliasFor<ArrayType>())) {
85+
typeDef->isAliasFor<ArrayType>() ||
86+
typeDef->isAliasForOpaqueType())) {
8587
return false;
8688
}
8789
}
8890
return true;
8991
}
90-
91-
void Function::replaceType(const std::shared_ptr<Type> &type,
92-
const std::shared_ptr<Type> &replacement) {
93-
if (*retType == *type) {
94-
retType = replacement;
95-
} else {
96-
retType->replaceType(type, replacement);
97-
}
98-
for (const auto &parameter : parameters) {
99-
parameter->replaceType(type, replacement);
100-
}
101-
}
102-
103-
bool Function::usesOpaqueType() const {
104-
if (retType->usesOpaqueType()) {
105-
return true;
106-
}
107-
for (const auto &parameter : parameters) {
108-
if (parameter->usesOpaqueType()) {
109-
return true;
110-
}
111-
}
112-
return false;
113-
}

bindgen/ir/Function.h

-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ class Function {
3333
*/
3434
bool isLegalScalaNativeFunction() const;
3535

36-
void replaceType(const std::shared_ptr<Type> &type,
37-
const std::shared_ptr<Type> &replacement);
38-
39-
bool usesOpaqueType() const;
40-
4136
private:
4237
std::string getVarargsParameterName() const;
4338

bindgen/ir/IR.cpp

+26-48
Original file line numberDiff line numberDiff line change
@@ -111,51 +111,50 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
111111

112112
for (const auto &typeDef : ir.typeDefs) {
113113
if (ir.shouldOutput(typeDef)) {
114-
if (!typeDef->usesOpaqueType()) {
115-
s << *typeDef;
116-
} else if (!typeDef->getType()) {
117-
llvm::errs() << "Error: type definition for "
118-
<< typeDef->getName() << " was not found.\n";
119-
llvm::errs().flush();
120-
} else {
121-
llvm::errs() << "Error: Typedef " << typeDef->getName()
122-
<< " is skipped because it references an "
123-
"opaque type.\n";
124-
llvm::errs().flush();
114+
s << *typeDef;
115+
if (typeDef->getType()) {
116+
auto *structOrUnion =
117+
dynamic_cast<StructOrUnion *>(typeDef->getType().get());
118+
if (structOrUnion &&
119+
structOrUnion->hasIllegalUsageOfOpaqueType()) {
120+
llvm::errs()
121+
<< "Error: record " << structOrUnion->getName()
122+
<< " has field of incomplete type. Declarations "
123+
"that use this type may not work properly.\n";
124+
llvm::errs().flush();
125+
}
125126
}
126127
}
127128
}
128129

129130
for (const auto &variable : ir.variables) {
130-
if (!variable->usesOpaqueType()) {
131+
if (!variable->hasIllegalUsageOfOpaqueType()) {
131132
s << *variable;
132133
} else {
133-
llvm::errs()
134-
<< "Error: Variable " << variable->getName()
135-
<< " is skipped because it references an opaque type.\n";
134+
llvm::errs() << "Error: Variable " << variable->getName()
135+
<< " is skipped because it has incomplete type.\n";
136136
}
137137
}
138138

139139
for (const auto &varDefine : ir.varDefines) {
140-
if (!varDefine->usesOpaqueType()) {
140+
if (!varDefine->hasIllegalUsageOfOpaqueType()) {
141141
s << *varDefine;
142142
} else {
143-
llvm::errs() << "Error: Typedef " << varDefine->getName()
144-
<< " is skipped because it references an "
145-
"opaque type.\n";
143+
llvm::errs() << "Error: Variable alias " << varDefine->getName()
144+
<< " is skipped because it has incomplete type\n";
146145
llvm::errs().flush();
147146
}
148147
}
149148

150149
for (const auto &func : ir.functions) {
151-
if (func->isLegalScalaNativeFunction()) {
152-
s << *func;
153-
} else {
150+
if (!func->isLegalScalaNativeFunction()) {
154151
llvm::errs()
155152
<< "Warning: Function " << func->getName()
156153
<< " is skipped because Scala Native does not support "
157154
"passing structs and arrays by value.\n";
158155
llvm::errs().flush();
156+
} else {
157+
s << *func;
159158
}
160159
}
161160

@@ -193,13 +192,13 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
193192

194193
for (const auto &st : ir.structs) {
195194
if (ir.shouldOutput(st) && st->hasHelperMethods() &&
196-
!st->usesOpaqueType()) {
195+
!st->hasIllegalUsageOfOpaqueType()) {
197196
s << "\n" << st->generateHelperClass();
198197
}
199198
}
200199

201200
for (const auto &u : ir.unions) {
202-
if (ir.shouldOutput(u) && !u->usesOpaqueType()) {
201+
if (ir.shouldOutput(u) && !u->hasIllegalUsageOfOpaqueType()) {
203202
s << "\n" << u->generateHelperClass();
204203
}
205204
}
@@ -480,38 +479,17 @@ bool IR::shouldOutput(const std::shared_ptr<T> &type) const {
480479
if (typeDef) {
481480
/* unused typedefs from main file are not printed if they are aliases
482481
* for opaque types */
483-
return !typeDef->referencesOpaqueType() && inMainFile(*typeDef);
482+
return !typeDef->isAliasForOpaqueType() && inMainFile(*typeDef);
484483
}
485484
return inMainFile(*type);
486485
}
487486

488487
void IR::fixPointersToOpaqueTypes() {
489-
std::shared_ptr<Type> pointerToByte =
490-
std::make_shared<PointerType>(std::make_shared<PrimitiveType>("Byte"));
491488
for (const auto &typeDef : typeDefs) {
492489
if (shouldOutput(typeDef)) {
493-
if (typeDef->referencesOpaqueType()) {
494-
std::shared_ptr<Type> pointerToStruct =
495-
std::make_shared<PointerType>(typeDef);
496-
replaceType(pointerToStruct, pointerToByte);
490+
if (typeDef->isAliasForOpaqueType()) {
491+
// TODO: ?
497492
}
498493
}
499494
}
500495
}
501-
502-
void IR::replaceType(std::shared_ptr<Type> type,
503-
std::shared_ptr<Type> replacement) {
504-
replaceType(functions, type, replacement);
505-
replaceType(typeDefs, type, replacement);
506-
replaceType(structs, type, replacement);
507-
replaceType(unions, type, replacement);
508-
}
509-
510-
template <typename T>
511-
void IR::replaceType(std::vector<std::shared_ptr<T>> declarations,
512-
std::shared_ptr<Type> type,
513-
std::shared_ptr<Type> replacement) {
514-
for (const auto &declaration : declarations) {
515-
declaration->replaceType(type, replacement);
516-
}
517-
}

bindgen/ir/IR.h

-14
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,6 @@ class IR {
171171
*/
172172
void fixPointersToOpaqueTypes();
173173

174-
/**
175-
* Replace given type with the replacement in all declarations.
176-
*/
177-
void replaceType(std::shared_ptr<Type> type,
178-
std::shared_ptr<Type> replacement);
179-
180-
/**
181-
* Replace given type with the replacement in given declarations.
182-
*/
183-
template <typename T>
184-
void replaceType(std::vector<std::shared_ptr<T>> declarations,
185-
std::shared_ptr<Type> type,
186-
std::shared_ptr<Type> replacement);
187-
188174
std::string libName; // name of the library
189175
std::string linkName; // name of the library to link with
190176
std::string objectName; // name of Scala object

bindgen/ir/Struct.cpp

+6-21
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,14 @@ std::shared_ptr<Location> StructOrUnion::getLocation() const {
7777
return location;
7878
}
7979

80-
void StructOrUnion::replaceType(const std::shared_ptr<Type> &type,
81-
const std::shared_ptr<Type> &replacement) {
80+
bool StructOrUnion::hasIllegalUsageOfOpaqueType() const {
8281
for (const auto &field : fields) {
83-
field->replaceType(type, replacement);
82+
auto *typeDef = dynamic_cast<TypeDef *>(field->getType().get());
83+
if (typeDef && typeDef->isAliasForOpaqueType()) {
84+
return true;
85+
}
8486
}
87+
return false;
8588
}
8689

8790
Struct::Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize,
@@ -170,15 +173,6 @@ bool Struct::operator==(const Type &other) const {
170173
return false;
171174
}
172175

173-
bool Struct::usesOpaqueType() const {
174-
for (const auto &field : fields) {
175-
if (field->usesOpaqueType()) {
176-
return true;
177-
}
178-
}
179-
return false;
180-
}
181-
182176
Union::Union(std::string name, std::vector<Field *> fields, uint64_t maxSize,
183177
std::shared_ptr<Location> location)
184178
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
@@ -220,12 +214,3 @@ bool Union::operator==(const Type &other) const {
220214
}
221215
return false;
222216
}
223-
224-
bool Union::usesOpaqueType() const {
225-
for (const auto &field : fields) {
226-
if (field->usesOpaqueType()) {
227-
return true;
228-
}
229-
}
230-
return ArrayType::usesOpaqueType();
231-
}

bindgen/ir/Struct.h

+5-10
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ class StructOrUnion {
3737

3838
virtual std::string getTypeAlias() const = 0;
3939

40-
void replaceType(const std::shared_ptr<Type> &type,
41-
const std::shared_ptr<Type> &replacement);
40+
/**
41+
* @return true if the record contains field of opaque type or an array
42+
* of elements of opaque type.
43+
*/
44+
bool hasIllegalUsageOfOpaqueType() const;
4245

4346
protected:
4447
std::string name;
@@ -71,10 +74,6 @@ class Struct : public StructOrUnion,
7174

7275
bool operator==(const Type &other) const override;
7376

74-
bool usesOpaqueType() const override;
75-
76-
using StructOrUnion::replaceType;
77-
7877
private:
7978
/* type size is needed if number of fields is bigger than 22 */
8079
uint64_t typeSize;
@@ -94,10 +93,6 @@ class Union : public StructOrUnion,
9493
bool operator==(const Type &other) const override;
9594

9695
std::string getTypeAlias() const override;
97-
98-
bool usesOpaqueType() const override;
99-
100-
using StructOrUnion::replaceType;
10196
};
10297

10398
#endif // SCALA_NATIVE_BINDGEN_STRUCT_H

bindgen/ir/TypeAndName.cpp

-19
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,3 @@ bool TypeAndName::usesType(const std::shared_ptr<Type> &type,
2626
return *this->type == *type ||
2727
this->type.get()->usesType(type, stopOnTypeDefs);
2828
}
29-
30-
void TypeAndName::replaceType(const std::shared_ptr<Type> &type,
31-
const std::shared_ptr<Type> &replacement) {
32-
if (!this->type) {
33-
return;
34-
}
35-
if (*this->type == *type) {
36-
this->type = replacement;
37-
} else {
38-
this->type->replaceType(type, replacement);
39-
}
40-
}
41-
42-
bool TypeAndName::usesOpaqueType() const {
43-
if (!type) {
44-
return true;
45-
}
46-
return type->usesOpaqueType();
47-
}

bindgen/ir/TypeAndName.h

-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ class TypeAndName {
2525

2626
bool usesType(const std::shared_ptr<Type> &type, bool stopOnTypeDefs) const;
2727

28-
void replaceType(const std::shared_ptr<Type> &type,
29-
const std::shared_ptr<Type> &replacement);
30-
31-
bool usesOpaqueType() const;
32-
3328
protected:
3429
std::string name;
3530
std::shared_ptr<Type> type;

bindgen/ir/TypeDef.cpp

+9-11
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ TypeDef::TypeDef(std::string name, std::shared_ptr<Type> type,
99
location(std::move(location)) {}
1010

1111
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const TypeDef &typeDef) {
12-
s << " type " + handleReservedWords(typeDef.name) + " = " +
13-
typeDef.getType()->str() + "\n";
12+
s << " type " << handleReservedWords(typeDef.name) << " = ";
13+
if (typeDef.type) {
14+
s << typeDef.getType()->str();
15+
} else {
16+
s << "native.CStruct0";
17+
}
18+
s << "\n";
1419
return s;
1520
}
1621

@@ -43,20 +48,13 @@ bool TypeDef::operator==(const Type &other) const {
4348

4449
std::shared_ptr<Location> TypeDef::getLocation() const { return location; }
4550

46-
bool TypeDef::referencesOpaqueType() const {
51+
bool TypeDef::isAliasForOpaqueType() const {
4752
if (!type) {
4853
return true;
4954
}
5055
auto *typeDef = dynamic_cast<const TypeDef *>(type.get());
5156
if (typeDef) {
52-
return typeDef->referencesOpaqueType();
57+
return typeDef->isAliasForOpaqueType();
5358
}
5459
return false;
5560
}
56-
57-
bool TypeDef::usesOpaqueType() const {
58-
if (!type) {
59-
return true;
60-
}
61-
return type->usesOpaqueType();
62-
}

bindgen/ir/TypeDef.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ class TypeDef : public TypeAndName, public Type {
4747
* @return true if typedef references opaque type directly or through a
4848
* chain of typedefs.
4949
*/
50-
bool referencesOpaqueType() const;
51-
52-
bool usesOpaqueType() const override;
53-
54-
using TypeAndName::replaceType;
50+
bool isAliasForOpaqueType() const;
5551

5652
private:
5753
/**

bindgen/ir/VarDefine.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
1111
return s;
1212
}
1313

14-
bool VarDefine::usesOpaqueType() const { return variable->usesOpaqueType(); }
14+
bool VarDefine::hasIllegalUsageOfOpaqueType() const {
15+
return variable->hasIllegalUsageOfOpaqueType();
16+
}

bindgen/ir/VarDefine.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class VarDefine : public Define {
1414
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
1515
const VarDefine &varDefine);
1616

17-
bool usesOpaqueType() const;
17+
bool hasIllegalUsageOfOpaqueType() const;
1818

1919
private:
2020
std::shared_ptr<Variable> variable;

0 commit comments

Comments
 (0)