2626#include < cxx/literals.h>
2727#include < cxx/memory_layout.h>
2828#include < cxx/names.h>
29+ #include < cxx/scope.h>
2930#include < cxx/symbols.h>
3031#include < cxx/translation_unit.h>
3132#include < cxx/types.h>
3233
34+ #include < format>
35+
3336namespace cxx {
3437
3538struct Codegen ::ConvertType {
@@ -40,6 +43,7 @@ struct Codegen::ConvertType {
4043
4144 auto getExprType () const -> mlir::Type;
4245 auto getIntType (const Type* type, bool isSigned) -> mlir::Type;
46+ auto getFloatType (const Type* type) -> mlir::Type;
4347
4448 auto operator ()(const VoidType* type) -> mlir::Type;
4549 auto operator ()(const NullptrType* type) -> mlir::Type;
@@ -106,6 +110,11 @@ auto Codegen::ConvertType::getIntType(const Type* type, bool isSigned)
106110 return gen.builder_ .getType <mlir::cxx::IntegerType>(width, isSigned);
107111}
108112
113+ auto Codegen::ConvertType::getFloatType (const Type* type) -> mlir::Type {
114+ return gen.builder_ .getType <mlir::cxx::FloatType>(
115+ memoryLayout ()->sizeOf (type).value () * 8 );
116+ }
117+
109118auto Codegen::ConvertType::operator ()(const VoidType* type) -> mlir::Type {
110119 return gen.builder_ .getType <mlir::cxx::VoidType>();
111120}
@@ -205,16 +214,16 @@ auto Codegen::ConvertType::operator()(const WideCharType* type) -> mlir::Type {
205214}
206215
207216auto Codegen::ConvertType::operator ()(const FloatType* type) -> mlir::Type {
208- return gen. builder_ . getF32Type ( );
217+ return getFloatType (type );
209218}
210219
211220auto Codegen::ConvertType::operator ()(const DoubleType* type) -> mlir::Type {
212- return gen. builder_ . getF64Type ( );
221+ return getFloatType (type );
213222}
214223
215224auto Codegen::ConvertType::operator ()(const LongDoubleType* type)
216225 -> mlir::Type {
217- return getExprType ( );
226+ return getFloatType (type );
218227}
219228
220229auto Codegen::ConvertType::operator ()(const QualType* type) -> mlir::Type {
@@ -223,12 +232,14 @@ auto Codegen::ConvertType::operator()(const QualType* type) -> mlir::Type {
223232
224233auto Codegen::ConvertType::operator ()(const BoundedArrayType* type)
225234 -> mlir::Type {
226- return getExprType ();
235+ auto elementType = gen.convertType (type->elementType ());
236+ return gen.builder_ .getType <mlir::cxx::ArrayType>(elementType, type->size ());
227237}
228238
229239auto Codegen::ConvertType::operator ()(const UnboundedArrayType* type)
230240 -> mlir::Type {
231- return getExprType ();
241+ auto elementType = gen.convertType (type->elementType ());
242+ return gen.builder_ .getType <mlir::cxx::PointerType>(elementType);
232243}
233244
234245auto Codegen::ConvertType::operator ()(const PointerType* type) -> mlir::Type {
@@ -251,7 +262,38 @@ auto Codegen::ConvertType::operator()(const FunctionType* type) -> mlir::Type {
251262}
252263
253264auto Codegen::ConvertType::operator ()(const ClassType* type) -> mlir::Type {
254- return getExprType ();
265+ auto classSymbol = type->symbol ();
266+
267+ auto ctx = gen.builder_ .getContext ();
268+
269+ if (auto it = gen.classNames_ .find (classSymbol);
270+ it != gen.classNames_ .end ()) {
271+ return mlir::cxx::ClassType::get (ctx, it->second , {});
272+ }
273+
274+ auto name = to_string (classSymbol->name ());
275+ if (name.empty ()) {
276+ auto loc = type->symbol ()->location ();
277+ name = std::format (" $class_{}" , loc.index ());
278+ }
279+
280+ gen.classNames_ [classSymbol] = name;
281+
282+ // todo: layout of parent classes, anonymous nested fields, etc.
283+
284+ std::vector<mlir::Type> memberTypes;
285+
286+ for (auto member : classSymbol->scope ()->symbols ()) {
287+ auto field = symbol_cast<FieldSymbol>(member);
288+ if (!field) continue ;
289+ if (field->isStatic ()) continue ;
290+ auto memberType = gen.convertType (member->type ());
291+ memberTypes.push_back (memberType);
292+ }
293+
294+ auto classType = mlir::cxx::ClassType::get (ctx, name, memberTypes);
295+
296+ return classType;
255297}
256298
257299auto Codegen::ConvertType::operator ()(const EnumType* type) -> mlir::Type {
0 commit comments