Skip to content

Commit 902fa75

Browse files
committed
Remove subclasses of Location. Don't remove not printed declarations
1 parent bce760d commit 902fa75

29 files changed

+190
-240
lines changed

bindgen/CMakeLists.txt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,10 @@ add_executable(bindgen
7070
ir/types/FunctionPointerType.h
7171
ir/types/ArrayType.cpp
7272
ir/types/ArrayType.h
73-
ir/location/Location.h
74-
ir/location/ScalaLocation.cpp
75-
ir/location/ScalaLocation.h
76-
ir/location/SourceLocation.cpp
77-
ir/location/SourceLocation.h
78-
ir/location/LocationManager.cpp
79-
ir/location/LocationManager.h
73+
ir/Location.h
74+
ir/Location.cpp
75+
ir/LocationManager.h
76+
ir/LocationManager.cpp
8077
)
8178

8279
if (STATIC_LINKING)

bindgen/Main.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "defines/DefineFinderActionFactory.h"
2+
#include "ir/LocationManager.h"
23
#include "visitor/ScalaFrontendActionFactory.h"
34
#include <clang/Tooling/CommonOptionsParser.h>
45

@@ -52,20 +53,19 @@ int main(int argc, const char *argv[]) {
5253
objectName = "nativeLib";
5354
}
5455

55-
IR ir(libName, linkName, objectName, Package.getValue());
56+
assert(op.getSourcePathList().size() == 1);
57+
char *resolved = realpath(op.getSourcePathList()[0].c_str(), nullptr);
58+
LocationManager locationManager(resolved);
59+
60+
IR ir(libName, linkName, objectName, Package.getValue(), locationManager);
5661

5762
DefineFinderActionFactory defineFinderActionFactory(ir);
5863
int result = Tool.run(&defineFinderActionFactory);
5964
if (result) {
6065
return result;
6166
}
6267

63-
assert(op.getSourcePathList().size() == 1);
64-
65-
char *resolved = realpath(op.getSourcePathList()[0].c_str(), nullptr);
66-
LocationManager locationManager(resolved);
67-
68-
ScalaFrontendActionFactory actionFactory(ir, locationManager);
68+
ScalaFrontendActionFactory actionFactory(ir);
6969
result = Tool.run(&actionFactory);
7070

7171
ir.generate(ExcludePrefix.getValue());

bindgen/TypeTranslator.h

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

33
#include "ir/IR.h"
4-
#include "ir/location/LocationManager.h"
54
#include <clang/Tooling/Tooling.h>
65

