func (v *Codegen) functionTypeToLLVMType(typ ast.FunctionType, ptr bool, gcon *ast.GenericContext) llvm.Type { numOfParams := len(typ.Parameters) if typ.Receiver != nil { numOfParams++ } params := make([]llvm.Type, 0, numOfParams) if typ.Receiver != nil { params = append(params, v.typeRefToLLVMTypeWithOuter(typ.Receiver, gcon)) } for _, par := range typ.Parameters { params = append(params, v.typeRefToLLVMTypeWithOuter(par, gcon)) } var returnType llvm.Type // oo theres a type, let's try figure it out if typ.Return != nil { returnType = v.typeRefToLLVMTypeWithOuter(typ.Return, gcon) } else { returnType = llvm.VoidType() } // create the function type funcType := llvm.FunctionType(returnType, params, typ.IsVariadic) if ptr { funcType = llvm.PointerType(funcType, 0) } return funcType }
func (v *Codegen) typeToLLVMType(typ ast.Type, gcon *ast.GenericContext) llvm.Type { switch typ := typ.(type) { case ast.PrimitiveType: return v.primitiveTypeToLLVMType(typ) case ast.FunctionType: return v.functionTypeToLLVMType(typ, true, gcon) case ast.StructType: return v.structTypeToLLVMType(typ, gcon) case ast.PointerType: return llvm.PointerType(v.typeRefToLLVMTypeWithOuter(typ.Addressee, gcon), 0) case ast.ArrayType: return v.arrayTypeToLLVMType(typ, gcon) case ast.TupleType: return v.tupleTypeToLLVMType(typ, gcon) case ast.EnumType: return v.enumTypeToLLVMType(typ, gcon) case ast.ReferenceType: return llvm.PointerType(v.typeRefToLLVMTypeWithOuter(typ.Referrer, gcon), 0) case *ast.NamedType: switch typ.Type.(type) { case ast.StructType, ast.EnumType: // If something seems wrong with the code and thie problems seems to come from here, // make sure the type doesn't need generics arguments as well. // This here ignores them. name := ast.TypeReferenceMangledName(ast.MANGLE_ARK_UNSTABLE, &ast.TypeReference{BaseType: typ}, gcon) v.addNamedType(typ, name, gcon) lt := v.namedTypeLookup[name] return lt default: return v.typeToLLVMType(typ.Type, gcon) } case *ast.SubstitutionType: if gcon == nil { panic("gcon == nil when getting substitution type") } if gcon.GetSubstitutionType(typ) == nil { panic("missing generic map entry for type " + typ.TypeName() + " " + fmt.Sprintf("(%p)", typ)) } return v.typeRefToLLVMTypeWithOuter(gcon.GetSubstitutionType(typ), gcon) default: log.Debugln("codegen", "Type was %s (%s)", typ.TypeName(), reflect.TypeOf(typ)) panic("Unimplemented type category in LLVM codegen") } }
func (v *Codegen) arrayTypeToLLVMType(typ ast.ArrayType, gcon *ast.GenericContext) llvm.Type { memType := v.typeRefToLLVMTypeWithOuter(typ.MemberType, gcon) if typ.IsFixedLength { return llvm.ArrayType(memType, typ.Length) } else { fields := []llvm.Type{v.primitiveTypeToLLVMType(ast.PRIMITIVE_uint), llvm.PointerType(memType, 0)} return llvm.StructType(fields, false) } }