Esempio n. 1
0
func (v *Codegen) addNamedTypeReference(n *ast.TypeReference, gcon *ast.GenericContext) {
	outer := gcon
	gcon = ast.NewGenericContextFromTypeReference(n)
	gcon.Outer = outer

	v.addNamedType(n.BaseType.(*ast.NamedType), ast.TypeReferenceMangledName(ast.MANGLE_ARK_UNSTABLE, n, gcon), gcon)
}
Esempio n. 2
0
func (v *Codegen) typeRefToLLVMTypeWithGenericContext(typ *ast.TypeReference, gcon *ast.GenericContext) llvm.Type {
	switch nt := typ.BaseType.(type) {
	case *ast.NamedType:
		switch nt.ActualType().(type) {
		case ast.StructType, ast.EnumType:
			v.addNamedTypeReference(typ, gcon)
			lt := v.namedTypeLookup[ast.TypeReferenceMangledName(ast.MANGLE_ARK_UNSTABLE, typ, gcon)]
			return lt

		default:
			return v.typeToLLVMType(nt.Type, gcon)
		}
	}

	return v.typeToLLVMType(typ.BaseType, gcon)
}
Esempio n. 3
0
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")
	}
}
Esempio n. 4
0
func (v *Codegen) addEnumType(typ ast.EnumType, name string, gcon *ast.GenericContext) {
	if _, ok := v.namedTypeLookup[name]; ok {
		return
	}

	if typ.Simple {
		// TODO: Handle other integer size, maybe dynamic depending on max value?
		v.namedTypeLookup[name] = llvm.IntType(32)
	} else {
		enum := v.curFile.LlvmModule.Context().StructCreateNamed(name)
		v.namedTypeLookup[name] = enum

		for _, member := range typ.Members {
			if named, ok := member.Type.(*ast.NamedType); ok {
				v.addNamedType(named, ast.TypeReferenceMangledName(ast.MANGLE_ARK_UNSTABLE, &ast.TypeReference{BaseType: member.Type}, gcon), gcon)
			}
		}

		enum.StructSetBody(v.enumTypeToLLVMTypeFields(typ, gcon), false)
	}
}