func (v *RecursiveDefinitionCheck) Visit(s *SemanticAnalyzer, n parser.Node) { var typ parser.Type if typeDecl, ok := n.(*parser.TypeDecl); ok { actualType := typeDecl.NamedType.ActualType() switch actualType.(type) { case *parser.EnumType: typ = actualType.(*parser.EnumType) case *parser.StructType: typ = actualType.(*parser.StructType) // TODO: Check tuple types once we add named types for everything default: return } } if ok, path := isTypeRecursive(typ); ok { s.Err(n, "Encountered recursive type definition") log.Errorln("semantic", "Path taken:") for _, typ := range path { log.Error("semantic", typ.TypeName()) log.Error("semantic", " <- ") } log.Error("semantic", "%s\n\n", typ.TypeName()) } }
func (v *Codegen) genDefaultValue(typ parser.Type) llvm.Value { typ = typ.ActualType() // Generate default struct values if structType, ok := typ.(*parser.StructType); ok { lit := createStructInitializer(structType) if lit != nil { return v.genStructLiteral(lit) } else { return llvm.Undef(v.typeToLLVMType(structType)) } } if tupleType, ok := typ.(*parser.TupleType); ok { values := make([]llvm.Value, len(tupleType.Members)) for idx, member := range tupleType.Members { values[idx] = v.genDefaultValue(member) } return llvm.ConstStruct(values, false) } if typ.IsIntegerType() || typ == parser.PRIMITIVE_bool { return llvm.ConstInt(v.typeToLLVMType(typ), 0, false) } if typ.IsFloatingType() { return llvm.ConstFloat(v.typeToLLVMType(typ), 0) } panic("type does not have default value: " + typ.TypeName()) }
func (v *RecursiveDefinitionCheck) Visit(s *SemanticAnalyzer, n parser.Node) { var typ parser.Type if typeDecl, ok := n.(*parser.TypeDecl); ok { typ = typeDecl.NamedType } else { return } if ok, path := isTypeRecursive(typ); ok { s.Err(n, "Encountered recursive type definition") log.Errorln("semantic", "Path taken:") for _, typ := range path { log.Error("semantic", typ.TypeName()) log.Error("semantic", " <- ") } log.Error("semantic", "%s\n\n", typ.TypeName()) } }
func (v *Codegen) typeToLLVMType(typ parser.Type) llvm.Type { switch typ := typ.(type) { case parser.PrimitiveType: return v.primitiveTypeToLLVMType(typ) case parser.FunctionType: return v.functionTypeToLLVMType(typ, true) case parser.StructType: return v.structTypeToLLVMType(typ) case parser.PointerType: return llvm.PointerType(v.typeToLLVMType(typ.Addressee), 0) case parser.ArrayType: return v.arrayTypeToLLVMType(typ) case parser.TupleType: return v.tupleTypeToLLVMType(typ) case parser.EnumType: return v.enumTypeToLLVMType(typ) case *parser.NamedType: nt := typ switch nt.Type.(type) { case parser.StructType, parser.EnumType: v.addNamedType(nt) lt := v.namedTypeLookup[nt.MangledName(parser.MANGLE_ARK_UNSTABLE)] return lt default: return v.typeToLLVMType(nt.Type) } case parser.MutableReferenceType: return llvm.PointerType(v.typeToLLVMType(typ.Referrer), 0) case parser.ConstantReferenceType: return llvm.PointerType(v.typeToLLVMType(typ.Referrer), 0) default: log.Debugln("codegen", "Type was %s (%s)", typ.TypeName(), reflect.TypeOf(typ)) panic("Unimplemented type category in LLVM codegen") } }