Skip to content

Commit 919c4be

Browse files
committed
Remove unused external types
1 parent 2f9f9bf commit 919c4be

26 files changed

+292
-48
lines changed

bindgen/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ add_executable(bindgen
7272
ir/types/FunctionPointerType.h
7373
ir/types/ArrayType.cpp
7474
ir/types/ArrayType.h
75+
ir/location/Location.h
76+
ir/location/ScalaLocation.cpp
77+
ir/location/ScalaLocation.h
78+
ir/location/SourceLocation.cpp
79+
ir/location/SourceLocation.h
80+
ir/location/LocationManager.cpp
81+
ir/location/LocationManager.h
7582
)
7683

7784
if (STATIC_LINKING)

bindgen/Main.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ int main(int argc, const char *argv[]) {
7979
return result;
8080
}
8181

82-
ScalaFrontendActionFactory actionFactory(ir);
82+
assert(op.getSourcePathList().size() == 1);
83+
84+
char *resolved = realpath(op.getSourcePathList()[0].c_str(), nullptr);
85+
LocationManager locationManager(resolved);
86+
87+
ScalaFrontendActionFactory actionFactory(ir, locationManager);
8388
result = Tool.run(&actionFactory);
8489

8590
auto printLoc = PrintHeadersLocation.getValue();

bindgen/TypeTranslator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ TypeTranslator::translateStructOrUnionOrEnum(const clang::QualType &qtpe) {
102102
/* type is not yet defined.
103103
* TypeDef with nullptr will be created.
104104
* nullptr will be replaced by actual type when the type is declared. */
105-
typeDef = ir.addTypeDef(nameWithoutSpace, nullptr);
105+
typeDef = ir.addTypeDef(nameWithoutSpace, nullptr, nullptr);
106106
return typeDef;
107107
}
108108

bindgen/TypeTranslator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "ir/IR.h"
4+
#include "ir/location/LocationManager.h"
45
#include <clang/Tooling/Tooling.h>
56