76
class TypeTranslator {

bindgen/ir/Enum.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ std::string Enum::getTypeAlias() const {
5656
return "enum_" + name;
5757
}
5858

59-
std::shared_ptr<Location> Enum::getLocation() { return location; }
59+
std::shared_ptr<Location> Enum::getLocation() const { return location; }

bindgen/ir/Enum.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Enum : public PrimitiveType, public std::enable_shared_from_this<Enum> {
3434

3535
std::string getTypeAlias() const;
3636

37-
std::shared_ptr<Location> getLocation();
37+
std::shared_ptr<Location> getLocation() const;
3838

3939
private:
4040
std::string name; // might be empty

bindgen/ir/IR.cpp

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "IR.h"
22
#include "../Utils.h"
3-
#include "location/SourceLocation.h"
43

54
IR::IR(std::string libName, std::string linkName, std::string objectName,
6-
std::string packageName)
5+
std::string packageName, const LocationManager &locationManager)
76
: libName(std::move(libName)), linkName(std::move(linkName)),
8-
objectName(std::move(objectName)), packageName(std::move(packageName)) {}
7+
objectName(std::move(objectName)), locationManager(locationManager),
8+
packageName(std::move(packageName)) {}
99

1010
void IR::addFunction(std::string name, std::vector<Parameter *> parameters,
1111
std::shared_ptr<Type> retType, bool isVariadic) {
@@ -78,8 +78,10 @@ void IR::addVarDefine(std::string name, std::shared_ptr<Variable> variable) {
7878
}
7979

8080
bool IR::libObjEmpty() const {
81-
return functions.empty() && typeDefs.empty() && structs.empty() &&
82-
unions.empty() && varDefines.empty() && variables.empty();
81+
return functions.empty() && !hasOutputtedTypeDefs() &&
82+
!hasOutputtedDeclaration(structs) &&
83+
!hasOutputtedDeclaration(unions) && varDefines.empty() &&
84+
variables.empty();
8385
}
8486

8587
llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
@@ -89,7 +91,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
8991
s << "package " << ir.packageName << "\n\n";
9092
}
9193

92-
if (!ir.libObjEmpty() || !ir.enums.empty() || !ir.literalDefines.empty()) {
94+
if (!ir.libObjEmpty() || ir.hasOutputtedEnums() ||
95+
!ir.literalDefines.empty()) {
9396
s << "import scala.scalanative._\n"
9497
<< "import scala.scalanative.native._\n\n";
9598
}
@@ -105,7 +108,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
105108
<< "object " << objectName << " {\n";
106109

107110
for (const auto &typeDef : ir.typeDefs) {
108-
s << *typeDef;
111+
if (ir.typeDefInMainFile(*typeDef) || ir.isTypeUsed(typeDef)) {
112+
s << *typeDef;
113+
}
109114
}
110115

111116
for (const auto &variable : ir.variables) {
@@ -131,19 +136,20 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
131136
s << "}\n\n";
132137
}
133138

134-
if (!ir.enums.empty() || ir.hasHelperMethods()) {
139+
if (ir.hasOutputtedEnums() || ir.hasHelperMethods()) {
135140
s << "import " << objectName << "._\n\n";
136141
}
137142

138-
if (!ir.enums.empty()) {
143+
if (ir.hasOutputtedEnums()) {
139144
s << "object " << ir.libName << "Enums {\n";
140145

141-
unsigned long enumeratorsCount = ir.enums.size();
142-
for (unsigned long i = 0; i < enumeratorsCount; i++) {
143-
auto e = ir.enums[i];
144-
s << *e;
145-
if (i < enumeratorsCount - 1) {
146-
s << "\n"; // space between groups of enums
146+
std::string sep = "";
147+
for (const auto &e : ir.enums) {
148+
if (ir.inMainFile(*e) ||
149+
(!e->isAnonymous() &&
150+
ir.isTypeUsed(ir.getTypeDefWithName(e->getTypeAlias())))) {
151+
s << sep << *e;
152+
sep = "\n";
147153
}
148154
}
149155

@@ -154,13 +160,15 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
154160
s << "object " << ir.libName << "Helpers {\n";
155161

156162
for (const auto &st : ir.structs) {
157-
if (st->hasHelperMethods()) {
163+
if (ir.isOutputted(st.get()) && st->hasHelperMethods()) {
158164
s << "\n" << st->generateHelperClass();
159165
}
160166
}
161167

162168
for (const auto &u : ir.unions) {
163-
s << "\n" << u->generateHelperClass();
169+
if (ir.isOutputted(u.get())) {
170+
s << "\n" << u->generateHelperClass();
171+
}
164172
}
165173

166174
s << "}\n\n";
@@ -173,19 +181,19 @@ void IR::generate(const std::string &excludePrefix) {
173181
if (!generated) {
174182
setScalaNames();
175183
filterDeclarations(excludePrefix);
176-
removeUnusedExternalTypedefs();
184+
// removeUnusedExternalTypedefs();
177185
generated = true;
178186
}
179187
}
180188

181189
bool IR::hasHelperMethods() const {
182-
if (!unions.empty()) {
190+
if (hasOutputtedDeclaration(unions)) {
183191
/* all unions have helper methods */
184192
return true;
185193
}
186194

187195
for (const auto &s : structs) {
188-
if (s->hasHelperMethods()) {
196+
if (isOutputted(s.get()) && s->hasHelperMethods()) {
189197
return true;
190198
}
191199
}
@@ -328,7 +336,7 @@ std::shared_ptr<Variable> IR::addVariable(const std::string &name,
328336
return variable;
329337
}
330338

331-
std::shared_ptr<TypeDef> IR::getTypeDefWithName(const std::string &name) {
339+
std::shared_ptr<TypeDef> IR::getTypeDefWithName(const std::string &name) const {
332340
/* nullptr is returned in 2 cases:
333341
* 1. TypeTranslator translates opaque struct/union type for which TypeDef
334342
* was not created.
@@ -338,8 +346,8 @@ std::shared_ptr<TypeDef> IR::getTypeDefWithName(const std::string &name) {
338346
}
339347

340348
template <typename T>
341-
T IR::getDeclarationWithName(std::vector<T> &declarations,
342-
const std::string &name) {
349+
T IR::getDeclarationWithName(const std::vector<T> &declarations,
350+
const std::string &name) const {
343351
for (auto it = declarations.begin(), end = declarations.end(); it != end;
344352
++it) {
345353
T declaration = (*it);
@@ -362,55 +370,60 @@ IR::~IR() {
362370
varDefines.clear();
363371
}
364372

365-
void IR::removeUnusedExternalTypedefs() {
366-
for (auto it = typeDefs.begin(); it != typeDefs.end();) {
367-
std::shared_ptr<TypeDef> typeDef = *it;
368-
std::shared_ptr<Location> location = typeDef->getLocation();
369-
auto *sourceLocation = dynamic_cast<SourceLocation *>(location.get());
370-
if (sourceLocation && !sourceLocation->isMainFile()) {
371-
if (!isTypeUsed(typeDef)) {
372-
it = typeDefs.erase(it);
373-
} else {
374-
++it;
375-
}
376-
} else {
377-
++it;
373+
bool IR::typeDefInMainFile(const TypeDef &typeDef) const {
374+
if (inMainFile(typeDef)) {
375+
return true;
376+
}
377+
Type *type = typeDef.getType().get();
378+
if (isInstanceOf<Struct>(type)) {
379+
return inMainFile(*dynamic_cast<Struct *>(type));
380+
}
381+
if (isInstanceOf<Union>(type)) {
382+
return inMainFile(*dynamic_cast<Union *>(type));
383+
}
384+
if (isInstanceOf<Enum>(type)) {
385+
return inMainFile(*dynamic_cast<Enum *>(type));
386+
}
387+
return false;
388+
}
389+
390+
template <typename T> bool IR::inMainFile(const T &type) const {
391+
std::shared_ptr<Location> location = type.getLocation();
392+
return location && locationManager.inMainFile(*location);
393+
}
394+
395+
bool IR::hasOutputtedEnums() const {
396+
for (const auto &e : enums) {
397+
if (inMainFile(*e) ||
398+
(!e->isAnonymous() &&
399+
isTypeUsed(getTypeDefWithName(e->getTypeAlias())))) {
400+
return true;
378401
}
379402
}
380-
removeUnusedExternalTypeAndTypedef(structs);
381-
removeUnusedExternalTypeAndTypedef(unions);
382-
removeUnusedExternalTypeAndTypedef(enums);
403+
return false;
383404
}
384405

385-
template <typename T>
386-
void IR::removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
387-
T *declaration) {
388-
for (auto it = declarations.begin(); it != declarations.end();) {
389-
T *decl = (*it).get();
390-
if (decl == declaration) {
391-
it = declarations.erase(it);
392-
} else {
393-
++it;
406+
bool IR::hasOutputtedTypeDefs() const {
407+
for (const auto &typeDef : typeDefs) {
408+
if (inMainFile(*typeDef) || isTypeUsed(typeDef)) {
409+
return true;
394410
}
395411
}
412+
return false;
396413
}
397414

398415
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-
}
416+
bool IR::hasOutputtedDeclaration(
417+
const std::vector<std::shared_ptr<T>> &declarations) const {
418+
for (const auto &declaration : declarations) {
419+
if (isOutputted(declaration.get())) {
420+
return true;
414421
}
415422
}
423+
return false;
424+
}
425+
426+
bool IR::isOutputted(const StructOrUnion *structOrUnion) const {
427+
return inMainFile(*structOrUnion) ||
428+
isTypeUsed(getTypeDefWithName(structOrUnion->getTypeAlias()));
416429
}

bindgen/ir/IR.h

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "Enum.h"
55
#include "Function.h"
66
#include "LiteralDefine.h"
7+
#include "LocationManager.h"
78
#include "PossibleVarDefine.h"
89
#include "Struct.h"
910
#include "TypeDef.h"
@@ -15,7 +16,7 @@
1516
class IR {
1617
public:
1718
IR(std::string libName, std::string linkName, std::string objectName,
18-
std::string packageName);
19+
std::string packageName, const LocationManager &locationManager);
1920

2021
~IR();
2122

@@ -68,7 +69,7 @@ class IR {
6869
*/
6970
std::string getDefineForVar(const std::string &varName) const;
7071

71-
std::shared_ptr<TypeDef> getTypeDefWithName(const std::string &name);
72+
std::shared_ptr<TypeDef> getTypeDefWithName(const std::string &name) const;
7273

7374
private:
7475
/**
@@ -137,28 +138,30 @@ class IR {
137138
void filterByName(std::vector<T> &declarations, const std::string &name);
138139

139140
template <typename T>
140-
T getDeclarationWithName(std::vector<T> &declarations,
141-
const std::string &name);
141+
T getDeclarationWithName(const std::vector<T> &declarations,
142+
const std::string &name) const;
142143

143-
void removeUnusedExternalTypedefs();
144+
bool typeDefInMainFile(const TypeDef &typeDef) const;
144145

145-
template <typename T>
146-
void removeDeclaration(std::vector<std::shared_ptr<T>> &declarations,
147-
T *declaration);
146+
template <typename T> bool inMainFile(const T &type) const;
147+
148+
bool hasOutputtedEnums() const;
149+
150+
bool hasOutputtedTypeDefs() const;
151+
152+
bool isOutputted(const StructOrUnion *structOrUnion) const;
148153

149154
/**
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
155+
* @tparam T Struct or Union
154156
*/
155157
template <typename T>
156-
void
157-
removeUnusedExternalTypeAndTypedef(std::vector<std::shared_ptr<T>> &types);
158+
bool hasOutputtedDeclaration(
159+
const std::vector<std::shared_ptr<T>> &declarations) const;
158160

159161
std::string libName; // name of the library
160162
std::string linkName; // name of the library to link with
161163
std::string objectName; // name of Scala object
164+
const LocationManager &locationManager;
162165
std::vector<std::shared_ptr<Function>> functions;
163166
std::vector<std::shared_ptr<TypeDef>> typeDefs;
164167
std::vector<std::shared_ptr<Struct>> structs;

bindgen/ir/Location.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "Location.h"
2+
3+
Location::Location(std::string path, int lineNumber)
4+
: path(std::move(path)), lineNumber(lineNumber) {}
5+
6+
std::string Location::getPath() const { return path; }

0 commit comments

Comments
 (0)