Skip to content

Commit

Permalink
Replace opaque type with CStruct0
Browse files Browse the repository at this point in the history
  • Loading branch information
kornilova203 committed Jul 12, 2018
1 parent 355a0a8 commit 072189c
Show file tree
Hide file tree
Showing 26 changed files with 122 additions and 291 deletions.
30 changes: 4 additions & 26 deletions bindgen/ir/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,39 +75,17 @@ bool Function::isLegalScalaNativeFunction() const {
* in this case is always represented as a pointer to element type */
auto *typeDef = dynamic_cast<TypeDef *>(retType.get());
if (typeDef &&
(typeDef->isAliasFor<Struct>() || typeDef->isAliasFor<ArrayType>())) {
(typeDef->isAliasFor<Struct>() || typeDef->isAliasFor<ArrayType>() ||
typeDef->isAliasForOpaqueType())) {
return false;
}
for (const auto &parameter : parameters) {
typeDef = dynamic_cast<TypeDef *>(parameter->getType().get());
if (typeDef && (typeDef->isAliasFor<Struct>() ||
typeDef->isAliasFor<ArrayType>())) {
typeDef->isAliasFor<ArrayType>() ||
typeDef->isAliasForOpaqueType())) {
return false;
}
}
return true;
}

void Function::replaceType(const std::shared_ptr<Type> &type,
const std::shared_ptr<Type> &replacement) {
if (*retType == *type) {
retType = replacement;
} else {
retType->replaceType(type, replacement);
}
for (const auto &parameter : parameters) {
parameter->replaceType(type, replacement);
}
}

