Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bindgen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ add_executable(bindgen
ir/Location.cpp
ir/LocationManager.h
ir/LocationManager.cpp
ir/LocatableType.cpp
ir/LocatableType.h
)

if (STATIC_LINKING)
Expand Down
6 changes: 2 additions & 4 deletions bindgen/ir/Enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ int64_t Enumerator::getValue() { return value; }
Enum::Enum(std::string name, std::string type,
std::vector<Enumerator> enumerators,
std::shared_ptr<Location> location)
: PrimitiveType(std::move(type)), name(std::move(name)),
enumerators(std::move(enumerators)), location(std::move(location)) {}
: PrimitiveType(std::move(type)), LocatableType(std::move(location)),
name(std::move(name)), enumerators(std::move(enumerators)) {}

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

Expand Down Expand Up @@ -55,5 +55,3 @@ std::string Enum::getTypeAlias() const {
assert(!isAnonymous());
return "enum_" + name;
}

std::shared_ptr<Location> Enum::getLocation() const { return location; }
6 changes: 2 additions & 4 deletions bindgen/ir/Enum.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SCALA_NATIVE_BINDGEN_ENUM_H
#define SCALA_NATIVE_BINDGEN_ENUM_H

#include "LocatableType.h"
#include "TypeDef.h"
#include "types/PrimitiveType.h"
#include <vector>
Expand All @@ -18,7 +19,7 @@ class Enumerator {
int64_t value;
};

