LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // DWARF type information structures. | 5 // DWARF type information structures. |
6 // The format is heavily biased toward C, but for simplicity | 6 // The format is heavily biased toward C, but for simplicity |
7 // the String methods use a pseudo-Go syntax. | 7 // the String methods use a pseudo-Go syntax. |
8 | 8 |
9 package dwarf | 9 package dwarf |
10 | 10 |
11 import "strconv" | 11 import ( |
| 12 » "reflect" |
| 13 » "strconv" |
| 14 ) |
12 | 15 |
13 // A Type conventionally represents a pointer to any of the | 16 // A Type conventionally represents a pointer to any of the |
14 // specific Type structures (CharType, StructType, etc.). | 17 // specific Type structures (CharType, StructType, etc.). |
15 type Type interface { | 18 type Type interface { |
16 Common() *CommonType | 19 Common() *CommonType |
17 String() string | 20 String() string |
18 Size() int64 | 21 Size() int64 |
19 } | 22 } |
20 | 23 |
21 // A CommonType holds fields common to multiple types. | 24 // A CommonType holds fields common to multiple types. |
22 // If a field is not known or not applicable for a given type, | 25 // If a field is not known or not applicable for a given type, |
23 // the zero value is used. | 26 // the zero value is used. |
24 type CommonType struct { | 27 type CommonType struct { |
25 » ByteSize int64 // size of value of this type, in bytes | 28 » ByteSize int64 // size of value of this type, in bytes |
26 » Name string // name that can be used to refer to type | 29 » Name string // name that can be used to refer to type |
| 30 » ReflectKind reflect.Kind // the reflect kind of the type. |
27 } | 31 } |
28 | 32 |
29 func (c *CommonType) Common() *CommonType { return c } | 33 func (c *CommonType) Common() *CommonType { return c } |
30 | 34 |
31 func (c *CommonType) Size() int64 { return c.ByteSize } | 35 func (c *CommonType) Size() int64 { return c.ByteSize } |
32 | 36 |
33 // Basic types | 37 // Basic types |
34 | 38 |
35 // A BasicType holds fields common to all basic types. | 39 // A BasicType holds fields common to all basic types. |
36 type BasicType struct { | 40 type BasicType struct { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 s += "@" + strconv.FormatInt(f.ByteOffset, 10) | 178 s += "@" + strconv.FormatInt(f.ByteOffset, 10) |
175 if f.BitSize > 0 { | 179 if f.BitSize > 0 { |
176 s += " : " + strconv.FormatInt(f.BitSize, 10) | 180 s += " : " + strconv.FormatInt(f.BitSize, 10) |
177 s += "@" + strconv.FormatInt(f.BitOffset, 10) | 181 s += "@" + strconv.FormatInt(f.BitOffset, 10) |
178 } | 182 } |
179 } | 183 } |
180 s += "}" | 184 s += "}" |
181 return s | 185 return s |
182 } | 186 } |
183 | 187 |
| 188 // A SliceType represents a Go slice type. It looks like a StructType, describin
g |
| 189 // the runtime-internal structure, with extra fields. |
| 190 type SliceType struct { |
| 191 StructType |
| 192 ElemType Type |
| 193 } |
| 194 |
| 195 func (t *SliceType) String() string { |
| 196 if t.Name != "" { |
| 197 return t.Name |
| 198 } |
| 199 return "[]" + t.ElemType.String() |
| 200 } |
| 201 |
| 202 // A StringType represents a Go string type. It looks like a StructType, describ
ing |
| 203 // the runtime-internal structure, but we wrap it for neatness. |
| 204 type StringType struct { |
| 205 StructType |
| 206 } |
| 207 |
| 208 func (t *StringType) String() string { |
| 209 if t.Name != "" { |
| 210 return t.Name |
| 211 } |
| 212 return "string" |
| 213 } |
| 214 |
184 // An EnumType represents an enumerated type. | 215 // An EnumType represents an enumerated type. |
185 // The only indication of its native integer type is its ByteSize | 216 // The only indication of its native integer type is its ByteSize |
186 // (inside CommonType). | 217 // (inside CommonType). |
187 type EnumType struct { | 218 type EnumType struct { |
188 CommonType | 219 CommonType |
189 EnumName string | 220 EnumName string |
190 Val []*EnumValue | 221 Val []*EnumValue |
191 } | 222 } |
192 | 223 |
193 // An EnumValue represents a single enumeration value. | 224 // An EnumValue represents a single enumeration value. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 274 |
244 // A TypedefType represents a named type. | 275 // A TypedefType represents a named type. |
245 type TypedefType struct { | 276 type TypedefType struct { |
246 CommonType | 277 CommonType |
247 Type Type | 278 Type Type |
248 } | 279 } |
249 | 280 |
250 func (t *TypedefType) String() string { return t.Name } | 281 func (t *TypedefType) String() string { return t.Name } |
251 | 282 |
252 func (t *TypedefType) Size() int64 { return t.Type.Size() } | 283 func (t *TypedefType) Size() int64 { return t.Type.Size() } |
| 284 |
| 285 // A MapType represents a Go slice type. It looks like a TypedefType, describing |
| 286 // the runtime-internal structure, with extra fields. |
| 287 type MapType struct { |
| 288 TypedefType |
| 289 KeyType Type |
| 290 ElemType Type |
| 291 } |
| 292 |
| 293 func (t *MapType) String() string { |
| 294 if t.Name != "" { |
| 295 return t.Name |
| 296 } |
| 297 return "map[" + t.KeyType.String() + "]" + t.ElemType.String() |
| 298 } |
253 | 299 |
254 // typeReader is used to read from either the info section or the | 300 // typeReader is used to read from either the info section or the |
255 // types section. | 301 // types section. |
256 type typeReader interface { | 302 type typeReader interface { |
257 Seek(Offset) | 303 Seek(Offset) |
258 Next() (*Entry, error) | 304 Next() (*Entry, error) |
259 clone() typeReader | 305 clone() typeReader |
260 offset() Offset | 306 offset() Offset |
261 } | 307 } |
262 | 308 |
263 // Type reads the type at off in the DWARF ``info'' section. | 309 // Type reads the type at off in the DWARF ``info'' section. |
264 func (d *Data) Type(off Offset) (Type, error) { | 310 func (d *Data) Type(off Offset) (Type, error) { |
265 return d.readType("info", d.Reader(), off, d.typeCache) | 311 return d.readType("info", d.Reader(), off, d.typeCache) |
| 312 } |
| 313 |
| 314 func getKind(e *Entry) reflect.Kind { |
| 315 integer, _ := e.Val(AttrGoKind).(int64) |
| 316 return reflect.Kind(integer) |
266 } | 317 } |
267 | 318 |
268 // readType reads a type from r at off of name using and updating a | 319 // readType reads a type from r at off of name using and updating a |
269 // type cache. | 320 // type cache. |
270 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
set]Type) (Type, error) { | 321 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
set]Type) (Type, error) { |
271 if t, ok := typeCache[off]; ok { | 322 if t, ok := typeCache[off]; ok { |
272 return t, nil | 323 return t, nil |
273 } | 324 } |
274 r.Seek(off) | 325 r.Seek(off) |
275 e, err := r.Next() | 326 e, err := r.Next() |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if kid.Children { | 368 if kid.Children { |
318 nextDepth++ | 369 nextDepth++ |
319 } | 370 } |
320 if nextDepth > 0 { | 371 if nextDepth > 0 { |
321 continue | 372 continue |
322 } | 373 } |
323 return kid | 374 return kid |
324 } | 375 } |
325 } | 376 } |
326 | 377 |
327 » // Get Type referred to by Entry's AttrType field. | 378 » // Get Type referred to by Entry's attr. |
328 // Set err if error happens. Not having a type is an error. | 379 // Set err if error happens. Not having a type is an error. |
329 » typeOf := func(e *Entry) Type { | 380 » typeOf := func(e *Entry, attr Attr) Type { |
330 » » tval := e.Val(AttrType) | 381 » » tval := e.Val(attr) |
331 var t Type | 382 var t Type |
332 switch toff := tval.(type) { | 383 switch toff := tval.(type) { |
333 case Offset: | 384 case Offset: |
334 if t, err = d.readType(name, r.clone(), toff, typeCache)
; err != nil { | 385 if t, err = d.readType(name, r.clone(), toff, typeCache)
; err != nil { |
335 return nil | 386 return nil |
336 } | 387 } |
337 case uint64: | 388 case uint64: |
338 if t, err = d.sigToType(toff); err != nil { | 389 if t, err = d.sigToType(toff); err != nil { |
339 return nil | 390 return nil |
340 } | 391 } |
341 default: | 392 default: |
342 // It appears that no Type means "void". | 393 // It appears that no Type means "void". |
343 return new(VoidType) | 394 return new(VoidType) |
344 } | 395 } |
345 return t | 396 return t |
346 } | 397 } |
347 | 398 |
348 switch e.Tag { | 399 switch e.Tag { |
349 case TagArrayType: | 400 case TagArrayType: |
350 // Multi-dimensional array. (DWARF v2 §5.4) | 401 // Multi-dimensional array. (DWARF v2 §5.4) |
351 // Attributes: | 402 // Attributes: |
352 // AttrType:subtype [required] | 403 // AttrType:subtype [required] |
353 // AttrStrideSize: size in bits of each element of the arra
y | 404 // AttrStrideSize: size in bits of each element of the arra
y |
354 // AttrByteSize: size of entire array | 405 // AttrByteSize: size of entire array |
355 // Children: | 406 // Children: |
356 // TagSubrangeType or TagEnumerationType giving one dimensi
on. | 407 // TagSubrangeType or TagEnumerationType giving one dimensi
on. |
357 // dimensions are in left to right order. | 408 // dimensions are in left to right order. |
358 t := new(ArrayType) | 409 t := new(ArrayType) |
| 410 t.ReflectKind = getKind(e) |
359 typ = t | 411 typ = t |
360 typeCache[off] = t | 412 typeCache[off] = t |
361 » » if t.Type = typeOf(e); err != nil { | 413 » » if t.Type = typeOf(e, AttrType); err != nil { |
362 goto Error | 414 goto Error |
363 } | 415 } |
364 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64) | 416 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64) |
365 | 417 |
366 // Accumulate dimensions, | 418 // Accumulate dimensions, |
367 ndim := 0 | 419 ndim := 0 |
368 for kid := next(); kid != nil; kid = next() { | 420 for kid := next(); kid != nil; kid = next() { |
369 // TODO(rsc): Can also be TagEnumerationType | 421 // TODO(rsc): Can also be TagEnumerationType |
370 // but haven't seen that in the wild yet. | 422 // but haven't seen that in the wild yet. |
371 switch kid.Tag { | 423 switch kid.Tag { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 case encUnsignedChar: | 480 case encUnsignedChar: |
429 typ = new(UcharType) | 481 typ = new(UcharType) |
430 } | 482 } |
431 typeCache[off] = typ | 483 typeCache[off] = typ |
432 t := typ.(interface { | 484 t := typ.(interface { |
433 Basic() *BasicType | 485 Basic() *BasicType |
434 }).Basic() | 486 }).Basic() |
435 t.Name = name | 487 t.Name = name |
436 t.BitSize, _ = e.Val(AttrBitSize).(int64) | 488 t.BitSize, _ = e.Val(AttrBitSize).(int64) |
437 t.BitOffset, _ = e.Val(AttrBitOffset).(int64) | 489 t.BitOffset, _ = e.Val(AttrBitOffset).(int64) |
| 490 t.ReflectKind = getKind(e) |
438 | 491 |
439 case TagClassType, TagStructType, TagUnionType: | 492 case TagClassType, TagStructType, TagUnionType: |
440 // Structure, union, or class type. (DWARF v2 §5.5) | 493 // Structure, union, or class type. (DWARF v2 §5.5) |
| 494 // Also Slices and Strings (Go-specific). |
441 // Attributes: | 495 // Attributes: |
442 // AttrName: name of struct, union, or class | 496 // AttrName: name of struct, union, or class |
443 // AttrByteSize: byte size [required] | 497 // AttrByteSize: byte size [required] |
444 // AttrDeclaration: if true, struct/union/class is incomple
te | 498 // AttrDeclaration: if true, struct/union/class is incomple
te |
| 499 // AttrGoElem: present for slices only. |
445 // Children: | 500 // Children: |
446 // TagMember to describe one member. | 501 // TagMember to describe one member. |
447 // AttrName: name of member [required] | 502 // AttrName: name of member [required] |
448 // AttrType: type of member [required] | 503 // AttrType: type of member [required] |
449 // AttrByteSize: size in bytes | 504 // AttrByteSize: size in bytes |
450 // AttrBitOffset: bit offset within bytes for bit f
ields | 505 // AttrBitOffset: bit offset within bytes for bit f
ields |
451 // AttrBitSize: bit size for bit fields | 506 // AttrBitSize: bit size for bit fields |
452 // AttrDataMemberLoc: location within struct [requi
red for struct, class] | 507 // AttrDataMemberLoc: location within struct [requi
red for struct, class] |
453 // There is much more to handle C++, all ignored for now. | 508 // There is much more to handle C++, all ignored for now. |
454 t := new(StructType) | 509 t := new(StructType) |
455 » » typ = t | 510 » » t.ReflectKind = getKind(e) |
456 » » typeCache[off] = t | 511 » » switch t.ReflectKind { |
| 512 » » case reflect.Slice: |
| 513 » » » slice := new(SliceType) |
| 514 » » » slice.ElemType = typeOf(e, AttrGoElem) |
| 515 » » » t = &slice.StructType |
| 516 » » » typ = slice |
| 517 » » case reflect.String: |
| 518 » » » str := new(StringType) |
| 519 » » » t = &str.StructType |
| 520 » » » typ = str |
| 521 » » default: |
| 522 » » » typ = t |
| 523 » » } |
| 524 » » typeCache[off] = typ |
457 switch e.Tag { | 525 switch e.Tag { |
458 case TagClassType: | 526 case TagClassType: |
459 t.Kind = "class" | 527 t.Kind = "class" |
460 case TagStructType: | 528 case TagStructType: |
461 t.Kind = "struct" | 529 t.Kind = "struct" |
462 case TagUnionType: | 530 case TagUnionType: |
463 t.Kind = "union" | 531 t.Kind = "union" |
464 } | 532 } |
465 t.StructName, _ = e.Val(AttrName).(string) | 533 t.StructName, _ = e.Val(AttrName).(string) |
466 t.Incomplete = e.Val(AttrDeclaration) != nil | 534 t.Incomplete = e.Val(AttrDeclaration) != nil |
467 t.Field = make([]*StructField, 0, 8) | 535 t.Field = make([]*StructField, 0, 8) |
468 var lastFieldType Type | 536 var lastFieldType Type |
469 var lastFieldBitOffset int64 | 537 var lastFieldBitOffset int64 |
470 for kid := next(); kid != nil; kid = next() { | 538 for kid := next(); kid != nil; kid = next() { |
471 if kid.Tag == TagMember { | 539 if kid.Tag == TagMember { |
472 f := new(StructField) | 540 f := new(StructField) |
473 » » » » if f.Type = typeOf(kid); err != nil { | 541 » » » » if f.Type = typeOf(kid, AttrType); err != nil { |
474 goto Error | 542 goto Error |
475 } | 543 } |
476 switch loc := kid.Val(AttrDataMemberLoc).(type)
{ | 544 switch loc := kid.Val(AttrDataMemberLoc).(type)
{ |
477 case []byte: | 545 case []byte: |
478 // TODO: Should have original compilatio
n | 546 // TODO: Should have original compilatio
n |
479 // unit here, not unknownFormat. | 547 // unit here, not unknownFormat. |
480 b := makeBuf(d, unknownFormat{}, "locati
on", 0, loc) | 548 b := makeBuf(d, unknownFormat{}, "locati
on", 0, loc) |
481 if x := b.uint8(); x != opPlusUconst { | 549 if x := b.uint8(); x != opPlusUconst { |
482 err = DecodeError{name, kid.Offs
et, "unexpected opcode 0x" + strconv.FormatUint(uint64(x), 16)} | 550 err = DecodeError{name, kid.Offs
et, "unexpected opcode 0x" + strconv.FormatUint(uint64(x), 16)} |
483 goto Error | 551 goto Error |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 // Final field must be zero width. Fix array le
ngth. | 585 // Final field must be zero width. Fix array le
ngth. |
518 zeroArray(lastFieldType) | 586 zeroArray(lastFieldType) |
519 } | 587 } |
520 } | 588 } |
521 | 589 |
522 case TagConstType, TagVolatileType, TagRestrictType: | 590 case TagConstType, TagVolatileType, TagRestrictType: |
523 // Type modifier (DWARF v2 §5.2) | 591 // Type modifier (DWARF v2 §5.2) |
524 // Attributes: | 592 // Attributes: |
525 // AttrType: subtype | 593 // AttrType: subtype |
526 t := new(QualType) | 594 t := new(QualType) |
| 595 t.ReflectKind = getKind(e) |
527 typ = t | 596 typ = t |
528 typeCache[off] = t | 597 typeCache[off] = t |
529 » » if t.Type = typeOf(e); err != nil { | 598 » » if t.Type = typeOf(e, AttrType); err != nil { |
530 goto Error | 599 goto Error |
531 } | 600 } |
532 switch e.Tag { | 601 switch e.Tag { |
533 case TagConstType: | 602 case TagConstType: |
534 t.Qual = "const" | 603 t.Qual = "const" |
535 case TagRestrictType: | 604 case TagRestrictType: |
536 t.Qual = "restrict" | 605 t.Qual = "restrict" |
537 case TagVolatileType: | 606 case TagVolatileType: |
538 t.Qual = "volatile" | 607 t.Qual = "volatile" |
539 } | 608 } |
540 | 609 |
541 case TagEnumerationType: | 610 case TagEnumerationType: |
542 // Enumeration type (DWARF v2 §5.6) | 611 // Enumeration type (DWARF v2 §5.6) |
543 // Attributes: | 612 // Attributes: |
544 // AttrName: enum name if any | 613 // AttrName: enum name if any |
545 // AttrByteSize: bytes required to represent largest value | 614 // AttrByteSize: bytes required to represent largest value |
546 // Children: | 615 // Children: |
547 // TagEnumerator: | 616 // TagEnumerator: |
548 // AttrName: name of constant | 617 // AttrName: name of constant |
549 // AttrConstValue: value of constant | 618 // AttrConstValue: value of constant |
550 t := new(EnumType) | 619 t := new(EnumType) |
| 620 t.ReflectKind = getKind(e) |
551 typ = t | 621 typ = t |
552 typeCache[off] = t | 622 typeCache[off] = t |
553 t.EnumName, _ = e.Val(AttrName).(string) | 623 t.EnumName, _ = e.Val(AttrName).(string) |
554 t.Val = make([]*EnumValue, 0, 8) | 624 t.Val = make([]*EnumValue, 0, 8) |
555 for kid := next(); kid != nil; kid = next() { | 625 for kid := next(); kid != nil; kid = next() { |
556 if kid.Tag == TagEnumerator { | 626 if kid.Tag == TagEnumerator { |
557 f := new(EnumValue) | 627 f := new(EnumValue) |
558 f.Name, _ = kid.Val(AttrName).(string) | 628 f.Name, _ = kid.Val(AttrName).(string) |
559 f.Val, _ = kid.Val(AttrConstValue).(int64) | 629 f.Val, _ = kid.Val(AttrConstValue).(int64) |
560 n := len(t.Val) | 630 n := len(t.Val) |
561 if n >= cap(t.Val) { | 631 if n >= cap(t.Val) { |
562 val := make([]*EnumValue, n, n*2) | 632 val := make([]*EnumValue, n, n*2) |
563 copy(val, t.Val) | 633 copy(val, t.Val) |
564 t.Val = val | 634 t.Val = val |
565 } | 635 } |
566 t.Val = t.Val[0 : n+1] | 636 t.Val = t.Val[0 : n+1] |
567 t.Val[n] = f | 637 t.Val[n] = f |
568 } | 638 } |
569 } | 639 } |
570 | 640 |
571 case TagPointerType: | 641 case TagPointerType: |
572 // Type modifier (DWARF v2 §5.2) | 642 // Type modifier (DWARF v2 §5.2) |
573 // Attributes: | 643 // Attributes: |
574 // AttrType: subtype [not required! void* has no AttrType] | 644 // AttrType: subtype [not required! void* has no AttrType] |
575 // AttrAddrClass: address class [ignored] | 645 // AttrAddrClass: address class [ignored] |
576 t := new(PtrType) | 646 t := new(PtrType) |
| 647 t.ReflectKind = getKind(e) |
577 typ = t | 648 typ = t |
578 typeCache[off] = t | 649 typeCache[off] = t |
579 if e.Val(AttrType) == nil { | 650 if e.Val(AttrType) == nil { |
580 t.Type = &VoidType{} | 651 t.Type = &VoidType{} |
581 break | 652 break |
582 } | 653 } |
583 » » t.Type = typeOf(e) | 654 » » t.Type = typeOf(e, AttrType) |
584 | 655 |
585 case TagSubroutineType: | 656 case TagSubroutineType: |
586 // Subroutine type. (DWARF v2 §5.7) | 657 // Subroutine type. (DWARF v2 §5.7) |
587 // Attributes: | 658 // Attributes: |
588 // AttrType: type of return value if any | 659 // AttrType: type of return value if any |
589 // AttrName: possible name of type [ignored] | 660 // AttrName: possible name of type [ignored] |
590 // AttrPrototyped: whether used ANSI C prototype [ignored] | 661 // AttrPrototyped: whether used ANSI C prototype [ignored] |
591 // Children: | 662 // Children: |
592 // TagFormalParameter: typed parameter | 663 // TagFormalParameter: typed parameter |
593 // AttrType: type of parameter | 664 // AttrType: type of parameter |
594 // TagUnspecifiedParameter: final ... | 665 // TagUnspecifiedParameter: final ... |
595 t := new(FuncType) | 666 t := new(FuncType) |
| 667 t.ReflectKind = getKind(e) |
596 typ = t | 668 typ = t |
597 typeCache[off] = t | 669 typeCache[off] = t |
598 » » if t.ReturnType = typeOf(e); err != nil { | 670 » » if t.ReturnType = typeOf(e, AttrType); err != nil { |
599 goto Error | 671 goto Error |
600 } | 672 } |
601 t.ParamType = make([]Type, 0, 8) | 673 t.ParamType = make([]Type, 0, 8) |
602 for kid := next(); kid != nil; kid = next() { | 674 for kid := next(); kid != nil; kid = next() { |
603 var tkid Type | 675 var tkid Type |
604 switch kid.Tag { | 676 switch kid.Tag { |
605 default: | 677 default: |
606 continue | 678 continue |
607 case TagFormalParameter: | 679 case TagFormalParameter: |
608 » » » » if tkid = typeOf(kid); err != nil { | 680 » » » » if tkid = typeOf(kid, AttrType); err != nil { |
609 goto Error | 681 goto Error |
610 } | 682 } |
611 case TagUnspecifiedParameters: | 683 case TagUnspecifiedParameters: |
612 tkid = &DotDotDotType{} | 684 tkid = &DotDotDotType{} |
613 } | 685 } |
614 t.ParamType = append(t.ParamType, tkid) | 686 t.ParamType = append(t.ParamType, tkid) |
615 } | 687 } |
616 | 688 |
617 case TagTypedef: | 689 case TagTypedef: |
618 // Typedef (DWARF v2 §5.3) | 690 // Typedef (DWARF v2 §5.3) |
| 691 // Also maps (Go-specific). |
619 // Attributes: | 692 // Attributes: |
620 // AttrName: name [required] | 693 // AttrName: name [required] |
621 // AttrType: type definition [required] | 694 // AttrType: type definition [required] |
| 695 // AttrGoKey: present for maps only. |
| 696 // AttrElemKey: present for maps only. |
622 t := new(TypedefType) | 697 t := new(TypedefType) |
623 » » typ = t | 698 » » t.ReflectKind = getKind(e) |
624 » » typeCache[off] = t | 699 » » switch t.ReflectKind { |
| 700 » » case reflect.Map: |
| 701 » » » m := new(MapType) |
| 702 » » » m.KeyType = typeOf(e, AttrGoKey) |
| 703 » » » m.ElemType = typeOf(e, AttrGoElem) |
| 704 » » » t = &m.TypedefType |
| 705 » » » typ = m |
| 706 » » default: |
| 707 » » » typ = t |
| 708 » » } |
| 709 » » typeCache[off] = typ |
625 t.Name, _ = e.Val(AttrName).(string) | 710 t.Name, _ = e.Val(AttrName).(string) |
626 » » t.Type = typeOf(e) | 711 » » t.Type = typeOf(e, AttrType) |
627 } | 712 } |
628 | 713 |
629 if err != nil { | 714 if err != nil { |
630 goto Error | 715 goto Error |
631 } | 716 } |
632 | 717 |
633 { | 718 { |
634 b, ok := e.Val(AttrByteSize).(int64) | 719 b, ok := e.Val(AttrByteSize).(int64) |
635 if !ok { | 720 if !ok { |
636 b = -1 | 721 b = -1 |
(...skipping 13 matching lines...) Expand all Loading... |
650 func zeroArray(t Type) { | 735 func zeroArray(t Type) { |
651 for { | 736 for { |
652 at, ok := t.(*ArrayType) | 737 at, ok := t.(*ArrayType) |
653 if !ok { | 738 if !ok { |
654 break | 739 break |
655 } | 740 } |
656 at.Count = 0 | 741 at.Count = 0 |
657 t = at.Type | 742 t = at.Type |
658 } | 743 } |
659 } | 744 } |
LEFT | RIGHT |