github.com/llir/llvm@v0.3.6/ir/types/types.go (about) 1 // Package types declares the data types of LLVM IR. 2 package types 3 4 import ( 5 "fmt" 6 "strings" 7 8 "github.com/llir/llvm/internal/enc" 9 ) 10 11 // === [ Types ] =============================================================== 12 13 // Convenience types. 14 var ( 15 // Basic types. 16 Void = &VoidType{} // void 17 MMX = &MMXType{} // x86_mmx 18 Label = &LabelType{} // label 19 Token = &TokenType{} // token 20 Metadata = &MetadataType{} // metadata 21 // Integer types. 22 I1 = &IntType{BitSize: 1} // i1 23 I2 = &IntType{BitSize: 2} // i2 24 I3 = &IntType{BitSize: 3} // i3 25 I4 = &IntType{BitSize: 4} // i4 26 I5 = &IntType{BitSize: 5} // i5 27 I6 = &IntType{BitSize: 6} // i6 28 I7 = &IntType{BitSize: 7} // i7 29 I8 = &IntType{BitSize: 8} // i8 30 I16 = &IntType{BitSize: 16} // i16 31 I32 = &IntType{BitSize: 32} // i32 32 I64 = &IntType{BitSize: 64} // i64 33 I128 = &IntType{BitSize: 128} // i128 34 I256 = &IntType{BitSize: 256} // i256 35 I512 = &IntType{BitSize: 512} // i512 36 I1024 = &IntType{BitSize: 1024} // i1024 37 // Floating-point types. 38 Half = &FloatType{Kind: FloatKindHalf} // half 39 Float = &FloatType{Kind: FloatKindFloat} // float 40 Double = &FloatType{Kind: FloatKindDouble} // double 41 X86_FP80 = &FloatType{Kind: FloatKindX86_FP80} // x86_fp80 42 FP128 = &FloatType{Kind: FloatKindFP128} // fp128 43 PPC_FP128 = &FloatType{Kind: FloatKindPPC_FP128} // ppc_fp128 44 // Integer pointer types. 45 I1Ptr = &PointerType{ElemType: I1} // i1* 46 I8Ptr = &PointerType{ElemType: I8} // i8* 47 I16Ptr = &PointerType{ElemType: I16} // i16* 48 I32Ptr = &PointerType{ElemType: I32} // i32* 49 I64Ptr = &PointerType{ElemType: I64} // i64* 50 I128Ptr = &PointerType{ElemType: I128} // i128* 51 ) 52 53 // Convenience functions. 54 55 // IsVoid reports whether the given type is a void type. 56 func IsVoid(t Type) bool { 57 _, ok := t.(*VoidType) 58 return ok 59 } 60 61 // IsFunc reports whether the given type is a function type. 62 func IsFunc(t Type) bool { 63 _, ok := t.(*FuncType) 64 return ok 65 } 66 67 // IsInt reports whether the given type is an integer type. 68 func IsInt(t Type) bool { 69 _, ok := t.(*IntType) 70 return ok 71 } 72 73 // IsFloat reports whether the given type is a floating-point type. 74 func IsFloat(t Type) bool { 75 _, ok := t.(*FloatType) 76 return ok 77 } 78 79 // IsMMX reports whether the given type is an MMX type. 80 func IsMMX(t Type) bool { 81 _, ok := t.(*MMXType) 82 return ok 83 } 84 85 // IsPointer reports whether the given type is a pointer type. 86 func IsPointer(t Type) bool { 87 _, ok := t.(*PointerType) 88 return ok 89 } 90 91 // IsVector reports whether the given type is a vector type. 92 func IsVector(t Type) bool { 93 _, ok := t.(*VectorType) 94 return ok 95 } 96 97 // IsLabel reports whether the given type is a label type. 98 func IsLabel(t Type) bool { 99 _, ok := t.(*LabelType) 100 return ok 101 } 102 103 // IsToken reports whether the given type is a token type. 104 func IsToken(t Type) bool { 105 _, ok := t.(*TokenType) 106 return ok 107 } 108 109 // IsMetadata reports whether the given type is a metadata type. 110 func IsMetadata(t Type) bool { 111 _, ok := t.(*MetadataType) 112 return ok 113 } 114 115 // IsArray reports whether the given type is an array type. 116 func IsArray(t Type) bool { 117 _, ok := t.(*ArrayType) 118 return ok 119 } 120 121 // IsStruct reports whether the given type is a struct type. 122 func IsStruct(t Type) bool { 123 _, ok := t.(*StructType) 124 return ok 125 } 126 127 // Equal reports whether t and u are of equal type. 128 func Equal(t, u Type) bool { 129 return t.Equal(u) 130 } 131 132 // Type is an LLVM IR type. 133 // 134 // A Type has one of the following underlying types. 135 // 136 // *types.VoidType // https://pkg.go.dev/github.com/llir/llvm/ir/types#VoidType 137 // *types.FuncType // https://pkg.go.dev/github.com/llir/llvm/ir/types#FuncType 138 // *types.IntType // https://pkg.go.dev/github.com/llir/llvm/ir/types#IntType 139 // *types.FloatType // https://pkg.go.dev/github.com/llir/llvm/ir/types#FloatType 140 // *types.MMXType // https://pkg.go.dev/github.com/llir/llvm/ir/types#MMXType 141 // *types.PointerType // https://pkg.go.dev/github.com/llir/llvm/ir/types#PointerType 142 // *types.VectorType // https://pkg.go.dev/github.com/llir/llvm/ir/types#VectorType 143 // *types.LabelType // https://pkg.go.dev/github.com/llir/llvm/ir/types#LabelType 144 // *types.TokenType // https://pkg.go.dev/github.com/llir/llvm/ir/types#TokenType 145 // *types.MetadataType // https://pkg.go.dev/github.com/llir/llvm/ir/types#MetadataType 146 // *types.ArrayType // https://pkg.go.dev/github.com/llir/llvm/ir/types#ArrayType 147 // *types.StructType // https://pkg.go.dev/github.com/llir/llvm/ir/types#StructType 148 type Type interface { 149 fmt.Stringer 150 // LLString returns the LLVM syntax representation of the definition of the 151 // type. 152 LLString() string 153 // Equal reports whether t and u are of equal type. 154 Equal(u Type) bool 155 // Name returns the type name of the type. 156 Name() string 157 // SetName sets the type name of the type. 158 SetName(name string) 159 } 160 161 // --- [ Void types ] ---------------------------------------------------------- 162 163 // VoidType is an LLVM IR void type. 164 type VoidType struct { 165 // Type name; or empty if not present. 166 TypeName string 167 } 168 169 // Equal reports whether t and u are of equal type. 170 func (t *VoidType) Equal(u Type) bool { 171 if _, ok := u.(*VoidType); ok { 172 return true 173 } 174 return false 175 } 176 177 // String returns the string representation of the void type. 178 func (t *VoidType) String() string { 179 if len(t.TypeName) > 0 { 180 return enc.TypeName(t.TypeName) 181 } 182 return t.LLString() 183 } 184 185 // LLString returns the LLVM syntax representation of the definition of the 186 // type. 187 // 188 // 'void' 189 func (t *VoidType) LLString() string { 190 return "void" 191 } 192 193 // Name returns the type name of the type. 194 func (t *VoidType) Name() string { 195 return t.TypeName 196 } 197 198 // SetName sets the type name of the type. 199 func (t *VoidType) SetName(name string) { 200 t.TypeName = name 201 } 202 203 // --- [ Function types ] ------------------------------------------------------ 204 205 // FuncType is an LLVM IR function type. 206 type FuncType struct { 207 // Type name; or empty if not present. 208 TypeName string 209 // Return type. 210 RetType Type 211 // Function parameters. 212 Params []Type 213 // Variable number of function arguments. 214 Variadic bool 215 } 216 217 // NewFunc returns a new function type based on the given return type and 218 // function parameter types. 219 func NewFunc(retType Type, params ...Type) *FuncType { 220 return &FuncType{ 221 RetType: retType, 222 Params: params, 223 } 224 } 225 226 // Equal reports whether t and u are of equal type. 227 func (t *FuncType) Equal(u Type) bool { 228 if u, ok := u.(*FuncType); ok { 229 if !t.RetType.Equal(u.RetType) { 230 return false 231 } 232 if len(t.Params) != len(u.Params) { 233 return false 234 } 235 for i := range t.Params { 236 if !t.Params[i].Equal(u.Params[i]) { 237 return false 238 } 239 } 240 return t.Variadic == u.Variadic 241 } 242 return false 243 } 244 245 // String returns the string representation of the function type. 246 func (t *FuncType) String() string { 247 if len(t.TypeName) > 0 { 248 return enc.TypeName(t.TypeName) 249 } 250 return t.LLString() 251 } 252 253 // LLString returns the LLVM syntax representation of the definition of the 254 // type. 255 // 256 // RetType=Type '(' Params ')' 257 func (t *FuncType) LLString() string { 258 buf := &strings.Builder{} 259 fmt.Fprintf(buf, "%s (", t.RetType) 260 for i, param := range t.Params { 261 if i != 0 { 262 buf.WriteString(", ") 263 } 264 buf.WriteString(param.String()) 265 } 266 if t.Variadic { 267 if len(t.Params) > 0 { 268 buf.WriteString(", ") 269 } 270 buf.WriteString("...") 271 } 272 buf.WriteString(")") 273 return buf.String() 274 } 275 276 // Name returns the type name of the type. 277 func (t *FuncType) Name() string { 278 return t.TypeName 279 } 280 281 // SetName sets the type name of the type. 282 func (t *FuncType) SetName(name string) { 283 t.TypeName = name 284 } 285 286 // --- [ Integer types ] ------------------------------------------------------- 287 288 // IntType is an LLVM IR integer type. 289 type IntType struct { 290 // Type name; or empty if not present. 291 TypeName string 292 // Integer size in number of bits. 293 BitSize uint64 294 } 295 296 // NewInt returns a new integer type based on the given integer bit size. 297 func NewInt(bitSize uint64) *IntType { 298 return &IntType{ 299 BitSize: bitSize, 300 } 301 } 302 303 // Equal reports whether t and u are of equal type. 304 func (t *IntType) Equal(u Type) bool { 305 if u, ok := u.(*IntType); ok { 306 return t.BitSize == u.BitSize 307 } 308 return false 309 } 310 311 // String returns the string representation of the integer type. 312 func (t *IntType) String() string { 313 if len(t.TypeName) > 0 { 314 return enc.TypeName(t.TypeName) 315 } 316 return t.LLString() 317 } 318 319 // LLString returns the LLVM syntax representation of the definition of the 320 // type. 321 // 322 // int_type_tok 323 func (t *IntType) LLString() string { 324 return fmt.Sprintf("i%d", t.BitSize) 325 } 326 327 // Name returns the type name of the type. 328 func (t *IntType) Name() string { 329 return t.TypeName 330 } 331 332 // SetName sets the type name of the type. 333 func (t *IntType) SetName(name string) { 334 t.TypeName = name 335 } 336 337 // --- [ Floating-point types ] ------------------------------------------------ 338 339 // FloatType is an LLVM IR floating-point type. 340 type FloatType struct { 341 // Type name; or empty if not present. 342 TypeName string 343 // Floating-point kind. 344 Kind FloatKind 345 } 346 347 // Equal reports whether t and u are of equal type. 348 func (t *FloatType) Equal(u Type) bool { 349 if u, ok := u.(*FloatType); ok { 350 return t.Kind == u.Kind 351 } 352 return false 353 } 354 355 // String returns the string representation of the floating-point type. 356 func (t *FloatType) String() string { 357 if len(t.TypeName) > 0 { 358 return enc.TypeName(t.TypeName) 359 } 360 return t.LLString() 361 } 362 363 // LLString returns the LLVM syntax representation of the definition of the 364 // type. 365 // 366 // FloatKind 367 func (t *FloatType) LLString() string { 368 return t.Kind.String() 369 } 370 371 // Name returns the type name of the type. 372 func (t *FloatType) Name() string { 373 return t.TypeName 374 } 375 376 // SetName sets the type name of the type. 377 func (t *FloatType) SetName(name string) { 378 t.TypeName = name 379 } 380 381 //go:generate stringer -linecomment -type FloatKind 382 383 // FloatKind represents the set of floating-point kinds. 384 type FloatKind uint8 385 386 // Floating-point kinds. 387 const ( 388 // 16-bit floating-point type (IEEE 754 half precision). 389 FloatKindHalf FloatKind = iota // half 390 // 32-bit floating-point type (IEEE 754 single precision). 391 FloatKindFloat // float 392 // 64-bit floating-point type (IEEE 754 double precision). 393 FloatKindDouble // double 394 // 128-bit floating-point type (IEEE 754 quadruple precision). 395 FloatKindFP128 // fp128 396 // 80-bit floating-point type (x86 extended precision). 397 FloatKindX86_FP80 // x86_fp80 398 // 128-bit floating-point type (PowerPC double-double arithmetic). 399 FloatKindPPC_FP128 // ppc_fp128 400 ) 401 402 // --- [ MMX types ] ----------------------------------------------------------- 403 404 // MMXType is an LLVM IR MMX type. 405 type MMXType struct { 406 // Type name; or empty if not present. 407 TypeName string 408 } 409 410 // Equal reports whether t and u are of equal type. 411 func (t *MMXType) Equal(u Type) bool { 412 if _, ok := u.(*MMXType); ok { 413 return true 414 } 415 return false 416 } 417 418 // String returns the string representation of the MMX type. 419 func (t *MMXType) String() string { 420 if len(t.TypeName) > 0 { 421 return enc.TypeName(t.TypeName) 422 } 423 return t.LLString() 424 } 425 426 // LLString returns the LLVM syntax representation of the definition of the 427 // type. 428 // 429 // 'x86_mmx' 430 func (t *MMXType) LLString() string { 431 return "x86_mmx" 432 } 433 434 // Name returns the type name of the type. 435 func (t *MMXType) Name() string { 436 return t.TypeName 437 } 438 439 // SetName sets the type name of the type. 440 func (t *MMXType) SetName(name string) { 441 t.TypeName = name 442 } 443 444 // --- [ Pointer types ] ------------------------------------------------------- 445 446 // PointerType is an LLVM IR pointer type. 447 type PointerType struct { 448 // Type name; or empty if not present. 449 TypeName string 450 // Element type. 451 ElemType Type 452 // Address space; or zero value for default address space. 453 AddrSpace AddrSpace 454 } 455 456 // NewPointer returns a new pointer type based on the given element type. 457 func NewPointer(elemType Type) *PointerType { 458 return &PointerType{ 459 ElemType: elemType, 460 } 461 } 462 463 // Equal reports whether t and u are of equal type. 464 func (t *PointerType) Equal(u Type) bool { 465 // HACK: to prevent infinite loops (e.g. struct foo containing field of type 466 // pointer to foo). 467 return t.String() == u.String() 468 } 469 470 // String returns the string representation of the pointer type. 471 func (t *PointerType) String() string { 472 if len(t.TypeName) > 0 { 473 return enc.TypeName(t.TypeName) 474 } 475 return t.LLString() 476 } 477 478 // LLString returns the LLVM syntax representation of the definition of the 479 // type. 480 // 481 // Elem=Type AddrSpaceopt '*' 482 func (t *PointerType) LLString() string { 483 buf := &strings.Builder{} 484 buf.WriteString(t.ElemType.String()) 485 if t.AddrSpace != 0 { 486 fmt.Fprintf(buf, " %s", t.AddrSpace) 487 } 488 buf.WriteString("*") 489 return buf.String() 490 } 491 492 // SetName sets the type name of the type. 493 func (t *PointerType) SetName(name string) { 494 t.TypeName = name 495 } 496 497 // Name returns the type name of the type. 498 func (t *PointerType) Name() string { 499 return t.TypeName 500 } 501 502 // AddrSpace is an LLVM IR pointer type address space. 503 type AddrSpace uint64 504 505 // String returns the string representation of the pointer type address space. 506 func (a AddrSpace) String() string { 507 // 'addrspace' '(' N=UintLit ')' 508 return fmt.Sprintf("addrspace(%d)", uint64(a)) 509 } 510 511 // --- [ Vector types ] -------------------------------------------------------- 512 513 // VectorType is an LLVM IR vector type. 514 type VectorType struct { 515 // Type name; or empty if not present. 516 TypeName string 517 // Scalable vector type. 518 Scalable bool 519 // Vector length. 520 Len uint64 521 // Element type. 522 ElemType Type 523 } 524 525 // NewVector returns a new vector type based on the given vector length and 526 // element type. 527 func NewVector(len uint64, elemType Type) *VectorType { 528 return &VectorType{ 529 Len: len, 530 ElemType: elemType, 531 } 532 } 533 534 // Equal reports whether t and u are of equal type. 535 func (t *VectorType) Equal(u Type) bool { 536 if u, ok := u.(*VectorType); ok { 537 if t.Scalable != u.Scalable { 538 return false 539 } 540 if t.Len != u.Len { 541 return false 542 } 543 return t.ElemType.Equal(u.ElemType) 544 } 545 return false 546 } 547 548 // String returns the string representation of the vector type. 549 func (t *VectorType) String() string { 550 if len(t.TypeName) > 0 { 551 return enc.TypeName(t.TypeName) 552 } 553 return t.LLString() 554 } 555 556 // LLString returns the LLVM syntax representation of the definition of the 557 // type. 558 // 559 // scalable: '<' 'vscale' 'x' Len=UintLit 'x' Elem=Type '>' 560 // non-scalable: '<' Len=UintLit 'x' Elem=Type '>' 561 func (t *VectorType) LLString() string { 562 if t.Scalable { 563 // '<' 'vscale' 'x' Len=UintLit 'x' Elem=Type '>' 564 return fmt.Sprintf("<vscale x %d x %s>", t.Len, t.ElemType) 565 } 566 // '<' Len=UintLit 'x' Elem=Type '>' 567 return fmt.Sprintf("<%d x %s>", t.Len, t.ElemType) 568 } 569 570 // Name returns the type name of the type. 571 func (t *VectorType) Name() string { 572 return t.TypeName 573 } 574 575 // SetName sets the type name of the type. 576 func (t *VectorType) SetName(name string) { 577 t.TypeName = name 578 } 579 580 // --- [ Label types ] --------------------------------------------------------- 581 582 // LabelType is an LLVM IR label type, which is used for basic block values. 583 type LabelType struct { 584 // Type name; or empty if not present. 585 TypeName string 586 } 587 588 // Equal reports whether t and u are of equal type. 589 func (t *LabelType) Equal(u Type) bool { 590 if _, ok := u.(*LabelType); ok { 591 return true 592 } 593 return false 594 } 595 596 // String returns the string representation of the label type. 597 func (t *LabelType) String() string { 598 if len(t.TypeName) > 0 { 599 return enc.TypeName(t.TypeName) 600 } 601 return t.LLString() 602 } 603 604 // LLString returns the LLVM syntax representation of the definition of the 605 // type. 606 // 607 // 'label' 608 func (t *LabelType) LLString() string { 609 return "label" 610 } 611 612 // Name returns the type name of the type. 613 func (t *LabelType) Name() string { 614 return t.TypeName 615 } 616 617 // SetName sets the type name of the type. 618 func (t *LabelType) SetName(name string) { 619 t.TypeName = name 620 } 621 622 // --- [ Token types ] --------------------------------------------------------- 623 624 // TokenType is an LLVM IR token type. 625 type TokenType struct { 626 // Type name; or empty if not present. 627 TypeName string 628 } 629 630 // Equal reports whether t and u are of equal type. 631 func (t *TokenType) Equal(u Type) bool { 632 if _, ok := u.(*TokenType); ok { 633 return true 634 } 635 return false 636 } 637 638 // String returns the string representation of the token type. 639 func (t *TokenType) String() string { 640 if len(t.TypeName) > 0 { 641 return enc.TypeName(t.TypeName) 642 } 643 return t.LLString() 644 } 645 646 // LLString returns the LLVM syntax representation of the definition of the 647 // type. 648 // 649 // 'token' 650 func (t *TokenType) LLString() string { 651 return "token" 652 } 653 654 // Name returns the type name of the type. 655 func (t *TokenType) Name() string { 656 return t.TypeName 657 } 658 659 // SetName sets the type name of the type. 660 func (t *TokenType) SetName(name string) { 661 t.TypeName = name 662 } 663 664 // --- [ Metadata types ] ------------------------------------------------------ 665 666 // MetadataType is an LLVM IR metadata type. 667 type MetadataType struct { 668 // Type name; or empty if not present. 669 TypeName string 670 } 671 672 // Equal reports whether t and u are of equal type. 673 func (t *MetadataType) Equal(u Type) bool { 674 if _, ok := u.(*MetadataType); ok { 675 return true 676 } 677 return false 678 } 679 680 // String returns the string representation of the metadata type. 681 func (t *MetadataType) String() string { 682 if len(t.TypeName) > 0 { 683 return enc.TypeName(t.TypeName) 684 } 685 return t.LLString() 686 } 687 688 // LLString returns the LLVM syntax representation of the definition of the 689 // type. 690 // 691 // 'metadata' 692 func (t *MetadataType) LLString() string { 693 return "metadata" 694 } 695 696 // Name returns the type name of the type. 697 func (t *MetadataType) Name() string { 698 return t.TypeName 699 } 700 701 // SetName sets the type name of the type. 702 func (t *MetadataType) SetName(name string) { 703 t.TypeName = name 704 } 705 706 // --- [ Array types ] --------------------------------------------------------- 707 708 // ArrayType is an LLVM IR array type. 709 type ArrayType struct { 710 // Type name; or empty if not present. 711 TypeName string 712 // Array length. 713 Len uint64 714 // Element type. 715 ElemType Type 716 } 717 718 // NewArray returns a new array type based on the given array length and element 719 // type. 720 func NewArray(len uint64, elemType Type) *ArrayType { 721 return &ArrayType{ 722 Len: len, 723 ElemType: elemType, 724 } 725 } 726 727 // Equal reports whether t and u are of equal type. 728 func (t *ArrayType) Equal(u Type) bool { 729 if u, ok := u.(*ArrayType); ok { 730 if t.Len != u.Len { 731 return false 732 } 733 return t.ElemType.Equal(u.ElemType) 734 } 735 return false 736 } 737 738 // String returns the string representation of the array type. 739 func (t *ArrayType) String() string { 740 if len(t.TypeName) > 0 { 741 return enc.TypeName(t.TypeName) 742 } 743 return t.LLString() 744 } 745 746 // LLString returns the LLVM syntax representation of the definition of the 747 // type. 748 // 749 // '[' Len=UintLit 'x' Elem=Type ']' 750 func (t *ArrayType) LLString() string { 751 return fmt.Sprintf("[%d x %s]", t.Len, t.ElemType) 752 } 753 754 // Name returns the type name of the type. 755 func (t *ArrayType) Name() string { 756 return t.TypeName 757 } 758 759 // SetName sets the type name of the type. 760 func (t *ArrayType) SetName(name string) { 761 t.TypeName = name 762 } 763 764 // --- [ Structure types ] ----------------------------------------------------- 765 766 // StructType is an LLVM IR structure type. Identified (named) struct types are 767 // uniqued by type names, not by structural identity. 768 type StructType struct { 769 // Type name; or empty if not present. 770 TypeName string 771 // Packed memory layout. 772 Packed bool 773 // Struct fields. 774 Fields []Type 775 // Opaque struct type. 776 Opaque bool 777 } 778 779 // NewStruct returns a new struct type based on the given field types. 780 func NewStruct(fields ...Type) *StructType { 781 return &StructType{ 782 Fields: fields, 783 } 784 } 785 786 // Equal reports whether t and u are of equal type. 787 func (t *StructType) Equal(u Type) bool { 788 if u, ok := u.(*StructType); ok { 789 if len(t.TypeName) > 0 || len(u.TypeName) > 0 { 790 // Identified struct types are uniqued by type names, not by structural 791 // identity. 792 // 793 // t or u is an identified struct type. 794 return t.TypeName == u.TypeName 795 } 796 // Literal struct types are uniqued by structural identity. 797 if t.Packed != u.Packed { 798 return false 799 } 800 if len(t.Fields) != len(u.Fields) { 801 return false 802 } 803 for i := range t.Fields { 804 if !t.Fields[i].Equal(u.Fields[i]) { 805 return false 806 } 807 } 808 return true 809 } 810 return false 811 } 812 813 // String returns the string representation of the structure type. 814 func (t *StructType) String() string { 815 if len(t.TypeName) > 0 { 816 return enc.TypeName(t.TypeName) 817 } 818 return t.LLString() 819 } 820 821 // LLString returns the LLVM syntax representation of the definition of the 822 // type. 823 // 824 // Opaque struct type. 825 // 826 // 'opaque' 827 // 828 // Struct type. 829 // 830 // '{' Fields=(Type separator ',')+? '}' 831 // 832 // Packed struct type. 833 // 834 // '<' '{' Fields=(Type separator ',')+? '}' '>' -> PackedStructType 835 func (t *StructType) LLString() string { 836 if t.Opaque { 837 return "opaque" 838 } 839 if len(t.Fields) == 0 { 840 if t.Packed { 841 return "<{}>" 842 } 843 return "{}" 844 } 845 buf := &strings.Builder{} 846 if t.Packed { 847 buf.WriteString("<") 848 } 849 buf.WriteString("{ ") 850 for i, field := range t.Fields { 851 if i != 0 { 852 buf.WriteString(", ") 853 } 854 buf.WriteString(field.String()) 855 } 856 buf.WriteString(" }") 857 if t.Packed { 858 buf.WriteString(">") 859 } 860 return buf.String() 861 } 862 863 // Name returns the type name of the type. 864 func (t *StructType) Name() string { 865 return t.TypeName 866 } 867 868 // SetName sets the type name of the type. 869 func (t *StructType) SetName(name string) { 870 t.TypeName = name 871 }