Skip to content

Commit bce760d

Browse files
committed
Add location to Struct, Union and Enum
1 parent 331dabe commit bce760d

File tree

9 files changed

+111
-72
lines changed

9 files changed

+111
-72
lines changed

bindgen/ir/Enum.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@ std::string Enumerator::getName() { return name; }
88
int64_t Enumerator::getValue() { return value; }
99

1010
Enum::Enum(std::string name, std::string type,
11-
std::vector<Enumerator> enumerators)
11+
std::vector<Enumerator> enumerators,
12+
std::shared_ptr<Location> location)
1213
: PrimitiveType(std::move(type)), name(std::move(name)),
13-
enumerators(std::move(enumerators)) {}
14+
enumerators(std::move(enumerators)), location(std::move(location)) {}
1415

1516
bool Enum::isAnonymous() const { return name.empty(); }
1617

17-
std::shared_ptr<TypeDef>
18-
Enum::generateTypeDef(std::shared_ptr<Location> location) {
19-
assert(!isAnonymous());
20-
return std::make_shared<TypeDef>("enum_" + name, shared_from_this(),
21-
std::move(location));
18+
std::shared_ptr<TypeDef> Enum::generateTypeDef() {
19+
return std::make_shared<TypeDef>(getTypeAlias(), shared_from_this(),
20+
nullptr);
2221
}
2322

2423
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e) {
@@ -51,3 +50,10 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e) {
5150
}
5251

5352
std::string Enum::getName() const { return name; }
53+
54+
std::string Enum::getTypeAlias() const {
55+
assert(!isAnonymous());
56+
return "enum_" + name;
57+
}
58+
59+
std::shared_ptr<Location> Enum::getLocation() { return location; }

bindgen/ir/Enum.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,28 @@ class Enumerator {
2121
class Enum : public PrimitiveType, public std::enable_shared_from_this<Enum> {
2222
public:
2323
Enum(std::string name, std::string type,
24-
std::vector<Enumerator> enumerators);
24+
std::vector<Enumerator> enumerators,
25+
std::shared_ptr<Location> location);
2526

2627
bool isAnonymous() const;
2728

28-
std::shared_ptr<TypeDef>
29-
generateTypeDef(std::shared_ptr<Location> location);
29+
std::shared_ptr<TypeDef> generateTypeDef();
3030

3131
std::string getName() const;
3232

3333
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e);
3434

35+
std::string getTypeAlias() const;
36+
37+
std::shared_ptr<Location> getLocation();
38+
3539
private:
3640
std::string name; // might be empty
3741
std::vector<Enumerator> enumerators;
42+
/**
43+
* nullptr if type is generated.
44+
*/
45+
std::shared_ptr<Location> location;
3846
};
3947

4048
#endif // SCALA_NATIVE_BINDGEN_ENUM_H

