@@ -552,8 +552,8 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
552
552
n .Const = fmt .Sprintf ("%#x" , enumVal [i ])
553
553
}
554
554
}
555
+ conv .FinishType (pos )
555
556
}
556
-
557
557
}
558
558
559
559
// mangleName does name mangling to translate names
@@ -926,6 +926,12 @@ type typeConv struct {
926
926
m map [dwarf.Type ]* Type
927
927
typedef map [string ]ast.Expr
928
928
929
+ // Map from types to incomplete pointers to those types.
930
+ ptrs map [dwarf.Type ][]* Type
931
+
932
+ // Fields to be processed by godefsField after completing pointers.
933
+ todoFlds [][]* ast.Field
934
+
929
935
// Predeclared types.
930
936
bool ast.Expr
931
937
byte ast.Expr // denotes padding
@@ -950,6 +956,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
950
956
c .ptrSize = ptrSize
951
957
c .intSize = intSize
952
958
c .m = make (map [dwarf.Type ]* Type )
959
+ c .ptrs = make (map [dwarf.Type ][]* Type )
953
960
c .bool = c .Ident ("bool" )
954
961
c .byte = c .Ident ("byte" )
955
962
c .int8 = c .Ident ("int8" )
@@ -1029,6 +1036,32 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
1029
1036
tr .FormatArgs = fargs
1030
1037
}
1031
1038
1039
+ // FinishType completes any outstanding type mapping work.
1040
+ // In particular, it resolves incomplete pointer types and also runs
1041
+ // godefsFields on any new struct types.
1042
+ func (c * typeConv ) FinishType (pos token.Pos ) {
1043
+ // Completing one pointer type might produce more to complete.
1044
+ // Keep looping until they're all done.
1045
+ for len (c .ptrs ) > 0 {
1046
+ for dtype := range c .ptrs {
1047
+ // Note Type might invalidate c.ptrs[dtype].
1048
+ t := c .Type (dtype , pos )
1049
+ for _ , ptr := range c .ptrs [dtype ] {
1050
+ ptr .Go .(* ast.StarExpr ).X = t .Go
1051
+ ptr .C .Set ("%s*" , t .C )
1052
+ }
1053
+ delete (c .ptrs , dtype )
1054
+ }
1055
+ }
1056
+
1057
+ // Now that pointer types are completed, we can invoke godefsFields
1058
+ // to rewrite struct definitions.
1059
+ for _ , fld := range c .todoFlds {
1060
+ godefsFields (fld )
1061
+ }
1062
+ c .todoFlds = nil
1063
+ }
1064
+
1032
1065
// Type returns a *Type with the same memory layout as
1033
1066
// dtype when used as the type of a variable or a struct field.
1034
1067
func (c * typeConv ) Type (dtype dwarf.Type , pos token.Pos ) * Type {
@@ -1068,13 +1101,12 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1068
1101
t .Go = c .Opaque (t .Size )
1069
1102
break
1070
1103
}
1071
- gt := & ast.ArrayType {
1072
- Len : c .intExpr (dt .Count ),
1073
- }
1074
- t .Go = gt // publish before recursive call
1075
1104
sub := c .Type (dt .Type , pos )
1076
1105
t .Align = sub .Align
1077
- gt .Elt = sub .Go
1106
+ t .Go = & ast.ArrayType {
1107
+ Len : c .intExpr (dt .Count ),
1108
+ Elt : sub .Go ,
1109
+ }
1078
1110
t .C .Set ("__typeof__(%s[%d])" , sub .C , dt .Count )
1079
1111
1080
1112
case * dwarf.BoolType :
@@ -1184,11 +1216,10 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1184
1216
break
1185
1217
}
1186
1218
1187
- gt := & ast.StarExpr {}
1188
- t .Go = gt // publish before recursive call
1189
- sub := c .Type (dt .Type , pos )
1190
- gt .X = sub .Go
1191
- t .C .Set ("%s*" , sub .C )
1219
+ // Placeholder initialization; completed in FinishType.
1220
+ t .Go = & ast.StarExpr {}
1221
+ t .C .Set ("<incomplete>*" )
1222
+ c .ptrs [dt .Type ] = append (c .ptrs [dt .Type ], t )
1192
1223
1193
1224
case * dwarf.QualType :
1194
1225
// Ignore qualifier.
@@ -1265,8 +1296,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1265
1296
}
1266
1297
name := c .Ident ("_Ctype_" + dt .Name )
1267
1298
goIdent [name .Name ] = name
1268
- t .Go = name // publish before recursive call
1269
1299
sub := c .Type (dt .Type , pos )
1300
+ t .Go = name
1270
1301
t .Size = sub .Size
1271
1302
t .Align = sub .Align
1272
1303
oldType := typedef [name .Name ]
@@ -1604,7 +1635,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
1604
1635
csyntax = buf .String ()
1605
1636
1606
1637
if * godefs || * cdefs {
1607
- godefsFields ( fld )
1638
+ c . todoFlds = append ( c . todoFlds , fld )
1608
1639
}
1609
1640
expr = & ast.StructType {Fields : & ast.FieldList {List : fld }}
1610
1641
return
0 commit comments