67
class TypeTranslator {

bindgen/ir/Enum.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ Enum::Enum(std::string name, std::string type,
1414

1515
bool Enum::isAnonymous() const { return name.empty(); }
1616

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

2224
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Enum &e) {

bindgen/ir/Enum.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class Enum : public PrimitiveType, public std::enable_shared_from_this<Enum> {
2525

2626
bool isAnonymous() const;
2727

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

3031
std::string getName() const;
3132

bindgen/ir/IR.cpp

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "IR.h"
22
#include "../Utils.h"
3+
#include "location/SourceLocation.h"
34

45
IR::IR(std::string libName, std::string linkName, std::string objectName,
56
std::string packageName)
@@ -13,48 +14,53 @@ void IR::addFunction(std::string name, std::vector<Parameter *> parameters,
1314
}
1415

1516
std::shared_ptr<TypeDef> IR::addTypeDef(std::string name,
16-
std::shared_ptr<Type> type) {
17-
typeDefs.push_back(std::make_shared<TypeDef>(std::move(name), type));
17+
std::shared_ptr<Type> type,
18+
std::shared_ptr<Location> location) {
19+
typeDefs.push_back(
20+
std::make_shared<TypeDef>(std::move(name), type, std::move(location)));
1821
return typeDefs.back();
1922
}
2023

2124
std::shared_ptr<Type> IR::addEnum(std::string name, const std::string &type,
22-
std::vector<Enumerator> enumerators) {
25+
std::vector<Enumerator> enumerators,
26+
std::shared_ptr<Location> location) {
2327
std::shared_ptr<Enum> e =
2428
std::make_shared<Enum>(std::move(name), type, std::move(enumerators));
2529
enums.push_back(e);
2630
if (!e->isAnonymous()) {
27-
typeDefs.push_back(e->generateTypeDef());
31+
typeDefs.push_back(e->generateTypeDef(std::move(location)));
2832
return typeDefs.back();
2933
}
3034
return nullptr;
3135
}
3236

3337
void IR::addStruct(std::string name, std::vector<Field *> fields,
34-
uint64_t typeSize) {
38+
uint64_t typeSize, std::shared_ptr<Location> location) {
3539
std::shared_ptr<Struct> s =
3640
std::make_shared<Struct>(name, std::move(fields), typeSize);
3741
structs.push_back(s);
3842
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("struct_" + name);
3943
if (typeDef) {
4044
/* the struct type used to be opaque type, typeDef contains nullptr */
4145
typeDef.get()->setType(s);
46+
typeDef.get()->setLocation(location);
4247
} else {
43-
typeDefs.push_back(s->generateTypeDef());
48+
typeDefs.push_back(s->generateTypeDef(std::move(location)));
4449
}
4550
}
4651

4752
void IR::addUnion(std::string name, std::vector<Field *> fields,
48-
uint64_t maxSize) {
53+
uint64_t maxSize, std::shared_ptr<Location> location) {
4954
std::shared_ptr<Union> u =
5055
std::make_shared<Union>(name, std::move(fields), maxSize);
5156
unions.push_back(u);
5257
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("union_" + name);
5358
if (typeDef) {
5459
/* the union type used to be opaque type, typeDef contains nullptr */
5560
typeDef.get()->setType(u);
61+
typeDef.get()->setLocation(location);
5662
} else {
57-
typeDefs.push_back(u->generateTypeDef());
63+
typeDefs.push_back(u->generateTypeDef(std::move(location)));
5864
}
5965
}
6066

@@ -171,6 +177,7 @@ void IR::generate(const std::string &excludePrefix) {
171177
if (!generated) {
172178
setScalaNames();
173179
filterDeclarations(excludePrefix);
180+
removeUnusedExternalTypes();
174181
generated = true;
175182
}
176183
}
@@ -230,7 +237,7 @@ void IR::replaceTypeInTypeDefs(std::shared_ptr<Type> oldType,
230237

231238
template <typename T>
232239
bool IR::isTypeUsed(const std::vector<T> &declarations,
233-
std::shared_ptr<Type> type, bool stopOnTypeDefs) {
240+
std::shared_ptr<Type> type, bool stopOnTypeDefs) const {
234241
for (const auto &decl : declarations) {
235242
if (decl->usesType(type, stopOnTypeDefs)) {
236243
return true;
@@ -239,7 +246,7 @@ bool IR::isTypeUsed(const std::vector<T> &declarations,
239246
return false;
240247
}
241248

242-
bool IR::typeIsUsedOnlyInTypeDefs(std::shared_ptr<Type> type) {
249+
bool IR::typeIsUsedOnlyInTypeDefs(const std::shared_ptr<Type> &type) const {
243250
/* varDefines are not checked here because they are simply
244251
* aliases for variables.*/
245252
return !(
@@ -248,6 +255,11 @@ bool IR::typeIsUsedOnlyInTypeDefs(std::shared_ptr<Type> type) {
248255
isTypeUsed(literalDefines, type, true));
249256
}
250257

258+
bool IR::isTypeUsed(const std::shared_ptr<Type> &type) const {
259+
return !(typeIsUsedOnlyInTypeDefs(type) &&
260+
!isTypeUsed(typeDefs, type, false));
261+
}
262+
251263
void IR::setScalaNames() {
252264
/* Renaming according to Scala naming conventions
253265
* should happen here */
@@ -353,3 +365,47 @@ IR::~IR() {
353365
variables.clear();
354366
varDefines.clear();
355367
}
368+
369+
void IR::removeUnusedExternalTypes() {
370+
for (auto it = typeDefs.begin(); it != typeDefs.end();) {
371+
std::shared_ptr<TypeDef> typeDef = *it;
372+
std::shared_ptr<Location> location = typeDef->getLocation();
373+
auto *sourceLocation = dynamic_cast<SourceLocation *>(location.get());
374+
if (sourceLocation && !sourceLocation->isMainFile()) {
375+
if (!isTypeUsed(typeDef)) {
376+
removeStructOrUnionOrEnum(typeDef->getType());
377+
it = typeDefs.erase(it);
378+
} else {
379+
++it;
380+
}
381+
} else {
382+
++it;
383+
}
384+
}
385+
}
386+
387+
template <typename T>
388+
void IR::removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
389+
T *declaration) {
390+
for (auto it = declarations.begin(); it != declarations.end();) {
391+
T *decl = (*it).get();
392+
if (decl == declaration) {
393+
it = declarations.erase(it);
394+
} else {
395+
++it;
396+
}
397+
}
398+
}
399+
400+
void IR::removeStructOrUnionOrEnum(std::shared_ptr<Type> type) {
401+
if (isInstanceOf<Struct>(type.get())) {
402+
auto *s = dynamic_cast<Struct *>(type.get());
403+
removeDeclaration(structs, s);
404+
} else if (isInstanceOf<Union>(type.get())) {
405+
auto *u = dynamic_cast<Union *>(type.get());
406+
removeDeclaration(unions, u);
407+
} else if (isInstanceOf<Enum>(type.get())) {
408+
auto *e = dynamic_cast<Enum *>(type.get());
409+
removeDeclaration(enums, e);
410+
}
411+
}

bindgen/ir/IR.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ class IR {
2323
std::shared_ptr<Type> retType, bool isVariadic);
2424

2525
std::shared_ptr<TypeDef> addTypeDef(std::string name,
26-
std::shared_ptr<Type> type);
26+
std::shared_ptr<Type> type,
27+
std::shared_ptr<Location> location);
2728

2829
/**
2930
* @return type alias for the enum
3031
*/
3132
std::shared_ptr<Type> addEnum(std::string name, const std::string &type,
32-
std::vector<Enumerator> enumerators);
33+
std::vector<Enumerator> enumerators,
34+
std::shared_ptr<Location> location);
3335

3436
void addStruct(std::string name, std::vector<Field *> fields,
35-
uint64_t typeSize);
37+
uint64_t typeSize, std::shared_ptr<Location> location);
3638

3739
void addUnion(std::string name, std::vector<Field *> fields,
38-
uint64_t maxSize);
40+
uint64_t maxSize, std::shared_ptr<Location> location);
3941

4042
void addLiteralDefine(std::string name, std::string literal,
4143
std::shared_ptr<Type> type);
@@ -109,14 +111,19 @@ class IR {
109111
/**
110112
* @return true if given type is used only in typedefs.
111113
*/
112-
bool typeIsUsedOnlyInTypeDefs(std::shared_ptr<Type> type);
114+
bool typeIsUsedOnlyInTypeDefs(const std::shared_ptr<Type> &type) const;
115+
116+
/**
117+
* @return true if type is used in one of declarations
118+
*/
119+
bool isTypeUsed(const std::shared_ptr<Type> &type) const;
113120

114121
/**
115122
* @return true if type is used in one of given declarations.
116123
*/
117124
template <typename T>
118125
bool isTypeUsed(const std::vector<T> &declarations,
119-
std::shared_ptr<Type> type, bool stopOnTypeDefs);
126+
std::shared_ptr<Type> type, bool stopOnTypeDefs) const;
120127

121128
void setScalaNames();
122129

@@ -133,6 +140,17 @@ class IR {
133140
T getDeclarationWithName(std::vector<T> &declarations,
134141
const std::string &name);
135142

143+
void removeUnusedExternalTypes();
144+
145+
template <typename T>
146+
void removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
147+
T *declaration);
148+
149+
/**
150+
* remove declaration from IR if type is struct, union or enum
151+
*/
152+
void removeStructOrUnionOrEnum(std::shared_ptr<Type> type);
153+
136154
std::string libName; // name of the library
137155
std::string linkName; // name of the library to link with
138156
std::string objectName; // name of Scala object

bindgen/ir/Struct.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,20 @@ bool StructOrUnion::operator==(const StructOrUnion &other) const {
7474
Struct::Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize)
7575
: StructOrUnion(std::move(name), std::move(fields)), typeSize(typeSize) {}
7676

77-
std::shared_ptr<TypeDef> Struct::generateTypeDef() {
77+
std::shared_ptr<TypeDef>
78+
Struct::generateTypeDef(std::shared_ptr<Location> location) {
7879
if (fields.size() < SCALA_NATIVE_MAX_STRUCT_FIELDS) {
79-
return std::make_shared<TypeDef>(getAliasType(), shared_from_this());
80+
return std::make_shared<TypeDef>(getAliasType(), shared_from_this(),
81+
std::move(location));
8082
} else {
8183
// There is no easy way to represent it as a struct in scala native,
8284
// have to represent it as an array and then Add helpers to help with
8385
// its manipulation
8486
return std::make_shared<TypeDef>(
8587
getAliasType(),
8688
std::make_shared<ArrayType>(std::make_shared<PrimitiveType>("Byte"),
87-
typeSize));
89+
typeSize),
90+
std::move(location));
8891
}
8992
}
9093

@@ -149,8 +152,10 @@ Union::Union(std::string name, std::vector<Field *> fields, uint64_t maxSize)
149152
: StructOrUnion(std::move(name), std::move(fields)),
150153
ArrayType(std::make_shared<PrimitiveType>("Byte"), maxSize) {}
151154

152-
std::shared_ptr<TypeDef> Union::generateTypeDef() {
153-
return std::make_shared<TypeDef>(getTypeAlias(), shared_from_this());
155+
std::shared_ptr<TypeDef>
156+
Union::generateTypeDef(std::shared_ptr<Location> location) {
157+
return std::make_shared<TypeDef>(getTypeAlias(), shared_from_this(),
158+
std::move(location));
154159
}
155160

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

bindgen/ir/Struct.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ class StructOrUnion {
2424

2525
~StructOrUnion();
2626

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

2930
virtual std::string generateHelperClass() const = 0;
3031

@@ -43,7 +44,8 @@ class Struct : public StructOrUnion,
4344
public:
4445
Struct(std::string name, std::vector<Field *> fields, uint64_t typeSize);
4546

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

4850
std::string generateHelperClass() const override;
4951

@@ -72,7 +74,8 @@ class Union : public StructOrUnion,
7274
public:
7375
Union(std::string name, std::vector<Field *> fields, uint64_t maxSize);
7476

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

7780
std::string generateHelperClass() const override;
7881

0 commit comments

Comments
 (0)