-
Notifications
You must be signed in to change notification settings - Fork 7
Handle opaque types #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5f1958d
9834ee7
c244c88
5c12773
7d1f079
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
|
@@ -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, | ||
|
@@ -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); | ||
} | ||
|
||
|
@@ -317,7 +333,6 @@ T IR::getDeclarationWithName(std::vector<T> &declarations, | |
return declaration; | ||
} | ||
} | ||
llvm::errs() << "Failed to get declaration for " << name << "\n"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we throw an exception here to avoid segfaults. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No,
I'll add comments about this to the code. |
||
return nullptr; | ||
} | ||
|
||
|
@@ -331,4 +346,4 @@ IR::~IR() { | |
possibleVarDefines.clear(); | ||
variables.clear(); | ||
varDefines.clear(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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)) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is std:: move needed here? My understanding is that ownership does not have to be explicitly transferred or is this an optimization? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, just a small optimization. |
||
|
||
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; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ class ArrayType : public Type { | |
public: | ||
ArrayType(std::shared_ptr<Type> elementsType, uint64_t size); | ||
|
||
~ArrayType() override; | ||
~ArrayType() override = default; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL |
||
|
||
bool usesType(std::shared_ptr<Type> type) const override; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
*/ | ||
class Type { | ||
public: | ||
virtual ~Type(); | ||
virtual ~Type() = default; | ||
|
||
virtual std::string str() const; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this for
static inline
functions?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it always used to return
nullptr
for function type, I just made it explicit.I found this declaration in libio.h:
That caused an error because
TypeDef
was created withnullptr
.Actually I am not aware of where function types may be used and what should we do with them. Maybe we should create an issue for investigating it.