Skip to content

Commit

Permalink
Merge pull request #94 from kornilova-l/opaque-type
Browse files Browse the repository at this point in the history
Handle opaque types
  • Loading branch information
kornilova203 authored Jul 4, 2018
2 parents e2eab49 + 7d1f079 commit 753a512
Show file tree
Hide file tree
Showing 20 changed files with 159 additions and 78 deletions.
31 changes: 20 additions & 11 deletions bindgen/TypeTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ TypeTranslator::TypeTranslator(clang::ASTContext *ctx_, IR &ir)
typeMap["char32_t"] = "native.CChar32";
typeMap["float"] = "native.CFloat";
typeMap["double"] = "native.CDouble";
typeMap["long double"] = "native.CDouble";
}

std::shared_ptr<Type>
Expand Down Expand Up @@ -86,15 +87,23 @@ TypeTranslator::translatePointer(const clang::QualType &pte,
std::shared_ptr<Type>
TypeTranslator::translateStructOrUnionOrEnum(const clang::QualType &qtpe) {
std::string name = qtpe.getUnqualifiedType().getAsString();
std::string nameWithoutSpace = replaceChar(name, " ", "_");

auto it = aliasesMap.find(name);
if (it != aliasesMap.end()) {
/* name contains space: struct <name>.
* Use type alias instead struct type */
return (*it).second;
/* If the struct was already declared then there is a TypeDef instance
* with appropriate name.
*
* If there is no such TypeDef then the type is opaque and TypeDef with
* nullptr will be generated for the type. */

std::shared_ptr<TypeDef> typeDef = ir.getTypeDefWithName(nameWithoutSpace);
if (typeDef) {
return typeDef;
}
/* type has typedef alias */
return ir.getTypeDefWithName(name);
/* type is not yet defined.
* TypeDef with nullptr will be created.
* nullptr will be replaced by actual type when the type is declared. */
typeDef = ir.addTypeDef(nameWithoutSpace, nullptr);
return typeDef;
}

std::shared_ptr<Type>
Expand Down Expand Up @@ -138,6 +147,10 @@ std::shared_ptr<Type> TypeTranslator::translate(const clang::QualType &qtpe,
std::make_shared<PrimitiveType>("Byte"), sizeInBits / 8);
}

if (tpe->isFunctionType()) {
return nullptr;
}

if (tpe->isFunctionPointerType()) {
return translateFunctionPointer(qtpe, avoid);

Expand Down Expand Up @@ -171,10 +184,6 @@ std::shared_ptr<Type> TypeTranslator::translate(const clang::QualType &qtpe,
}
}

void TypeTranslator::addAlias(std::string cName, std::shared_ptr<Type> type) {
aliasesMap[cName] = type;
}

std::string TypeTranslator::getTypeFromTypeMap(std::string cType) {
auto it = typeMap.find(cType);
if (it != typeMap.end()) {
Expand Down
9 changes: 1 addition & 8 deletions bindgen/TypeTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ class TypeTranslator {
* @param tpe The type to translate
* @param avoid A type to avoid, useful to avoid cyclic definitions inside
* structs, unions, ...
* @return the type translated
* @return the type translated or nullptr if type is function type.
*/
std::shared_ptr<Type> translate(const clang::QualType &tpe,
const std::string * = nullptr);

void addAlias(std::string cName, std::shared_ptr<Type> type);

std::string getTypeFromTypeMap(std::string cType);

private:
Expand All @@ -30,11 +28,6 @@ class TypeTranslator {
*/
std::map<std::string, std::string> typeMap;

/**
* Maps C struct, union or enum name to Type alias
*/
std::map<std::string, std::shared_ptr<Type>> aliasesMap;

std::shared_ptr<Type>
translateStructOrUnionOrEnum(const clang::QualType &qtpe);

Expand Down
10 changes: 10 additions & 0 deletions bindgen/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ template <typename T, typename PT> static inline bool isInstanceOf(PT *type) {
return p != nullptr;
}

static inline std::string replaceChar(const std::string &str,
const std::string &c1,
const std::string &c2) {
auto f = str.find(c1);
if (f != std::string::npos) {
return std::string(str).replace(f, c1.length(), c2);
}
return std::string(str);
}

/**
* Types may be wrapper in a chain of typedefs.
* @return true if given type is of type T or is an alias for type T.
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Parameter::Parameter(std::string name, std::shared_ptr<Type> type)
Function::Function(const std::string &name, std::vector<Parameter *> parameters,
std::shared_ptr<Type> retType, bool isVariadic)
: name(name), scalaName(name), parameters(std::move(parameters)),
retType(retType), isVariadic(isVariadic) {}
retType(std::move(retType)), isVariadic(isVariadic) {}

llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const Function &func) {
if (func.scalaName != func.name) {
Expand Down
43 changes: 29 additions & 14 deletions bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ void IR::addFunction(std::string name, std::vector<Parameter *> parameters,
retType, isVariadic));
}

void IR::addTypeDef(std::string name, std::shared_ptr<Type> type) {
std::shared_ptr<TypeDef> IR::addTypeDef(std::string name,
std::shared_ptr<Type> type) {
typeDefs.push_back(std::make_shared<TypeDef>(std::move(name), type));
return typeDefs.back();
}

std::shared_ptr<Type> IR::addEnum(std::string name, const std::string &type,
Expand All @@ -28,23 +30,32 @@ std::shared_ptr<Type> IR::addEnum(std::string name, const std::string &type,
return nullptr;
}

std::shared_ptr<Type> IR::addStruct(std::string name,
std::vector<Field *> fields,
uint64_t typeSize) {
void IR::addStruct(std::string name, std::vector<Field *> fields,
uint64_t typeSize) {
std::shared_ptr<Struct> s =
std::make_shared<Struct>(std::move(name), std::move(fields), typeSize);
std::make_shared<Struct>(name, std::move(fields), typeSize);
structs.push_back(s);
typeDefs.push_back(s->generateTypeDef());
return typeDefs.back();
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("struct_" + name);
if (typeDef) {
/* the struct type used to be opaque type, typeDef contains nullptr */
typeDef.get()->setType(s);
} else {
typeDefs.push_back(s->generateTypeDef());
}
}

std::shared_ptr<Type>
IR::addUnion(std::string name, std::vector<Field *> fields, uint64_t maxSize) {
void IR::addUnion(std::string name, std::vector<Field *> fields,
uint64_t maxSize) {
std::shared_ptr<Union> u =
std::make_shared<Union>(std::move(name), std::move(fields), maxSize);
std::make_shared<Union>(name, std::move(fields), maxSize);
unions.push_back(u);
typeDefs.push_back(u->generateTypeDef());
return typeDefs.back();
std::shared_ptr<TypeDef> typeDef = getTypeDefWithName("union_" + name);
if (typeDef) {
/* the union type used to be opaque type, typeDef contains nullptr */
typeDef.get()->setType(u);
} else {
typeDefs.push_back(u->generateTypeDef());
}
}

void IR::addLiteralDefine(std::string name, std::string literal,
Expand Down Expand Up @@ -304,6 +315,11 @@ std::shared_ptr<Variable> IR::addVariable(const std::string &name,
}

std::shared_ptr<TypeDef> IR::getTypeDefWithName(const std::string &name) {
/* nullptr is returned in 2 cases:
* 1. TypeTranslator translates opaque struct/union type for which TypeDef
* was not created.
* 2. TreeVisitor visits struct/union declaration and it checks whether a
* TypeDef already exists for it.*/
return getDeclarationWithName(typeDefs, name);
}

Expand All @@ -317,7 +333,6 @@ T IR::getDeclarationWithName(std::vector<T> &declarations,
return declaration;
}
}
llvm::errs() << "Failed to get declaration for " << name << "\n";
return nullptr;
}

Expand All @@ -331,4 +346,4 @@ IR::~IR() {
possibleVarDefines.clear();
variables.clear();
varDefines.clear();
}
}
19 changes: 6 additions & 13 deletions bindgen/ir/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,20 @@ class IR {
void addFunction(std::string name, std::vector<Parameter *> parameters,
std::shared_ptr<Type> retType, bool isVariadic);

void addTypeDef(std::string name, std::shared_ptr<Type> type);
std::shared_ptr<TypeDef> addTypeDef(std::string name,
std::shared_ptr<Type> type);

/**
* @return type alias for the enum
*/
std::shared_ptr<Type> addEnum(std::string name, const std::string &type,
std::vector<Enumerator> enumerators);

/**
* @return type alias for the struct
*/
std::shared_ptr<Type>
addStruct(std::string name, std::vector<Field *> fields, uint64_t typeSize);
void addStruct(std::string name, std::vector<Field *> fields,
uint64_t typeSize);

/**
* @return type alias for the union
*/
std::shared_ptr<Type>
addUnion(std::string name, std::vector<Field *> fields, uint64_t maxSize);
void addUnion(std::string name, std::vector<Field *> fields,
uint64_t maxSize);

void addLiteralDefine(std::string name, std::string literal,
std::shared_ptr<Type> type);
Expand Down Expand Up @@ -138,8 +133,6 @@ class IR {
T getDeclarationWithName(std::vector<T> &declarations,
const std::string &name);

template <typename T> void clearVector(std::vector<T> v);

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
1 change: 0 additions & 1 deletion bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "types/ArrayType.h"
#include "types/PrimitiveType.h"
#include <sstream>
#include <utility>

Field::Field(std::string name, std::shared_ptr<Type> type)
: TypeAndName(std::move(name), std::move(type)) {}
Expand Down
2 changes: 1 addition & 1 deletion bindgen/ir/TypeAndName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <clang/Tooling/Tooling.h>

TypeAndName::TypeAndName(std::string name, std::shared_ptr<Type> type)
: name(std::move(name)), type(type) {}
: name(std::move(name)), type(std::move(type)) {}

std::shared_ptr<Type> TypeAndName::getType() const { return type; }

Expand Down
8 changes: 7 additions & 1 deletion bindgen/ir/TypeDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
#include "../Utils.h"

TypeDef::TypeDef(std::string name, std::shared_ptr<Type> type)
: TypeAndName(std::move(name), type) {}
: TypeAndName(std::move(name), std::move(type)) {}

llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const TypeDef &typeDef) {
if (!typeDef.getType()) {
llvm::errs() << "Error: type declaration for " << typeDef.getName()
<< " was not found.\n";
llvm::errs().flush();
return s;
}
s << " type " + handleReservedWords(typeDef.name) + " = " +
typeDef.getType()->str() + "\n";
return s;
Expand Down
4 changes: 1 addition & 3 deletions bindgen/ir/types/ArrayType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "../../Utils.h"

ArrayType::ArrayType(std::shared_ptr<Type> elementsType, uint64_t size)
: size(size), elementsType(elementsType) {}
: size(size), elementsType(std::move(elementsType)) {}

std::string ArrayType::str() const {
return "native.CArray[" + elementsType->str() + ", " +
Expand All @@ -12,5 +12,3 @@ std::string ArrayType::str() const {
bool ArrayType::usesType(std::shared_ptr<Type> type) const {
return this == type.get() || elementsType == type;
}

ArrayType::~ArrayType() {}
2 changes: 1 addition & 1 deletion bindgen/ir/types/ArrayType.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class ArrayType : public Type {
public:
ArrayType(std::shared_ptr<Type> elementsType, uint64_t size);

~ArrayType() override;
~ArrayType() override = default;

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

Expand Down
6 changes: 2 additions & 4 deletions bindgen/ir/types/FunctionPointerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
FunctionPointerType::FunctionPointerType(
std::shared_ptr<Type> returnType,
const std::vector<std::shared_ptr<Type>> &parametersTypes, bool isVariadic)
: returnType(returnType), parametersTypes(parametersTypes),
: returnType(std::move(returnType)), parametersTypes(parametersTypes),
isVariadic(isVariadic) {}

std::string FunctionPointerType::str() const {
Expand All @@ -30,12 +30,10 @@ bool FunctionPointerType::usesType(std::shared_ptr<Type> type) const {
return true;
}

for (auto parameterType : parametersTypes) {
for (const auto &parameterType : parametersTypes) {
if (parameterType == type) {
return true;
}
}
return false;
}

FunctionPointerType::~FunctionPointerType() {}
2 changes: 1 addition & 1 deletion bindgen/ir/types/FunctionPointerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class FunctionPointerType : public Type {
const std::vector<std::shared_ptr<Type>> &parametersTypes,
bool isVariadic);

~FunctionPointerType() override;
~FunctionPointerType() override = default;

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

Expand Down
4 changes: 1 addition & 3 deletions bindgen/ir/types/PointerType.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "PointerType.h"

PointerType::PointerType(std::shared_ptr<Type> type) : type(type) {}
PointerType::PointerType(std::shared_ptr<Type> type) : type(std::move(type)) {}

std::string PointerType::str() const {
return "native.Ptr[" + type->str() + "]";
Expand All @@ -12,5 +12,3 @@ bool PointerType::usesType(std::shared_ptr<Type> type) const {
}
return this->type == type;
}

PointerType::~PointerType() {}
2 changes: 1 addition & 1 deletion bindgen/ir/types/PointerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class PointerType : public Type {
public:
explicit PointerType(std::shared_ptr<Type> type);

~PointerType() override;
~PointerType() override = default;

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

Expand Down
2 changes: 0 additions & 2 deletions bindgen/ir/types/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@
std::string Type::str() const { return ""; }

bool Type::usesType(std::shared_ptr<Type> type) const { return false; }

Type::~Type() = default;
2 changes: 1 addition & 1 deletion bindgen/ir/types/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
class Type {
public:
virtual ~Type();
virtual ~Type() = default;

virtual std::string str() const;

Expand Down
Loading

0 comments on commit 753a512

Please sign in to comment.