]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/debug/dwarf/type.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.git] / libgo / go / debug / dwarf / type.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // DWARF type information structures.
6 // The format is heavily biased toward C, but for simplicity
7 // the String methods use a pseudo-Go syntax.
8
9 package dwarf
10
11 import (
12 "os"
13 "strconv"
14 )
15
16 // A Type conventionally represents a pointer to any of the
17 // specific Type structures (CharType, StructType, etc.).
18 type Type interface {
19 Common() *CommonType
20 String() string
21 Size() int64
22 }
23
24 // A CommonType holds fields common to multiple types.
25 // If a field is not known or not applicable for a given type,
26 // the zero value is used.
27 type CommonType struct {
28 ByteSize int64 // size of value of this type, in bytes
29 Name string // name that can be used to refer to type
30 }
31
32 func (c *CommonType) Common() *CommonType { return c }
33
34 func (c *CommonType) Size() int64 { return c.ByteSize }
35
36 // Basic types
37
38 // A BasicType holds fields common to all basic types.
39 type BasicType struct {
40 CommonType
41 BitSize int64
42 BitOffset int64
43 }
44
45 func (b *BasicType) Basic() *BasicType { return b }
46
47 func (t *BasicType) String() string {
48 if t.Name != "" {
49 return t.Name
50 }
51 return "?"
52 }
53
54 // A CharType represents a signed character type.
55 type CharType struct {
56 BasicType
57 }
58
59 // A UcharType represents an unsigned character type.
60 type UcharType struct {
61 BasicType
62 }
63
64 // An IntType represents a signed integer type.
65 type IntType struct {
66 BasicType
67 }
68
69 // A UintType represents an unsigned integer type.
70 type UintType struct {
71 BasicType
72 }
73
74 // A FloatType represents a floating point type.
75 type FloatType struct {
76 BasicType
77 }
78
79 // A ComplexType represents a complex floating point type.
80 type ComplexType struct {
81 BasicType
82 }
83
84 // A BoolType represents a boolean type.
85 type BoolType struct {
86 BasicType
87 }
88
89 // An AddrType represents a machine address type.
90 type AddrType struct {
91 BasicType
92 }
93
94 // qualifiers
95
96 // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
97 type QualType struct {
98 CommonType
99 Qual string
100 Type Type
101 }
102
103 func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
104
105 func (t *QualType) Size() int64 { return t.Type.Size() }
106
107 // An ArrayType represents a fixed size array type.
108 type ArrayType struct {
109 CommonType
110 Type Type
111 StrideBitSize int64 // if > 0, number of bits to hold each element
112 Count int64 // if == -1, an incomplete array, like char x[].
113 }
114
115 func (t *ArrayType) String() string {
116 return "[" + strconv.Itoa64(t.Count) + "]" + t.Type.String()
117 }
118
119 func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
120
121 // A VoidType represents the C void type.
122 type VoidType struct {
123 CommonType
124 }
125
126 func (t *VoidType) String() string { return "void" }
127
128 // A PtrType represents a pointer type.
129 type PtrType struct {
130 CommonType
131 Type Type
132 }
133
134 func (t *PtrType) String() string { return "*" + t.Type.String() }
135
136 // A StructType represents a struct, union, or C++ class type.
137 type StructType struct {
138 CommonType
139 StructName string
140 Kind string // "struct", "union", or "class".
141 Field []*StructField
142 Incomplete bool // if true, struct, union, class is declared but not defined
143 }
144
145 // A StructField represents a field in a struct, union, or C++ class type.
146 type StructField struct {
147 Name string
148 Type Type
149 ByteOffset int64
150 ByteSize int64
151 BitOffset int64 // within the ByteSize bytes at ByteOffset
152 BitSize int64 // zero if not a bit field
153 }
154
155 func (t *StructType) String() string {
156 if t.StructName != "" {
157 return t.Kind + " " + t.StructName
158 }
159 return t.Defn()
160 }
161
162 func (t *StructType) Defn() string {
163 s := t.Kind
164 if t.StructName != "" {
165 s += " " + t.StructName
166 }
167 if t.Incomplete {
168 s += " /*incomplete*/"
169 return s
170 }
171 s += " {"
172 for i, f := range t.Field {
173 if i > 0 {
174 s += "; "
175 }
176 s += f.Name + " " + f.Type.String()
177 s += "@" + strconv.Itoa64(f.ByteOffset)
178 if f.BitSize > 0 {
179 s += " : " + strconv.Itoa64(f.BitSize)
180 s += "@" + strconv.Itoa64(f.BitOffset)
181 }
182 }
183 s += "}"
184 return s
185 }
186
187 // An EnumType represents an enumerated type.
188 // The only indication of its native integer type is its ByteSize
189 // (inside CommonType).
190 type EnumType struct {
191 CommonType
192 EnumName string
193 Val []*EnumValue
194 }
195
196 // An EnumValue represents a single enumeration value.
197 type EnumValue struct {
198 Name string
199 Val int64
200 }
201
202 func (t *EnumType) String() string {
203 s := "enum"
204 if t.EnumName != "" {
205 s += " " + t.EnumName
206 }
207 s += " {"
208 for i, v := range t.Val {
209 if i > 0 {
210 s += "; "
211 }
212 s += v.Name + "=" + strconv.Itoa64(v.Val)
213 }
214 s += "}"
215 return s
216 }
217
218 // A FuncType represents a function type.
219 type FuncType struct {
220 CommonType
221 ReturnType Type
222 ParamType []Type
223 }
224
225 func (t *FuncType) String() string {
226 s := "func("
227 for i, t := range t.ParamType {
228 if i > 0 {
229 s += ", "
230 }
231 s += t.String()
232 }
233 s += ")"
234 if t.ReturnType != nil {
235 s += " " + t.ReturnType.String()
236 }
237 return s
238 }
239
240 // A DotDotDotType represents the variadic ... function parameter.
241 type DotDotDotType struct {
242 CommonType
243 }
244
245 func (t *DotDotDotType) String() string { return "..." }
246
247 // A TypedefType represents a named type.
248 type TypedefType struct {
249 CommonType
250 Type Type
251 }
252
253 func (t *TypedefType) String() string { return t.Name }
254
255 func (t *TypedefType) Size() int64 { return t.Type.Size() }
256
257 func (d *Data) Type(off Offset) (Type, os.Error) {
258 if t, ok := d.typeCache[off]; ok {
259 return t, nil
260 }
261
262 r := d.Reader()
263 r.Seek(off)
264 e, err := r.Next()
265 if err != nil {
266 return nil, err
267 }
268 if e == nil || e.Offset != off {
269 return nil, DecodeError{"info", off, "no type at offset"}
270 }
271
272 // Parse type from Entry.
273 // Must always set d.typeCache[off] before calling
274 // d.Type recursively, to handle circular types correctly.
275 var typ Type
276
277 // Get next child; set err if error happens.
278 next := func() *Entry {
279 if !e.Children {
280 return nil
281 }
282 kid, err1 := r.Next()
283 if err1 != nil {
284 err = err1
285 return nil
286 }
287 if kid == nil {
288 err = DecodeError{"info", r.b.off, "unexpected end of DWARF entries"}
289 return nil
290 }
291 if kid.Tag == 0 {
292 return nil
293 }
294 return kid
295 }
296
297 // Get Type referred to by Entry's AttrType field.
298 // Set err if error happens. Not having a type is an error.
299 typeOf := func(e *Entry) Type {
300 toff, ok := e.Val(AttrType).(Offset)
301 if !ok {
302 // It appears that no Type means "void".
303 return new(VoidType)
304 }
305 var t Type
306 if t, err = d.Type(toff); err != nil {
307 return nil
308 }
309 return t
310 }
311
312 switch e.Tag {
313 case TagArrayType:
314 // Multi-dimensional array. (DWARF v2 §5.4)
315 // Attributes:
316 // AttrType:subtype [required]
317 // AttrStrideSize: size in bits of each element of the array
318 // AttrByteSize: size of entire array
319 // Children:
320 // TagSubrangeType or TagEnumerationType giving one dimension.
321 // dimensions are in left to right order.
322 t := new(ArrayType)
323 typ = t
324 d.typeCache[off] = t
325 if t.Type = typeOf(e); err != nil {
326 goto Error
327 }
328 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
329
330 // Accumulate dimensions,
331 ndim := 0
332 for kid := next(); kid != nil; kid = next() {
333 // TODO(rsc): Can also be TagEnumerationType
334 // but haven't seen that in the wild yet.
335 switch kid.Tag {
336 case TagSubrangeType:
337 max, ok := kid.Val(AttrUpperBound).(int64)
338 if !ok {
339 max = -2 // Count == -1, as in x[].
340 }
341 if ndim == 0 {
342 t.Count = max + 1
343 } else {
344 // Multidimensional array.
345 // Create new array type underneath this one.
346 t.Type = &ArrayType{Type: t.Type, Count: max + 1}
347 }
348 ndim++
349 case TagEnumerationType:
350 err = DecodeError{"info", kid.Offset, "cannot handle enumeration type as array bound"}
351 goto Error
352 }
353 }
354 if ndim == 0 {
355 err = DecodeError{"info", e.Offset, "missing dimension for array"}
356 goto Error
357 }
358
359 case TagBaseType:
360 // Basic type. (DWARF v2 §5.1)
361 // Attributes:
362 // AttrName: name of base type in programming language of the compilation unit [required]
363 // AttrEncoding: encoding value for type (encFloat etc) [required]
364 // AttrByteSize: size of type in bytes [required]
365 // AttrBitOffset: for sub-byte types, size in bits
366 // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
367 name, _ := e.Val(AttrName).(string)
368 enc, ok := e.Val(AttrEncoding).(int64)
369 if !ok {
370 err = DecodeError{"info", e.Offset, "missing encoding attribute for " + name}
371 goto Error
372 }
373 switch enc {
374 default:
375 err = DecodeError{"info", e.Offset, "unrecognized encoding attribute value"}
376 goto Error
377
378 case encAddress:
379 typ = new(AddrType)
380 case encBoolean:
381 typ = new(BoolType)
382 case encComplexFloat:
383 typ = new(ComplexType)
384 case encFloat:
385 typ = new(FloatType)
386 case encSigned:
387 typ = new(IntType)
388 case encUnsigned:
389 typ = new(UintType)
390 case encSignedChar:
391 typ = new(CharType)
392 case encUnsignedChar:
393 typ = new(UcharType)
394 }
395 d.typeCache[off] = typ
396 t := typ.(interface {
397 Basic() *BasicType
398 }).Basic()
399 t.Name = name
400 t.BitSize, _ = e.Val(AttrBitSize).(int64)
401 t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
402
403 case TagClassType, TagStructType, TagUnionType:
404 // Structure, union, or class type. (DWARF v2 §5.5)
405 // Attributes:
406 // AttrName: name of struct, union, or class
407 // AttrByteSize: byte size [required]
408 // AttrDeclaration: if true, struct/union/class is incomplete
409 // Children:
410 // TagMember to describe one member.
411 // AttrName: name of member [required]
412 // AttrType: type of member [required]
413 // AttrByteSize: size in bytes
414 // AttrBitOffset: bit offset within bytes for bit fields
415 // AttrBitSize: bit size for bit fields
416 // AttrDataMemberLoc: location within struct [required for struct, class]
417 // There is much more to handle C++, all ignored for now.
418 t := new(StructType)
419 typ = t
420 d.typeCache[off] = t
421 switch e.Tag {
422 case TagClassType:
423 t.Kind = "class"
424 case TagStructType:
425 t.Kind = "struct"
426 case TagUnionType:
427 t.Kind = "union"
428 }
429 t.StructName, _ = e.Val(AttrName).(string)
430 t.Incomplete = e.Val(AttrDeclaration) != nil
431 t.Field = make([]*StructField, 0, 8)
432 for kid := next(); kid != nil; kid = next() {
433 if kid.Tag == TagMember {
434 f := new(StructField)
435 if f.Type = typeOf(kid); err != nil {
436 goto Error
437 }
438 if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok {
439 b := makeBuf(d, "location", 0, loc, d.addrsize)
440 if b.uint8() != opPlusUconst {
441 err = DecodeError{"info", kid.Offset, "unexpected opcode"}
442 goto Error
443 }
444 f.ByteOffset = int64(b.uint())
445 if b.err != nil {
446 err = b.err
447 goto Error
448 }
449 }
450 f.Name, _ = kid.Val(AttrName).(string)
451 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
452 f.BitOffset, _ = kid.Val(AttrBitOffset).(int64)
453 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
454 t.Field = append(t.Field, f)
455 }
456 }
457
458 case TagConstType, TagVolatileType, TagRestrictType:
459 // Type modifier (DWARF v2 §5.2)
460 // Attributes:
461 // AttrType: subtype
462 t := new(QualType)
463 typ = t
464 d.typeCache[off] = t
465 if t.Type = typeOf(e); err != nil {
466 goto Error
467 }
468 switch e.Tag {
469 case TagConstType:
470 t.Qual = "const"
471 case TagRestrictType:
472 t.Qual = "restrict"
473 case TagVolatileType:
474 t.Qual = "volatile"
475 }
476
477 case TagEnumerationType:
478 // Enumeration type (DWARF v2 §5.6)
479 // Attributes:
480 // AttrName: enum name if any
481 // AttrByteSize: bytes required to represent largest value
482 // Children:
483 // TagEnumerator:
484 // AttrName: name of constant
485 // AttrConstValue: value of constant
486 t := new(EnumType)
487 typ = t
488 d.typeCache[off] = t
489 t.EnumName, _ = e.Val(AttrName).(string)
490 t.Val = make([]*EnumValue, 0, 8)
491 for kid := next(); kid != nil; kid = next() {
492 if kid.Tag == TagEnumerator {
493 f := new(EnumValue)
494 f.Name, _ = kid.Val(AttrName).(string)
495 f.Val, _ = kid.Val(AttrConstValue).(int64)
496 n := len(t.Val)
497 if n >= cap(t.Val) {
498 val := make([]*EnumValue, n, n*2)
499 copy(val, t.Val)
500 t.Val = val
501 }
502 t.Val = t.Val[0 : n+1]
503 t.Val[n] = f
504 }
505 }
506
507 case TagPointerType:
508 // Type modifier (DWARF v2 §5.2)
509 // Attributes:
510 // AttrType: subtype [not required! void* has no AttrType]
511 // AttrAddrClass: address class [ignored]
512 t := new(PtrType)
513 typ = t
514 d.typeCache[off] = t
515 if e.Val(AttrType) == nil {
516 t.Type = &VoidType{}
517 break
518 }
519 t.Type = typeOf(e)
520
521 case TagSubroutineType:
522 // Subroutine type. (DWARF v2 §5.7)
523 // Attributes:
524 // AttrType: type of return value if any
525 // AttrName: possible name of type [ignored]
526 // AttrPrototyped: whether used ANSI C prototye [ignored]
527 // Children:
528 // TagFormalParameter: typed parameter
529 // AttrType: type of parameter
530 // TagUnspecifiedParameter: final ...
531 t := new(FuncType)
532 typ = t
533 d.typeCache[off] = t
534 if t.ReturnType = typeOf(e); err != nil {
535 goto Error
536 }
537 t.ParamType = make([]Type, 0, 8)
538 for kid := next(); kid != nil; kid = next() {
539 var tkid Type
540 switch kid.Tag {
541 default:
542 continue
543 case TagFormalParameter:
544 if tkid = typeOf(kid); err != nil {
545 goto Error
546 }
547 case TagUnspecifiedParameters:
548 tkid = &DotDotDotType{}
549 }
550 t.ParamType = append(t.ParamType, tkid)
551 }
552
553 case TagTypedef:
554 // Typedef (DWARF v2 §5.3)
555 // Attributes:
556 // AttrName: name [required]
557 // AttrType: type definition [required]
558 t := new(TypedefType)
559 typ = t
560 d.typeCache[off] = t
561 t.Name, _ = e.Val(AttrName).(string)
562 t.Type = typeOf(e)
563 }
564
565 if err != nil {
566 goto Error
567 }
568
569 b, ok := e.Val(AttrByteSize).(int64)
570 if !ok {
571 b = -1
572 }
573 typ.Common().ByteSize = b
574
575 return typ, nil
576
577 Error:
578 // If the parse fails, take the type out of the cache
579 // so that the next call with this offset doesn't hit
580 // the cache and return success.
581 d.typeCache[off] = nil, false
582 return nil, err
583 }