11#include " ir.h"
22#pragma warning(push, 0)
3+ #include < llvm/ADT/SmallString.h>
34#include < llvm/ADT/StringSet.h>
45#include < llvm/ADT/StringSwitch.h>
56#pragma warning(pop)
67#include " ../ast/decl.h"
78#include " ../ast/mangle.h"
9+ #include " ../ast/module.h"
810
911using namespace cx ;
1012
@@ -34,21 +36,39 @@ IRType* cx::getIRType(Type astType) {
3436
3537 if (enumDecl->hasAssociatedValues ()) {
3638 auto unionType = new IRUnionType{IRTypeKind::IRUnionType, {}, " " };
37- irType = new IRStructType{IRTypeKind::IRStructType, {tagType, unionType}, astType.getQualifiedTypeName (), ' _' + mangleType (astType), false };
39+ irType = new IRStructType{IRTypeKind::IRStructType,
40+ {IRField{tagType, " tag" }, IRField{unionType, " union" }},
41+ astType.getQualifiedTypeName (),
42+ ' _' + mangleType (astType),
43+ false ,
44+ false };
3845 irTypes.emplace (astType.getBase (), irType);
39- auto associatedTypes = map (enumDecl->cases , [](const EnumCase& c) { return getIRType (c.associatedType ); });
40- unionType->elementTypes = std::move (associatedTypes);
46+ auto associatedTypes = map (enumDecl->cases , [](const EnumCase& c) { return IRField{ getIRType (c.associatedType ), c. name } ; });
47+ unionType->fields = std::move (associatedTypes);
4148 return irType;
4249 } else {
4350 irType = tagType;
4451 }
45- } else if (astType.getDecl ()) {
46- auto structType =
47- new IRStructType{IRTypeKind::IRStructType, {}, astType.getQualifiedTypeName (), ' _' + mangleType (astType), astType.getDecl ()->packed };
48- irTypes.emplace (astType.getBase (), structType);
49- auto elementTypes = map (astType.getDecl ()->fields , [](const FieldDecl& f) { return getIRType (f.type ); });
50- structType->elementTypes = std::move (elementTypes);
51- return structType;
52+ } else if (auto decl = astType.getDecl ()) {
53+ if (decl->isUnion ()) {
54+ auto unionType = new IRUnionType{IRTypeKind::IRUnionType, {}, astType.getQualifiedTypeName ()};
55+ irTypes.emplace (astType.getBase (), unionType);
56+ // Fields are set late to handle recursive types.
57+ unionType->fields = map (decl->fields , [](const FieldDecl& f) { return IRField{getIRType (f.type ), f.name }; });
58+ return unionType;
59+ } else {
60+ bool isImportedFromC = decl->module .name .ends_with (" _h" );
61+ auto structType = new IRStructType{IRTypeKind::IRStructType,
62+ {},
63+ astType.getQualifiedTypeName (),
64+ isImportedFromC ? astType.getName ().str () : (' _' + mangleType (astType)),
65+ decl->packed ,
66+ isImportedFromC};
67+ irTypes.emplace (astType.getBase (), structType);
68+ // Fields are set late to handle recursive types.
69+ structType->fields = map (decl->fields , [](const FieldDecl& f) { return IRField{getIRType (f.type ), f.name }; });
70+ return structType;
71+ }
5272 } else {
5373 llvm_unreachable (StringBuilder () << " unknown type '" << astType << " '" );
5474 }
@@ -65,8 +85,8 @@ IRType* cx::getIRType(Type astType) {
6585 break ;
6686 }
6787 case TypeKind::TupleType: {
68- auto elementTypes = map (astType.getTupleElements (), [](const TupleElement& e) { return getIRType (e.type ); });
69- irType = new IRStructType{IRTypeKind::IRStructType, std::move (elementTypes ), std::string (), std::string (), false };
88+ auto fields = map (astType.getTupleElements (), [](const TupleElement& e) { return IRField{ getIRType (e.type ), e. name } ; });
89+ irType = new IRStructType{IRTypeKind::IRStructType, std::move (fields ), std::string (), std::string (), false , false };
7090 break ;
7191 }
7292 case TypeKind::FunctionType: {
@@ -114,7 +134,7 @@ IRType* Value::getType() const {
114134 return llvm::cast<InsertInst>(this )->aggregate ->getType ();
115135 case ValueKind::ExtractInst: {
116136 auto extract = llvm::cast<ExtractInst>(this );
117- return extract->aggregate ->getType ()->getElements ()[extract->index ];
137+ return extract->aggregate ->getType ()->getFields ()[extract->index ]. type ;
118138 }
119139 case ValueKind::CallInst: {
120140 auto functionType = llvm::cast<CallInst>(this )->function ->getType ();
@@ -171,8 +191,8 @@ IRType* Value::getType() const {
171191 auto baseType = gep->pointer ->getType ()->getPointee ();
172192 switch (baseType->kind ) {
173193 case IRTypeKind::IRStructType:
174- ASSERT (gep->index < baseType->getElements ().size ());
175- return baseType->getElements ()[gep->index ]->getPointerTo ();
194+ ASSERT (gep->index < baseType->getFields ().size ());
195+ return baseType->getFields ()[gep->index ]. type ->getPointerTo ();
176196 case IRTypeKind::IRArrayType:
177197 ASSERT (gep->index < baseType->getArraySize ());
178198 return baseType->getElementType ()->getPointerTo ();
@@ -605,9 +625,9 @@ IRType* IRType::getPointee() {
605625 return llvm::cast<IRPointerType>(this )->pointee ;
606626}
607627
608- llvm::ArrayRef<IRType* > IRType::getElements () {
609- if (isUnion ()) return llvm::cast<IRUnionType>(this )->elementTypes ;
610- return llvm::cast<IRStructType>(this )->elementTypes ;
628+ llvm::ArrayRef<IRField > IRType::getFields () {
629+ if (isUnion ()) return llvm::cast<IRUnionType>(this )->fields ;
630+ return llvm::cast<IRStructType>(this )->fields ;
611631}
612632
613633llvm::StringRef IRType::getName () {
@@ -659,10 +679,10 @@ llvm::raw_ostream& cx::operator<<(llvm::raw_ostream& stream, IRType* type) {
659679 if (type->getName () != " " ) {
660680 return stream << type->getName ();
661681 } else {
662- stream << " { " ;
663- for (auto & element : type->getElements ()) {
664- stream << element ;
665- if (&element != &type->getElements ().back ()) stream << " , " ;
682+ stream << " struct { " ;
683+ for (auto & field : type->getFields ()) {
684+ stream << field. type ;
685+ if (&field != &type->getFields ().back ()) stream << " , " ;
666686 }
667687 return stream << " }" ;
668688 }
@@ -672,13 +692,9 @@ llvm::raw_ostream& cx::operator<<(llvm::raw_ostream& stream, IRType* type) {
672692 return stream << type->getName ();
673693 } else {
674694 stream << " union { " ;
675- for (auto & element : type->getElements ()) {
676- if (element) { // TODO: Element type should exist for all associated values
677- stream << element;
678- } else {
679- stream << " void" ;
680- }
681- if (&element != &type->getElements ().back ()) stream << " , " ;
695+ for (auto & field : type->getFields ()) {
696+ stream << field.type ;
697+ if (&field != &type->getFields ().back ()) stream << " , " ;
682698 }
683699 return stream << " }" ;
684700 }
@@ -714,9 +730,9 @@ bool IRType::equals(IRType* other) {
714730 if (!other->isStruct ()) return false ;
715731 if (getName () != other->getName ()) return false ;
716732 if (getName ().empty ()) {
717- if (getElements ().size () != other->getElements ().size ()) return false ;
718- for (size_t i = 0 ; i < getElements ().size (); ++i) {
719- if (!getElements ()[i]->equals (other->getElements ()[i])) return false ;
733+ if (getFields ().size () != other->getFields ().size ()) return false ;
734+ for (size_t i = 0 ; i < getFields ().size (); ++i) {
735+ if (!getFields ()[i]. type ->equals (other->getFields ()[i]. type )) return false ;
720736 }
721737 }
722738 return true ;
0 commit comments