bindgen/ir/IR.cpp

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,39 @@ std::shared_ptr<TypeDef> IR::addTypeDef(std::string name,
2424
void IR::addEnum(std::string name, const std::string &type,
2525
std::vector<Enumerator> enumerators,
2626
std::shared_ptr<Location> location) {
27-
std::shared_ptr<Enum> e =
28-
std::make_shared<Enum>(std::move(name), type, std::move(enumerators));
27+
std::shared_ptr<Enum> e = std::make_shared<Enum>(
28+
std::move(name), type, std::move(enumerators), std::move(location));
2929
enums.push_back(e);
3030
if (!e->isAnonymous()) {
31-
typeDefs.push_back(e->generateTypeDef(std::move(location)));
31+
typeDefs.push_back(e->generateTypeDef());
3232
}
3333
}
3434

3535
void IR::addStruct(std::string name, std::vector<Field *> fields,
3636
uint64_t typeSize, std::shared_ptr<Location> location) {
37-
std::shared_ptr<Struct> s =
38-
std::make_shared<Struct>(name, std::move(fields), typeSize);
37+
std::shared_ptr<Struct> s = std::make_shared<Struct>(
38+
name, std::move(fields), typeSize, std::move(location));
3939
structs.push_back(s);
4040
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("struct_" + name);
4141
if (typeDef) {
4242
/* the struct type used to be opaque type, typeDef contains nullptr */
4343
typeDef.get()->setType(s);
44-
typeDef.get()->setLocation(location);
4544
} else {
46-
typeDefs.push_back(s->generateTypeDef(std::move(location)));
45+
typeDefs.push_back(s->generateTypeDef());
4746
}
4847
}
4948

5049
void IR::addUnion(std::string name, std::vector<Field *> fields,
5150
uint64_t maxSize, std::shared_ptr<Location> location) {
52-
std::shared_ptr<Union> u =
53-
std::make_shared<Union>(name, std::move(fields), maxSize);
51+
std::shared_ptr<Union> u = std::make_shared<Union>(
52+
name, std::move(fields), maxSize, std::move(location));
5453
unions.push_back(u);
5554
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("union_" + name);
5655
if (typeDef) {
5756
/* the union type used to be opaque type, typeDef contains nullptr */
5857
typeDef.get()->setType(u);
59-
typeDef.get()->setLocation(location);
6058
} else {
61-
typeDefs.push_back(u->generateTypeDef(std::move(location)));
59+
typeDefs.push_back(u->generateTypeDef());
6260
}
6361
}
6462

@@ -175,7 +173,7 @@ void IR::generate(const std::string &excludePrefix) {
175173
if (!generated) {
176174
setScalaNames();
177175
filterDeclarations(excludePrefix);
178-
removeUnusedExternalTypes();
176+
removeUnusedExternalTypedefs();
179177
generated = true;
180178
}
181179
}
@@ -364,14 +362,13 @@ IR::~IR() {
364362
varDefines.clear();
365363
}
366364

367-
void IR::removeUnusedExternalTypes() {
365+
void IR::removeUnusedExternalTypedefs() {
368366
for (auto it = typeDefs.begin(); it != typeDefs.end();) {
369367
std::shared_ptr<TypeDef> typeDef = *it;
370368
std::shared_ptr<Location> location = typeDef->getLocation();
371369
auto *sourceLocation = dynamic_cast<SourceLocation *>(location.get());
372370
if (sourceLocation && !sourceLocation->isMainFile()) {
373371
if (!isTypeUsed(typeDef)) {
374-
removeStructOrUnionOrEnum(typeDef->getType());
375372
it = typeDefs.erase(it);
376373
} else {
377374
++it;
@@ -380,6 +377,9 @@ void IR::removeUnusedExternalTypes() {
380377
++it;
381378
}
382379
}
380+
removeUnusedExternalTypeAndTypedef(structs);
381+
removeUnusedExternalTypeAndTypedef(unions);
382+
removeUnusedExternalTypeAndTypedef(enums);
383383
}
384384

385385
template <typename T>
@@ -395,15 +395,22 @@ void IR::removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
395395
}
396396
}
397397

398-
void IR::removeStructOrUnionOrEnum(std::shared_ptr<Type> type) {
399-
if (isInstanceOf<Struct>(type.get())) {
400-
auto *s = dynamic_cast<Struct *>(type.get());
401-
removeDeclaration(structs, s);
402-
} else if (isInstanceOf<Union>(type.get())) {
403-
auto *u = dynamic_cast<Union *>(type.get());
404-
removeDeclaration(unions, u);
405-
} else if (isInstanceOf<Enum>(type.get())) {
406-
auto *e = dynamic_cast<Enum *>(type.get());
407-
removeDeclaration(enums, e);
398+
template <typename T>
399+
void IR::removeUnusedExternalTypeAndTypedef(
400+
std::vector<std::shared_ptr<T>> &types) {
401+
for (auto it = types.begin(); it != types.end();) {
402+
std::shared_ptr<T> t = *it;
403+
auto *sourceLocation =
404+
dynamic_cast<SourceLocation *>(t->getLocation().get());
405+
if (sourceLocation && !sourceLocation->isMainFile()) {
406+
std::shared_ptr<TypeDef> typeDef =
407+
getTypeDefWithName(t->getTypeAlias());
408+
if (!isTypeUsed(typeDef)) {
409+
it = types.erase(it);
410+
removeDeclaration(typeDefs, typeDef.get());
411+
} else {
412+
++it;
413+
}
414+
}
408415
}
409416
}

bindgen/ir/IR.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,21 @@ class IR {
140140
T getDeclarationWithName(std::vector<T> &declarations,
141141
const std::string &name);
142142

143-
void removeUnusedExternalTypes();
143+
void removeUnusedExternalTypedefs();
144144

145145
template <typename T>
146146
void removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
147147
T *declaration);
148148

149149
/**
150-
* remove declaration from IR if type is struct, union or enum
150+
* Go through types, find corresponding typedef, if the typedef is not used
151+
* then the type and the typedef are removed
152+
*
153+
* @tparam T Struct, Union or Enum
151154
*/
152-
void removeStructOrUnionOrEnum(std::shared_ptr<Type> type);
155+
template <typename T>
156+
void
157+
removeUnusedExternalTypeAndTypedef(std::vector<std::shared_ptr<T>> &types);
153158

154159
std::string libName; // name of the library
155160
std::string linkName; // name of the library to link with

bindgen/ir/Struct.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ std::string Field::generateGetter(int fieldIndex) {
3838
return s.str();
3939
}
4040

41-
StructOrUnion::StructOrUnion(std::string name, std::vector<Field *> fields)
42-
: name(std::move(name)), fields(std::move(fields)) {}
41+
StructOrUnion::StructOrUnion(std::string name, std::vector<Field *> fields,
42+
std::shared_ptr<Location> location)
43+
: name(std::move(name)), fields(std::move(fields)),
44+
location(std::move(location)) {}
4345

4446
std::string StructOrUnion::getName() const { return name; }
4547

@@ -71,20 +73,23 @@ bool StructOrUnion::operator==(const StructOrUnion &other) const {
7173
return false;
7274
}
7375

74-
Struct::Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize)
75-
: StructOrUnion(std::move(name), std::move(fields)), typeSize(typeSize) {}
76+
std::shared_ptr<Location> StructOrUnion::getLocation() { return location; }
7677

77-
std::shared_ptr<TypeDef>
78-
Struct::generateTypeDef(std::shared_ptr<Location> location) {
78+
Struct::Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize,
79+
std::shared_ptr<Location> location)
80+
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
81+
typeSize(typeSize) {}
82+
83+
std::shared_ptr<TypeDef> Struct::generateTypeDef() {
7984
if (fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS) {
80-
return std::make_shared<TypeDef>(getAliasType(), shared_from_this(),
81-
std::move(location));
85+
return std::make_shared<TypeDef>(getTypeAlias(), shared_from_this(),
86+
nullptr);
8287
} else {
8388
// There is no easy way to represent it as a struct in scala native,
8489
// have to represent it as an array and then Add helpers to help with
8590
// its manipulation
8691
return std::make_shared<TypeDef>(
87-
getAliasType(),
92+
getTypeAlias(),
8893
std::make_shared<ArrayType>(std::make_shared<PrimitiveType>("Byte"),
8994
typeSize),
9095
std::move(location));
@@ -95,7 +100,7 @@ std::string Struct::generateHelperClass() const {
95100
assert(hasHelperMethods());
96101
/* struct is not empty and not represented as an array */
97102
std::stringstream s;
98-
std::string type = getAliasType();
103+
std::string type = getTypeAlias();
99104
s << " implicit class " << type << "_ops(val p: native.Ptr[" << type
100105
<< "])"
101106
<< " extends AnyVal {\n";
@@ -121,7 +126,7 @@ bool Struct::hasHelperMethods() const {
121126
return !fields.empty() && fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS;
122127
}
123128

124-
std::string Struct::getAliasType() const { return "struct_" + name; }
129+
std::string Struct::getTypeAlias() const { return "struct_" + name; }
125130

126131
std::string Struct::str() const {
127132
std::stringstream ss;
@@ -148,14 +153,14 @@ bool Struct::usesType(const std::shared_ptr<Type> &type,
148153
return false;
149154
}
150155

151-
Union::Union(std::string name, std::vector<Field *> fields, uint64_t maxSize)
152-
: StructOrUnion(std::move(name), std::move(fields)),
156+
Union::Union(std::string name, std::vector<Field *> fields, uint64_t maxSize,
157+
std::shared_ptr<Location> location)
158+
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
153159
ArrayType(std::make_shared<PrimitiveType>("Byte"), maxSize) {}
154160

155-
std::shared_ptr<TypeDef>
156-
Union::generateTypeDef(std::shared_ptr<Location> location) {
161+
std::shared_ptr<TypeDef> Union::generateTypeDef() {
157162
return std::make_shared<TypeDef>(getTypeAlias(), shared_from_this(),
158-
std::move(location));
163+
nullptr);
159164
}
160165

161166
std::string Union::generateHelperClass() const {

bindgen/ir/Struct.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,42 @@ class Field : public TypeAndName {
2020

2121
class StructOrUnion {
2222
public:
23-
StructOrUnion(std::string name, std::vector<Field *> fields);
23+
StructOrUnion(std::string name, std::vector<Field *> fields,
24+
std::shared_ptr<Location> location);
2425

2526
~StructOrUnion();
2627

27-
virtual std::shared_ptr<TypeDef>
28-
generateTypeDef(std::shared_ptr<Location> location) = 0;
28+
virtual std::shared_ptr<TypeDef> generateTypeDef() = 0;
2929

3030
virtual std::string generateHelperClass() const = 0;
3131

3232
std::string getName() const;
3333

3434
bool operator==(const StructOrUnion &other) const;
3535

36+
std::shared_ptr<Location> getLocation();
37+
3638
protected:
3739
std::string name;
3840
std::vector<Field *> fields;
41+
/**
42+
* nullptr if type is generated.
43+
*/
44+
std::shared_ptr<Location> location;
3945
};
4046

4147
class Struct : public StructOrUnion,
4248
public Type,
4349
public std::enable_shared_from_this<Struct> {
4450
public:
45-
Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize);
51+
Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize,
52+
std::shared_ptr<Location> location);
4653

47-
std::shared_ptr<TypeDef>
48-
generateTypeDef(std::shared_ptr<Location> location) override;
54+
std::shared_ptr<TypeDef> generateTypeDef() override;
4955

5056
std::string generateHelperClass() const override;
5157

52-
std::string getAliasType() const;
58+
std::string getTypeAlias() const;
5359

5460
/**
5561
* @return true if helper methods will be generated for this struct
@@ -72,16 +78,15 @@ class Union : public StructOrUnion,
7278
public ArrayType,
7379
public std::enable_shared_from_this<Union> {
7480
public:
75-
Union(std::string name, std::vector<Field *> fields, uint64_t maxSize);
81+
Union(std::string name, std::vector<Field *> fields, uint64_t maxSize,
82+
std::shared_ptr<Location> location);
7683

77-
std::shared_ptr<TypeDef>
78-
generateTypeDef(std::shared_ptr<Location> location) override;
84+
std::shared_ptr<TypeDef> generateTypeDef() override;
7985

8086
std::string generateHelperClass() const override;
8187

8288
using StructOrUnion::operator==;
8389

84-
private:
8590
std::string getTypeAlias() const;
8691
};
8792

bindgen/ir/TypeDef.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,4 @@ bool TypeDef::operator==(const Type &other) const {
4545
return false;
4646
}
4747

48-
void TypeDef::setLocation(std::shared_ptr<Location> location) {
49-
this->location = std::move(location);
50-
}
51-
5248
std::shared_ptr<Location> TypeDef::getLocation() { return location; }

bindgen/ir/TypeDef.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ class TypeDef : public TypeAndName, public Type {
2121

2222
bool operator==(const Type &other) const override;
2323

24-
void setLocation(std::shared_ptr<Location> location);
25-
2624
std::shared_ptr<Location> getLocation();
2725

2826
private:
2927
/**
30-
* nullptr if type is located in main file or is generated.
28+
* nullptr if type is generated.
3129
*/
3230
std::shared_ptr<Location> location;
3331
};

0 commit comments

Comments
 (0)