func (tm *LLVMTypeMap) structLLVMType(s *types.Struct) llvm.Type { // Types may be circular, so we need to first create an empty // struct type, then fill in its body after visiting its // members. sstr := s.String() typ, ok := tm.types[sstr] if !ok { typ = llvm.GlobalContext().StructCreateNamed("") tm.types[sstr] = typ elements := make([]llvm.Type, len(s.Fields)) for i, f := range s.Fields { ft := f.Type.(types.Type) elements[i] = tm.ToLLVM(ft) } typ.StructSetBody(elements, false) } return typ }
func (c *compiler) VisitStructType(s *ast.StructType) TypeValue { var typ = new(types.Struct) if s.Fields != nil && s.Fields.List != nil { tags := make(map[*ast.Object]string) var i int = 0 for _, field := range s.Fields.List { fieldtype := c.GetType(field.Type) if field.Names != nil { for _, name := range field.Names { obj := name.Obj if obj == nil { obj = ast.NewObj(ast.Var, "_") } obj.Type = fieldtype typ.Fields = append(typ.Fields, obj) if field.Tag != nil { tags[obj] = field.Tag.Value } } i += len(field.Names) } else { obj := ast.NewObj(ast.Var, "_") obj.Type = fieldtype typ.Fields = append(typ.Fields, obj) if field.Tag != nil { tags[obj] = field.Tag.Value } i++ } } typ.Tags = make([]string, len(typ.Fields)) for i, field := range typ.Fields { // TODO unquote string? typ.Tags[i] = tags[field] } } return TypeValue{typ} }