bool Function::usesOpaqueType() const {
if (retType->usesOpaqueType()) {
return true;
}
for (const auto &parameter : parameters) {
if (parameter->usesOpaqueType()) {
return true;
}
}
return false;
}
5 changes: 0 additions & 5 deletions bindgen/ir/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ class Function {
*/
bool isLegalScalaNativeFunction() const;

void replaceType(const std::shared_ptr<Type> &type,
const std::shared_ptr<Type> &replacement);

bool usesOpaqueType() const;

private:
std::string getVarargsParameterName() const;

Expand Down
81 changes: 24 additions & 57 deletions bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,51 +111,50 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {

for (const auto &typeDef : ir.typeDefs) {
if (ir.shouldOutput(typeDef)) {
if (!typeDef->usesOpaqueType()) {
s << *typeDef;
} else if (!typeDef->getType()) {
llvm::errs() << "Error: type definition for "
<< typeDef->getName() << " was not found.\n";
llvm::errs().flush();
} else {
llvm::errs() << "Error: Typedef " << typeDef->getName()
<< " is skipped because it references an "
"opaque type.\n";
llvm::errs().flush();
s << *typeDef;
if (typeDef->getType()) {
auto *structOrUnion =
dynamic_cast<StructOrUnion *>(typeDef->getType().get());
if (structOrUnion &&
structOrUnion->hasIllegalUsageOfOpaqueType()) {
llvm::errs()
<< "Error: record " << structOrUnion->getName()
<< " has field of incomplete type. Declarations "
"that use this type may not work properly.\n";
llvm::errs().flush();
}
}
}
}

for (const auto &variable : ir.variables) {
if (!variable->usesOpaqueType()) {
if (!variable->hasIllegalUsageOfOpaqueType()) {
s << *variable;
} else {
llvm::errs()
<< "Error: Variable " << variable->getName()
<< " is skipped because it references an opaque type.\n";
llvm::errs() << "Error: Variable " << variable->getName()
<< " is skipped because it has incomplete type.\n";
}
}

for (const auto &varDefine : ir.varDefines) {
if (!varDefine->usesOpaqueType()) {
if (!varDefine->hasIllegalUsageOfOpaqueType()) {
s << *varDefine;
} else {
llvm::errs() << "Error: Typedef " << varDefine->getName()
<< " is skipped because it references an "
"opaque type.\n";
llvm::errs() << "Error: Variable alias " << varDefine->getName()
<< " is skipped because it has incomplete type\n";
llvm::errs().flush();
}
}

for (const auto &func : ir.functions) {
if (func->isLegalScalaNativeFunction()) {
s << *func;
} else {
if (!func->isLegalScalaNativeFunction()) {
llvm::errs()
<< "Warning: Function " << func->getName()
<< " is skipped because Scala Native does not support "
"passing structs and arrays by value.\n";
llvm::errs().flush();
} else {
s << *func;
}
}

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

for (const auto &st : ir.structs) {
if (ir.shouldOutput(st) && st->hasHelperMethods() &&
!st->usesOpaqueType()) {
!st->hasIllegalUsageOfOpaqueType()) {
s << "\n" << st->generateHelperClass();
}
}

for (const auto &u : ir.unions) {
if (ir.shouldOutput(u) && !u->usesOpaqueType()) {
if (ir.shouldOutput(u) && !u->hasIllegalUsageOfOpaqueType()) {
s << "\n" << u->generateHelperClass();
}
}
Expand All @@ -214,7 +213,6 @@ void IR::generate(const std::string &excludePrefix) {
if (!generated) {
setScalaNames();
filterDeclarations(excludePrefix);
fixPointersToOpaqueTypes();
generated = true;
}
}
Expand Down Expand Up @@ -480,38 +478,7 @@ bool IR::shouldOutput(const std::shared_ptr<T> &type) const {
if (typeDef) {
/* unused typedefs from main file are not printed if they are aliases
* for opaque types */
return !typeDef->referencesOpaqueType() && inMainFile(*typeDef);
return !typeDef->isAliasForOpaqueType() && inMainFile(*typeDef);
}
return inMainFile(*type);
}

void IR::fixPointersToOpaqueTypes() {
std::shared_ptr<Type> pointerToByte =
std::make_shared<PointerType>(std::make_shared<PrimitiveType>("Byte"));
for (const auto &typeDef : typeDefs) {
if (shouldOutput(typeDef)) {
if (typeDef->referencesOpaqueType()) {
std::shared_ptr<Type> pointerToStruct =
std::make_shared<PointerType>(typeDef);
replaceType(pointerToStruct, pointerToByte);
}
}
}
}

void IR::replaceType(std::shared_ptr<Type> type,
std::shared_ptr<Type> replacement) {
replaceType(functions, type, replacement);
replaceType(typeDefs, type, replacement);
replaceType(structs, type, replacement);
replaceType(unions, type, replacement);
}

template <typename T>
void IR::replaceType(std::vector<std::shared_ptr<T>> declarations,
std::shared_ptr<Type> type,
std::shared_ptr<Type> replacement) {
for (const auto &declaration : declarations) {
declaration->replaceType(type, replacement);
}
}
19 changes: 0 additions & 19 deletions bindgen/ir/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,25 +166,6 @@ class IR {
bool hasOutputtedDeclaration(
const std::vector<std::shared_ptr<T>> &declarations) const;

/**
* Replace pointer to opaque types with pointers to byte.
*/
void fixPointersToOpaqueTypes();

/**
* Replace given type with the replacement in all declarations.
*/
void replaceType(std::shared_ptr<Type> type,
std::shared_ptr<Type> replacement);

/**
* Replace given type with the replacement in given declarations.
*/
template <typename T>
void replaceType(std::vector<std::shared_ptr<T>> declarations,
std::shared_ptr<Type> type,
std::shared_ptr<Type> replacement);

std::string libName; // name of the library
std::string linkName; // name of the library to link with
std::string objectName; // name of Scala object
Expand Down
27 changes: 6 additions & 21 deletions bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,14 @@ std::shared_ptr<Location> StructOrUnion::getLocation() const {
return location;
}

void StructOrUnion::replaceType(const std::shared_ptr<Type> &type,
const std::shared_ptr<Type> &replacement) {
bool StructOrUnion::hasIllegalUsageOfOpaqueType() const {
for (const auto &field : fields) {
field->replaceType(type, replacement);
auto *typeDef = dynamic_cast<TypeDef *>(field->getType().get());
if (typeDef && typeDef->isAliasForOpaqueType()) {
return true;
}
}
return false;
}

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

bool Struct::usesOpaqueType() const {
for (const auto &field : fields) {
if (field->usesOpaqueType()) {
return true;
}
}
return false;
}

Union::Union(std::string name, std::vector<Field *> fields, uint64_t maxSize,
std::shared_ptr<Location> location)
: StructOrUnion(std::move(name), std::move(fields), std::move(location)),
Expand Down Expand Up @@ -220,12 +214,3 @@ bool Union::operator==(const Type &other) const {
}
return false;
}

bool Union::usesOpaqueType() const {
for (const auto &field : fields) {
if (field->usesOpaqueType()) {
return true;
}
}
return ArrayType::usesOpaqueType();
}
15 changes: 5 additions & 10 deletions bindgen/ir/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ class StructOrUnion {

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

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

protected:
std::string name;
Expand Down Expand Up @@ -71,10 +74,6 @@ class Struct : public StructOrUnion,

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

bool usesOpaqueType() const override;

using StructOrUnion::replaceType;

private:
/* type size is needed if number of fields is bigger than 22 */
uint64_t typeSize;
Expand All @@ -94,10 +93,6 @@ class Union : public StructOrUnion,
bool operator==(const Type &other) const override;

std::string getTypeAlias() const override;

bool usesOpaqueType() const override;

using StructOrUnion::replaceType;
};

#endif // SCALA_NATIVE_BINDGEN_STRUCT_H
19 changes: 0 additions & 19 deletions bindgen/ir/TypeAndName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,3 @@ bool TypeAndName::usesType(const std::shared_ptr<Type> &type,
return *this->type == *type ||
this->type.get()->usesType(type, stopOnTypeDefs);
}

void TypeAndName::replaceType(const std::shared_ptr<Type> &type,
const std::shared_ptr<Type> &replacement) {
if (!this->type) {
return;
}
if (*this->type == *type) {
this->type = replacement;
} else {
this->type->replaceType(type, replacement);
}
}

bool TypeAndName::usesOpaqueType() const {
if (!type) {
return true;
}
return type->usesOpaqueType();
}
5 changes: 0 additions & 5 deletions bindgen/ir/TypeAndName.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ class TypeAndName {

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

void replaceType(const std::shared_ptr<Type> &type,
const std::shared_ptr<Type> &replacement);

bool usesOpaqueType() const;

protected:
std::string name;
std::shared_ptr<Type> type;
Expand Down
20 changes: 9 additions & 11 deletions bindgen/ir/TypeDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ TypeDef::TypeDef(std::string name, std::shared_ptr<Type> type,
location(std::move(location)) {}

llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const TypeDef &typeDef) {
s << " type " + handleReservedWords(typeDef.name) + " = " +
typeDef.getType()->str() + "\n";
s << " type " << handleReservedWords(typeDef.name) << " = ";
if (typeDef.type) {
s << typeDef.getType()->str();
} else {
s << "native.CStruct0";
}
s << "\n";
return s;
}

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

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

bool TypeDef::referencesOpaqueType() const {
bool TypeDef::isAliasForOpaqueType() const {
if (!type) {
return true;
}
auto *typeDef = dynamic_cast<const TypeDef *>(type.get());
if (typeDef) {
return typeDef->referencesOpaqueType();
return typeDef->isAliasForOpaqueType();
}
return false;
}

bool TypeDef::usesOpaqueType() const {
if (!type) {
return true;
}
return type->usesOpaqueType();
}
6 changes: 1 addition & 5 deletions bindgen/ir/TypeDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,7 @@ class TypeDef : public TypeAndName, public Type {
* @return true if typedef references opaque type directly or through a
* chain of typedefs.
*/
bool referencesOpaqueType() const;

bool usesOpaqueType() const override;

using TypeAndName::replaceType;
bool isAliasForOpaqueType() const;

private:
/**
Expand Down
4 changes: 3 additions & 1 deletion bindgen/ir/VarDefine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s,
return s;
}

bool VarDefine::usesOpaqueType() const { return variable->usesOpaqueType(); }
bool VarDefine::hasIllegalUsageOfOpaqueType() const {
return variable->hasIllegalUsageOfOpaqueType();
}
Loading

0 comments on commit 072189c

Please sign in to comment.