class Enum : public PrimitiveType {
class Enum : public PrimitiveType, public LocatableType {
public:
Enum(std::string name, std::string type,
std::vector<Enumerator> enumerators,
Expand All @@ -34,12 +35,9 @@ class Enum : public PrimitiveType {

std::string getTypeAlias() const;

std::shared_ptr<Location> getLocation() const;

private:
std::string name; // might be empty
std::vector<Enumerator> enumerators;
std::shared_ptr<Location> location;
};

#endif // SCALA_NATIVE_BINDGEN_ENUM_H
3 changes: 2 additions & 1 deletion bindgen/ir/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Function &func) {
return s;
}

bool Function::usesType(std::shared_ptr<Type> type, bool stopOnTypeDefs) const {
bool Function::usesType(std::shared_ptr<const Type> type,
bool stopOnTypeDefs) const {
if (*retType == *type || retType->usesType(type, stopOnTypeDefs)) {
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Function {
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
const Function &func);

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

std::string getName() const;

Expand Down
48 changes: 12 additions & 36 deletions bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
for (const auto &typeDef : ir.typeDefs) {
if (ir.shouldOutput(typeDef)) {
s << *typeDef;
} else if (isAliasForOpaqueType(typeDef.get()) &&
ir.inMainFile(*typeDef)) {
} else if (typeDef->hasLocation() &&
isAliasForOpaqueType(typeDef.get()) &&
ir.locationManager.inMainFile(*typeDef->getLocation())) {
llvm::errs() << "Warning: type alias " + typeDef->getName()
<< " is skipped because it is an unused alias for "
"incomplete type."
Expand Down Expand Up @@ -271,7 +272,8 @@ void IR::replaceTypeInTypeDefs(std::shared_ptr<const Type> oldType,

template <typename T>
bool IR::isTypeUsed(const std::vector<T> &declarations,
std::shared_ptr<Type> type, bool stopOnTypeDefs) const {
std::shared_ptr<const Type> type,
bool stopOnTypeDefs) const {
for (const auto &decl : declarations) {
if (decl->usesType(type, stopOnTypeDefs)) {
return true;
Expand All @@ -280,7 +282,8 @@ bool IR::isTypeUsed(const std::vector<T> &declarations,
return false;
}

bool IR::typeIsUsedOnlyInTypeDefs(const std::shared_ptr<Type> &type) const {
bool IR::typeIsUsedOnlyInTypeDefs(
const std::shared_ptr<const Type> &type) const {
/* varDefines are not checked here because they are simply
* aliases for variables.*/
return !(
Expand All @@ -289,7 +292,7 @@ bool IR::typeIsUsedOnlyInTypeDefs(const std::shared_ptr<Type> &type) const {
isTypeUsed(literalDefines, type, true));
}

bool IR::isTypeUsed(const std::shared_ptr<Type> &type,
bool IR::isTypeUsed(const std::shared_ptr<const Type> &type,
bool checkRecursively) const {
if (checkRecursively) {
if (isTypeUsed(functions, type, true) ||
Expand Down Expand Up @@ -437,26 +440,6 @@ IR::~IR() {
varDefines.clear();
}

template <typename T> bool IR::inMainFile(const T &type) const {
std::shared_ptr<Location> location = type.getLocation();
if (!location) {
/* generated TypeDef */
auto *typeDef = dynamic_cast<const TypeDef *>(&type);
assert(typeDef);
const Type *innerType = typeDef->getType().get();
if (isInstanceOf<Struct>(innerType)) {
return inMainFile(*dynamic_cast<const Struct *>(innerType));
}
if (isInstanceOf<Union>(innerType)) {
return inMainFile(*dynamic_cast<const Union *>(innerType));
}
if (isInstanceOf<Enum>(innerType)) {
return inMainFile(*dynamic_cast<const Enum *>(innerType));
}
}
return location && locationManager.inMainFile(*location);
}

template <typename T>
bool IR::hasOutputtedDeclaration(
const std::vector<std::shared_ptr<T>> &declarations) const {
Expand All @@ -468,20 +451,13 @@ bool IR::hasOutputtedDeclaration(
return false;
}

template <typename T>
bool IR::shouldOutput(const std::shared_ptr<T> &type) const {
bool IR::shouldOutput(const std::shared_ptr<const LocatableType> &type) const {
if (isTypeUsed(type, true)) {
return true;
}
if (!inMainFile(*type)) {
/* remove unused types from included files */
if (isAliasForOpaqueType(type.get())) {
return false;
}
auto *typeDef = dynamic_cast<TypeDef *>(type.get());
if (typeDef) {
/* unused typedefs from main file are printed only if they are not
* aliases for an opaque type. */
return !isAliasForOpaqueType(typeDef);
}
return true;
/* remove unused types from included files */
return locationManager.inMainFile(*type->getLocation());
}
14 changes: 6 additions & 8 deletions bindgen/ir/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,22 +114,24 @@ class IR {
/**
* @return true if given type is used only in typedefs.
*/
bool typeIsUsedOnlyInTypeDefs(const std::shared_ptr<Type> &type) const;
bool
typeIsUsedOnlyInTypeDefs(const std::shared_ptr<const Type> &type) const;

/**
* @param checkRecursively if this parameter is true then the method will
* output false if the type is used only in unused types
* @return true if type is used in one of declarations
*/
bool isTypeUsed(const std::shared_ptr<Type> &type,
bool isTypeUsed(const std::shared_ptr<const Type> &type,
bool checkRecursively = false) const;

/**
* @return true if type is used in one of given declarations.
*/
template <typename T>
bool isTypeUsed(const std::vector<T> &declarations,
std::shared_ptr<Type> type, bool stopOnTypeDefs) const;
std::shared_ptr<const Type> type,
bool stopOnTypeDefs) const;

void setScalaNames();

Expand All @@ -146,19 +148,15 @@ class IR {
T getDeclarationWithName(const std::vector<T> &declarations,
const std::string &name) const;

template <typename T> bool inMainFile(const T &type) const;

/**
* @tparam T Enum, Struct, Union or TypeDef
* @return true if the type will be printed.
* Following types are not printed:
* - Unused types from included headers
* - Unused typedefs from main header if they reference an opaque
* type (if such typedef is used then true is returned but error
* message is printed when bindings are generated)
*/
template <typename T>
bool shouldOutput(const std::shared_ptr<T> &type) const;
bool shouldOutput(const std::shared_ptr<const LocatableType> &type) const;

/**
* @tparam T Struct or Union
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/LiteralDefine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
return s;
}

bool LiteralDefine::usesType(const std::shared_ptr<Type> &type,
bool LiteralDefine::usesType(const std::shared_ptr<const Type> &type,
bool stopOnTypeDefs) const {
return *this->type == *type ||
this->type.get()->usesType(type, stopOnTypeDefs);
Expand Down
3 changes: 2 additions & 1 deletion bindgen/ir/LiteralDefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class LiteralDefine : public Define {
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
const LiteralDefine &literalDefine);

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

private:
std::string literal;
Expand Down
8 changes: 8 additions & 0 deletions bindgen/ir/LocatableType.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "LocatableType.h"

LocatableType::LocatableType(std::shared_ptr<Location> location)
: location(std::move(location)) {}

std::shared_ptr<Location> LocatableType::getLocation() const {
return location;
}
20 changes: 20 additions & 0 deletions bindgen/ir/LocatableType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef SCALA_NATIVE_BINDGEN_LOCATABLE_H
#define SCALA_NATIVE_BINDGEN_LOCATABLE_H

#include "Location.h"
#include "types/Type.h"

class LocatableType : virtual public Type {
public:
explicit LocatableType(std::shared_ptr<Location> location);

virtual std::shared_ptr<Location> getLocation() const;

protected:
/**
* nullptr if type is generated
*/
std::shared_ptr<Location> location;
};

#endif // SCALA_NATIVE_BINDGEN_LOCATABLE_H
10 changes: 3 additions & 7 deletions bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ uint64_t Field::getOffsetInBits() const { return offsetInBits; }
StructOrUnion::StructOrUnion(std::string name,
std::vector<std::shared_ptr<Field>> fields,
std::shared_ptr<Location> location)
: name(std::move(name)), fields(std::move(fields)),
location(std::move(location)) {}
: LocatableType(std::move(location)), name(std::move(name)),
fields(std::move(fields)) {}

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

std::shared_ptr<Location> StructOrUnion::getLocation() const {
return location;
}

bool StructOrUnion::hasHelperMethods() const { return !fields.empty(); }

Struct::Struct(std::string name, std::vector<std::shared_ptr<Field>> fields,
Expand Down Expand Up @@ -121,7 +117,7 @@ std::string Struct::str() const {
return ss.str();
}

bool Struct::usesType(const std::shared_ptr<Type> &type,
bool Struct::usesType(const std::shared_ptr<const Type> &type,
bool stopOnTypeDefs) const {
for (const auto &field : fields) {
if (*field->getType() == *type ||
Expand Down
8 changes: 3 additions & 5 deletions bindgen/ir/Struct.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SCALA_NATIVE_BINDGEN_STRUCT_H
#define SCALA_NATIVE_BINDGEN_STRUCT_H

#include "LocatableType.h"
#include "TypeAndName.h"
#include "TypeDef.h"
#include "types/ArrayType.h"
Expand All @@ -25,7 +26,7 @@ class Field : public TypeAndName {
uint64_t offsetInBits = 0;
};

class StructOrUnion : public virtual Type {
class StructOrUnion : public LocatableType {
public:
StructOrUnion(std::string name, std::vector<std::shared_ptr<Field>> fields,
std::shared_ptr<Location> location);
Expand All @@ -36,16 +37,13 @@ class StructOrUnion : public virtual Type {

std::string getName() const;

std::shared_ptr<Location> getLocation() const;

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

virtual bool hasHelperMethods() const;

protected:
std::string name;
std::vector<std::shared_ptr<Field>> fields;
std::shared_ptr<Location> location;
};

class Struct : public StructOrUnion {
Expand All @@ -65,7 +63,7 @@ class Struct : public StructOrUnion {
*/
bool hasHelperMethods() const override;

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

std::string str() const override;
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/TypeAndName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ bool TypeAndName::operator!=(const TypeAndName &other) const {
return !(*this == other);
}

bool TypeAndName::usesType(const std::shared_ptr<Type> &type,
bool TypeAndName::usesType(const std::shared_ptr<const Type> &type,
bool stopOnTypeDefs) const {
return *this->type == *type ||
this->type.get()->usesType(type, stopOnTypeDefs);
Expand Down
3 changes: 2 additions & 1 deletion bindgen/ir/TypeAndName.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class TypeAndName {

bool operator!=(const TypeAndName &other) const;

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

protected:
std::string name;
Expand Down
Loading