gitlab.com/cznic/ccir@v1.0.0/ccir.go (about) 1 // Copyright 2017 The CCIR 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 // Package ccir translates cc[0] ASTs to an intermediate representation. (Work In Progress) 6 // 7 // Supported platforms and architectures 8 // 9 // In GOOS_GOARCH form 10 // 11 // linux_386 12 // linux_amd64 13 // windows_386 14 // windows_amd64 15 // 16 // If you can access a machine with a not yet supported os/arch and you would 17 // like to contribute to porting this package, you may want to start by trying 18 // 19 // $ cd $GOPATH/src/modernc.org/ccir/libc 20 // $ go generate 21 // 22 // Please fill an issue for the port and let's discuss it there. 23 // 24 // Links 25 // 26 // Referenced from elsewhere 27 // 28 // [0]: https://modernc.org/cc 29 package ccir // import "modernc.org/ccir" 30 31 import ( 32 "fmt" 33 "go/token" 34 "math" 35 "os" 36 "path" 37 "path/filepath" 38 "runtime" 39 "strings" 40 41 "modernc.org/cc" 42 "modernc.org/internal/buffer" 43 "modernc.org/ir" 44 "modernc.org/mathutil" 45 "modernc.org/strutil" 46 "modernc.org/virtual" 47 "modernc.org/xc" 48 ) 49 50 const ( 51 _ = iota //TODOOK 52 stmtExprValue 53 stmtExprAddress 54 ) 55 56 var ( 57 // Testing amends things for tests. 58 Testing bool 59 // CRT0Path points to the C _start function source file. R/O. 60 CRT0Path string 61 // LibcIncludePath can be used as an argument to cc.SysIncludePaths. R/O. 62 LibcIncludePath string 63 64 ccTestdata string 65 isTesting bool // Running tests. 66 ) 67 68 func init() { 69 ip, err := cc.ImportPath() 70 if err != nil { 71 panic(err) 72 } 73 74 for _, v := range filepath.SplitList(strutil.Gopath()) { 75 p := filepath.Join(v, "src", ip, "testdata") 76 fi, err := os.Stat(p) 77 if err != nil { 78 continue 79 } 80 81 if fi.IsDir() { 82 ccTestdata = p 83 break 84 } 85 } 86 if ccTestdata == "" { 87 panic("cannot find cc/testdata/") 88 } 89 90 p, err := strutil.ImportPath() 91 if err != nil { 92 panic(err) 93 } 94 95 for _, v := range strings.Split(strutil.Gopath(), string(os.PathListSeparator)) { 96 p := filepath.Join(v, "src", p, "libc") 97 _, err := os.Stat(p) 98 if err != nil { 99 continue 100 } 101 102 LibcIncludePath = p 103 CRT0Path = filepath.Join(p, "crt0.c") 104 return 105 } 106 panic("internal error") 107 } 108 109 //TODO remove me. 110 func TODO(more ...interface{}) string { //TODOOK 111 _, fn, fl, _ := runtime.Caller(1) 112 fmt.Fprintf(os.Stderr, "%s:%d: %v\n", path.Base(fn), fl, fmt.Sprint(more...)) 113 os.Stderr.Sync() 114 panic(fmt.Errorf("%s:%d: %v", path.Base(fn), fl, fmt.Sprint(more...))) 115 } 116 117 type labels struct { 118 breakLabel int 119 caseLabel int 120 continueLabel int 121 } 122 123 func (l *labels) setBreak(n int) int { 124 r := l.breakLabel 125 l.breakLabel = n 126 return r 127 } 128 129 func (l *labels) setContinue(n int) int { 130 r := l.continueLabel 131 l.continueLabel = n 132 return r 133 } 134 135 type varInfo struct { 136 index int 137 staticName ir.NameID 138 typ ir.TypeID 139 140 arg bool 141 static bool 142 } 143 144 type fdata struct { 145 arguments []ir.TypeID 146 blockLevel int 147 cResult cc.Type 148 f *ir.FunctionDefinition 149 index int // Current function object index. 150 label int 151 loop bool 152 result ir.TypeID 153 static int 154 statics map[ir.NameID]ir.NameID 155 variable int 156 variables map[*cc.Declarator]varInfo 157 } 158 159 type c struct { 160 ast *cc.TranslationUnit 161 builtins map[ir.NameID]struct{} 162 cint cc.Type 163 ctypes map[cc.Type]ir.Type 164 f fdata 165 model ir.MemoryModel 166 out []ir.Object 167 types ir.TypeCache 168 } 169 170 func newC(model ir.MemoryModel, ast *cc.TranslationUnit, o *options) *c { 171 return &c{ 172 ast: ast, 173 builtins: map[ir.NameID]struct{}{}, 174 cint: ast.Model.IntType, 175 ctypes: map[cc.Type]ir.Type{}, 176 model: model, 177 types: o.tc, 178 } 179 } 180 181 func (c *c) isVLA(t cc.Type) *cc.Expression { 182 switch d := t.Declarator().DirectDeclarator; d.Case { 183 case 0: // IDENTIFIER 184 return nil 185 case 1: // '(' Declarator ')' // Case 1 186 TODO(position(d)) 187 case 2: // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' // Case 2 188 o := d.ExpressionOpt 189 if o == nil { 190 return nil 191 } 192 193 if e := o.Expression; e.Value == nil { 194 return e 195 } 196 197 return nil 198 case 3: // DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']' // Case 3 199 TODO(position(d)) 200 case 4: // DirectDeclarator '[' TypeQualifierList "static" Expression ']' // Case 4 201 TODO(position(d)) 202 case 5: // DirectDeclarator '[' TypeQualifierListOpt '*' ']' // Case 5 203 TODO(position(d)) 204 case 6: // DirectDeclarator '(' ParameterTypeList ')' // Case 6 205 return nil 206 case 7: // DirectDeclarator '(' IdentifierListOpt ')' // Case 7 207 return nil 208 } 209 panic("internal error") 210 } 211 212 func (c *c) nm(d *cc.Declarator) ir.NameID { 213 id, _ := d.Identifier() 214 return ir.NameID(id) 215 } 216 217 func (c *c) tnm(d *cc.Declarator) ir.NameID { 218 var b buffer.Bytes 219 220 defer b.Close() 221 222 t := d.Type 223 for { 224 done := true 225 switch t.Kind() { 226 case cc.Array: 227 fmt.Fprintf(&b, "[%v]", t.Elements()) 228 t = t.Element() 229 done = false 230 case cc.Ptr: 231 b.WriteByte('*') 232 t = t.Element() 233 done = false 234 } 235 if done { 236 break 237 } 238 } 239 if nm := t.RawDeclarator().RawSpecifier().TypedefName(); nm != 0 { 240 b.WriteByte('X') 241 b.Write(dict.S(nm)) 242 return ir.NameID(dict.ID(b.Bytes())) 243 } 244 245 switch t.Kind() { 246 case cc.Struct, cc.UChar: 247 if nm := t.Tag(); nm != 0 { 248 b.WriteByte('T') 249 b.Write(dict.S(nm)) 250 return ir.NameID(dict.ID(b.Bytes())) 251 } 252 } 253 254 return 0 255 } 256 257 func (c *c) typ0(dst *buffer.Bytes, t cc.Type, flat, arrayDecay bool) { 258 sou := "struct{" 259 switch k := t.Kind(); k { 260 case cc.Ptr: 261 dst.WriteByte('*') 262 if arrayDecay && t.Element().Kind() == cc.Array && isOpenMDArray(t) { 263 fmt.Fprintf(dst, "[0]") 264 c.typ0(dst, t.Element(), false, false) 265 return 266 } 267 268 if flat { 269 switch t.Element().Kind() { 270 case cc.Struct, cc.Union, cc.Array: 271 dst.WriteString("struct{}") 272 return 273 } 274 } 275 276 c.typ0(dst, t.Element(), flat, false) 277 case cc.Enum: 278 dst.WriteString(fmt.Sprintf("int%v", c.ast.Model.Items[cc.Int].Size*8)) 279 case cc.Char, cc.SChar, cc.Short, cc.Int, cc.Long, cc.LongLong: 280 dst.WriteString(fmt.Sprintf("int%v", c.ast.Model.Items[k].Size*8)) 281 case cc.Bool, cc.UChar, cc.UShort, cc.UInt, cc.ULong, cc.ULongLong: 282 dst.WriteString(fmt.Sprintf("uint%v", c.ast.Model.Items[k].Size*8)) 283 case cc.Float, cc.Double, cc.LongDouble: 284 dst.WriteString(fmt.Sprintf("float%v", c.ast.Model.Items[k].Size*8)) 285 case cc.FloatComplex, cc.DoubleComplex, cc.LongDoubleComplex: 286 dst.WriteString(fmt.Sprintf("complex%v", c.ast.Model.Items[k].Size*8)) 287 case cc.Function: 288 dst.WriteString("func(") 289 p, variadic := t.Parameters() 290 for i, v := range p { 291 c.typ0(dst, v.Type, flat, true) 292 if i+1 < len(p) { 293 dst.WriteByte(',') 294 } 295 } 296 if variadic { 297 dst.WriteString("...") 298 } 299 dst.WriteByte(')') 300 if r := t.Result(); r.Kind() != cc.Void { 301 c.typ0(dst, r, flat, true) 302 } 303 case cc.Array: 304 switch n := t.Elements(); { 305 case n < 0: 306 panic("internal error") 307 case arrayDecay: 308 dst.WriteByte('*') 309 fallthrough 310 default: 311 dst.WriteByte('[') 312 fmt.Fprintf(dst, "%d", n) 313 dst.WriteByte(']') 314 c.typ0(dst, t.Element(), flat, false) 315 } 316 case cc.Union: 317 sou = "union{" 318 fallthrough 319 case cc.Struct: 320 dst.WriteString(sou) 321 m := c.members(t, false, true) 322 n := 0 323 for _, v := range m { 324 t := v.Type 325 if c.isVLA(t) != nil { 326 panic(fmt.Errorf("%s: struct/union member cannot be a variable length array", position(t.Declarator()))) 327 } 328 329 if v.Bits != 0 { 330 if v.BitOffsetOf != 0 { 331 continue 332 } 333 334 t = v.BitFieldType 335 if t == nil { 336 t = c.cint 337 } 338 } 339 340 if n != 0 { 341 dst.WriteByte(',') 342 } 343 n++ 344 dst.Write(dict.S(v.Name)) 345 dst.WriteByte(' ') 346 c.typ0(dst, t, true, false) 347 } 348 dst.WriteByte('}') 349 return 350 case cc.Void: 351 dst.WriteString("struct{}") 352 default: 353 panic(fmt.Errorf("internal error %v:%v", t, k)) 354 } 355 } 356 357 func (c *c) typ(n cc.Node, in cc.Type) ir.Type { 358 if r := c.ctypes[in]; r != nil { 359 return r 360 } 361 362 var dst buffer.Bytes 363 c.typ0(&dst, in, false, false) 364 out, err := c.types.Type(ir.TypeID(dict.ID(dst.Bytes()))) 365 if err != nil { 366 panic(fmt.Errorf("%s: type %q:%q, type specifier %q: internal error: %v", position(in.Declarator()), in, in.Kind(), dst.Bytes(), err)) 367 } 368 369 dst.Close() 370 c.ctypes[in] = out 371 return out 372 } 373 374 func (c *c) linkage(l cc.Linkage) ir.Linkage { 375 switch l { 376 case cc.External: 377 return ir.ExternalLinkage 378 case cc.Internal: 379 return ir.InternalLinkage 380 case cc.None: 381 return ir.Linkage(-1) 382 default: 383 panic("internal error") 384 } 385 } 386 387 func (c *c) addressInitializer(n *cc.Expression) (r ir.Value) { 388 n, _ = c.normalize(n) 389 switch n.Case { 390 case 0: // IDENTIFIER 391 switch n.Type.Kind() { 392 case cc.Array, cc.Function, cc.Union, cc.Struct: 393 id := n.Token.Val 394 b, s := n.IdentResolutionScope().Lookup2(cc.NSIdentifiers, id) 395 d := b.Node.(*cc.DirectDeclarator).TopDeclarator() 396 switch s.Scope() { 397 case cc.ScopeFile: 398 return &ir.AddressValue{Index: -1, Linkage: c.linkage(d.Linkage), NameID: c.nm(d)} 399 case cc.ScopeBlock: 400 if d.Type.Specifier().IsStatic() { 401 return &ir.AddressValue{Index: -1, Linkage: ir.InternalLinkage, NameID: c.f.statics[c.nm(d)]} 402 } 403 } 404 default: 405 TODO(position(n), fmt.Sprintf(" %v:%v", n.Type, n.Type.Kind())) 406 } 407 case 8: // Expression '[' ExpressionList ']' // Case 8 408 t := n.Expression.Type 409 switch t.Kind() { 410 case cc.Array: 411 switch x := c.addressInitializer(n.Expression).(type) { 412 case *ir.AddressValue: 413 switch index := n.ExpressionList.Value.(type) { 414 case int32: 415 x.Offset += uintptr(index) * uintptr(t.Element().SizeOf()) 416 default: 417 TODO(position(n), fmt.Sprintf(" %T", index)) 418 } 419 return x 420 default: 421 TODO(position(n.Token), fmt.Sprintf(" %T", x)) 422 } 423 default: 424 TODO(position(n), " ", t.Kind()) 425 } 426 case 10: // Expression '.' IDENTIFIER // Case 10 427 t := n.Expression.Type 428 switch x := c.addressInitializer(n.Expression).(type) { 429 case *ir.AddressValue: 430 m, err := t.Member(n.Token2.Val) 431 if err != nil { 432 panic("internal errir") 433 } 434 435 x.Offset += uintptr(m.OffsetOf) 436 return x 437 default: 438 TODO(position(n.Token), fmt.Sprintf(" %T", x)) 439 } 440 case 14: // '(' TypeName ')' '{' InitializerList CommaOpt '}' // Case 14 441 TODO(position(n)) 442 case 17: // '&' Expression // Case 17 443 switch n := n.Expression; n.Case { 444 case 0: // IDENTIFIER 445 id := n.Token.Val 446 b, s := n.IdentResolutionScope().Lookup2(cc.NSIdentifiers, id) 447 d := b.Node.(*cc.DirectDeclarator).TopDeclarator() 448 switch s.Scope() { 449 case cc.ScopeFile: 450 return &ir.AddressValue{Index: -1, Linkage: c.linkage(d.Linkage), NameID: c.nm(d)} 451 } 452 default: 453 return c.addressInitializer(n) 454 } 455 case 25: // '(' TypeName ')' Expression // Case 25 456 return c.addressInitializer(n.Expression) 457 } 458 return nil 459 } 460 461 func (c *c) arrayInitializerList(t cc.Type, n *cc.InitializerList) (ir.Value, bool) { 462 values := &ir.CompositeValue{} 463 complete := true 464 var designators int 465 elem := t.Element() 466 for l := n; l != nil; l = l.InitializerList { 467 val, init := c.initializer(elem, l.Initializer, false) 468 if init != nil { 469 complete = false 470 } 471 472 if o := l.DesignationOpt; o != nil { 473 dl := o.Designation.DesignatorList 474 if dl.DesignatorList != nil { 475 TODO(position(n)) 476 } 477 478 switch d := dl.Designator; d.Case { 479 case 0: // '[' ConstantExpression ']' 480 TODO(position(n)) 481 case 1: // '.' IDENTIFIER // Case 1 482 panic("internal error") 483 default: 484 panic("internal error") 485 } 486 } 487 488 values.Values = append(values.Values, val) 489 } 490 if designators != 0 { 491 TODO(position(n)) 492 } 493 494 return values, complete 495 } 496 497 func (c *c) members(t cc.Type, skipAnonymousBitFields, acceptIncompleteTypes bool) []cc.Member { 498 members, incomplete := t.Members() 499 if incomplete && !acceptIncompleteTypes { 500 TODO(position(t.Declarator())) 501 } 502 503 if !skipAnonymousBitFields { 504 return members 505 } 506 507 w := 0 508 for _, v := range members { 509 if v.Name == 0 && v.Bits != 0 && skipAnonymousBitFields { 510 continue 511 } 512 513 members[w] = v 514 w++ 515 } 516 return members[:w] 517 } 518 519 func (c *c) structInitializerList(t cc.Type, n *cc.InitializerList) (ir.Value, bool) { 520 members := c.members(t, true, false) 521 if len(members) == 1 && n.Len() > 1 { 522 if t0 := members[0].Type; t0.Kind() == cc.Array { 523 val, complete := c.arrayInitializerList(t0, n) 524 if val != nil { 525 val = &ir.CompositeValue{Values: []ir.Value{val}} 526 } 527 return val, complete 528 } 529 } 530 531 values := make([]ir.Value, len(members)) 532 complete := true 533 var i int 534 for l := n; l != nil; l = l.InitializerList { 535 search2: 536 switch in := l.Initializer; in.Case { 537 case 2: // IDENTIFIER ':' Initializer // Case 2 538 nm := in.Token.Val 539 for j, v := range members { 540 if v.Name == nm { 541 i = j 542 break search2 543 } 544 } 545 546 panic("internal error") 547 default: 548 if o := l.DesignationOpt; o != nil { 549 dl := o.Designation.DesignatorList 550 if dl.DesignatorList != nil { 551 TODO(position(n)) 552 } 553 554 search: 555 switch d := dl.Designator; d.Case { 556 case 0: // '[' ConstantExpression ']' 557 panic("internal error") 558 case 1: // '.' IDENTIFIER // Case 1 559 nm := d.Token2.Val 560 for j, v := range members { 561 if v.Name == nm { 562 i = j 563 break search 564 } 565 } 566 567 panic("internal error") 568 default: 569 panic("internal error") 570 } 571 } 572 } 573 574 ft := members[i].Type 575 if i == len(members)-1 && l.InitializerList != nil && ft.Kind() == cc.Array { 576 val, ok := c.initializerList(ft, l) 577 values[i] = val 578 if !ok { 579 complete = false 580 } 581 break 582 } 583 584 val, init := c.initializer(ft, l.Initializer, true) 585 if init != nil { 586 complete = false 587 } 588 values[i] = val 589 i++ 590 } 591 592 iField := 0 593 iValue := 0 594 for i := 0; i < len(members) && iValue < len(values); i++ { 595 m := members[i] 596 if m.Bits != 0 { 597 group := m.BitFieldGroup 598 groupStart := i 599 groupEnd := len(members) 600 for ; i < len(members); i++ { 601 if members[i].Bits == 0 || members[i].BitFieldGroup != group { 602 groupEnd = i 603 i-- 604 break 605 } 606 } 607 608 var bval uint64 609 var val ir.Value 610 for j := groupStart; j < groupEnd && iValue < len(values); j++ { 611 var bits uint64 612 switch x := values[iValue].(type) { 613 case nil: 614 // ok 615 case *ir.Int32Value: 616 bits = uint64(x.Value) 617 case *ir.Int64Value: 618 bits = uint64(x.Value) 619 default: 620 panic(fmt.Errorf("%s: TODO %T", position(n), x)) 621 } 622 bits &= 1<<uint(members[j].Bits) - 1 623 bval |= bits << uint(members[j].BitOffsetOf) 624 iValue++ 625 } 626 627 if bval != 0 { 628 switch { 629 case bval > math.MaxUint32: 630 val = &ir.Int64Value{Value: int64(bval)} 631 default: 632 val = &ir.Int32Value{Value: int32(bval)} 633 } 634 } 635 636 // The bit field group has zero value. 637 values[iField] = val 638 iField++ 639 continue 640 } 641 642 // Normal field. 643 values[iField] = values[iValue] 644 iValue++ 645 iField++ 646 } 647 values = values[:iField] 648 w := -1 649 for i, v := range values { 650 if v != nil { 651 w = i 652 } 653 } 654 values = values[:w+1] 655 return &ir.CompositeValue{Values: values}, complete 656 } 657 658 func (c *c) initializerList(t cc.Type, n *cc.InitializerList) (ir.Value, bool) { 659 switch t.Kind() { 660 case cc.Array, cc.Ptr: 661 return c.arrayInitializerList(t, n) 662 case cc.Struct, cc.Union: 663 return c.structInitializerList(t, n) 664 default: 665 panic(fmt.Errorf("%s: internal error %v %v %v", position(n), t, t.Kind(), n.Len())) 666 } 667 } 668 669 func (c *c) initializerExpr(n *cc.Expression) ir.Value { 670 switch x := n.Value.(type) { 671 case nil: 672 switch n.Case { 673 case 29: // Expression '+' Expression // Case 29 674 if n.Expression.Value != nil && n.Expression2 != nil { 675 switch a := c.initializerExpr(n.Expression).(type) { 676 case *ir.StringValue: 677 switch x := n.Expression2.Value.(type) { 678 case int32: 679 a.Offset += uintptr(x) 680 return a 681 default: 682 panic(fmt.Errorf("%s: %T", position(n), x)) 683 } 684 default: 685 panic(fmt.Errorf("%s: %T", position(n), a)) 686 } 687 } 688 default: 689 if val := c.addressInitializer(n); val != nil { 690 return val 691 } 692 } 693 694 return nil 695 case cc.StringLitID: 696 return &ir.StringValue{StringID: ir.StringID(x)} 697 case cc.LongStringLitID: 698 return &ir.WideStringValue{Value: []rune(string(dict.S(int(x))))} 699 case int8: 700 return &ir.Int32Value{Value: int32(x)} 701 case uint8: 702 return &ir.Int32Value{Value: int32(x)} 703 case int16: 704 return &ir.Int32Value{Value: int32(x)} 705 case uint16: 706 return &ir.Int32Value{Value: int32(x)} 707 case int32: 708 return &ir.Int32Value{Value: x} 709 case uint32: 710 if x <= math.MaxInt32 { 711 return &ir.Int32Value{Value: int32(x)} 712 } 713 714 return &ir.Int64Value{Value: int64(x)} 715 case int64: 716 switch { 717 case x >= math.MinInt32 && x <= math.MaxInt32: 718 return &ir.Int32Value{Value: int32(x)} 719 default: 720 return &ir.Int64Value{Value: x} 721 } 722 case float32: 723 return &ir.Float32Value{Value: x} 724 case float64: 725 return &ir.Float64Value{Value: x} 726 case uint64: 727 switch { 728 case x <= math.MaxInt32: 729 return &ir.Int32Value{Value: int32(x)} 730 default: 731 return &ir.Int64Value{Value: int64(x)} 732 } 733 case uintptr: 734 switch { 735 case x <= math.MaxInt32: 736 return &ir.Int32Value{Value: int32(x)} 737 default: 738 return &ir.Int64Value{Value: int64(x)} 739 } 740 case complex64: 741 return &ir.Complex64Value{Value: x} 742 case complex128: 743 return &ir.Complex128Value{Value: x} 744 case cc.ComputedGotoID: 745 return &ir.AddressValue{NameID: c.f.f.NameID, Linkage: c.f.f.Linkage, Label: ir.NameID(x), Index: -1} 746 default: 747 TODO(position(n), fmt.Sprintf(" %T", x)) 748 } 749 panic("unreachable") 750 } 751 752 func (c *c) initializer(t cc.Type, n *cc.Initializer, ok bool) (ir.Value, *cc.Initializer) { 753 if n == nil { 754 return nil, nil 755 } 756 757 switch n.Case { 758 case 0: // Expression 759 if val := c.initializerExpr(n.Expression); val != nil { 760 return val, nil 761 } 762 763 return nil, n 764 case 1: // '{' InitializerList CommaOpt '}' // Case 1 765 init := n 766 val, ok := c.initializerList(t, n.InitializerList) 767 if ok { 768 init = nil 769 } 770 771 return val, init 772 case 2: // IDENTIFIER ':' Initializer // Case 2 773 if ok { 774 return c.initializer(t, n.Initializer, false) 775 } 776 777 TODO(position(n), t) 778 } 779 panic("internal error") 780 } 781 782 func (c *c) exprInitializerListStructField(v []ir.Operation, t, ft cc.Type, pt ir.Type, i, nm int, n *cc.InitializerList) int { 783 if o := n.DesignationOpt; o != nil { 784 l := o.Designation.DesignatorList 785 if l.DesignatorList != nil { 786 TODO(position(n)) 787 } 788 789 outer: 790 switch d := l.Designator; d.Case { 791 case 0: // '[' ConstantExpression ']' 792 panic("internal error") 793 case 1: // '.' IDENTIFIER // Case 1 794 nm = d.Token2.Val 795 members := c.members(t, true, false) 796 for j, v := range members { 797 if v.Name == nm { 798 i = j 799 ft = v.Type 800 break outer 801 } 802 } 803 804 panic("internal error") 805 default: 806 panic("internal error") 807 } 808 } 809 810 fi, bits, bitoff, ft2, vt := c.field(n, t, nm) 811 v = append(v, &ir.Field{Address: true, TypeID: pt.ID(), Index: fi, Position: position(n)}) 812 if vt := c.typ(n, vt); vt.Kind() == ir.Array { 813 pt := c.typ(n, t).(*ir.StructOrUnionType).Fields[fi].Pointer() 814 vt = vt.(*ir.ArrayType).Item.Pointer() 815 v = append(v, &ir.Convert{TypeID: pt.ID(), Result: vt.ID(), Position: position(n)}) 816 } 817 818 switch init := n.Initializer; init.Case { 819 case 0: // Expression 820 for _, v := range v { 821 c.emit(v) 822 } 823 if bits != 0 { 824 c.expression(ft2, init.Expression) 825 ftid := c.typ(n, ft2).ID() 826 c.emit(&ir.Store{Bits: bits, BitOffset: bitoff, TypeID: ftid, Position: position(init)}) 827 c.emit(&ir.Drop{TypeID: ftid, Position: position(init)}) 828 break 829 } 830 831 c.expression(ft, init.Expression) 832 c.emit(&ir.Store{TypeID: c.typ(n, ft).ID(), Position: position(init)}) 833 c.emit(&ir.Drop{TypeID: c.typ(n, ft).ID(), Position: position(init)}) 834 case 1: // '{' InitializerList CommaOpt '}' // Case 1 835 switch ft.Kind() { 836 case cc.Array: 837 pt := c.typ(n, ft.Element().Pointer()) 838 c.exprInitializerArray(v, ft, pt, init.InitializerList) 839 case cc.Struct: 840 c.exprInitializerStruct(v, t, c.typ(n, t).Pointer(), init.InitializerList) 841 default: 842 panic(fmt.Errorf("%s: %v:%v", position(n.Initializer), ft, ft.Kind())) 843 } 844 default: 845 panic(fmt.Errorf("%s: internal error %v, %v, %v, %v, %v, %q", position(init), init.Case, t, ft, pt, i, dict.S(nm))) 846 } 847 i++ 848 return i 849 } 850 851 func (c *c) exprInitializerListArrayElement(v []ir.Operation, t, et cc.Type, pt ir.Type, i int, n *cc.InitializerList) int { 852 if o := n.DesignationOpt; o != nil { 853 TODO(position(n)) 854 } 855 856 v = append( 857 v, 858 &ir.Const32{TypeID: idInt32, Value: int32(i), Position: position(n)}, 859 &ir.Element{Address: true, IndexType: idInt32, TypeID: c.typ(n, et.Pointer()).ID(), Position: position(n)}, 860 ) 861 switch init := n.Initializer; init.Case { 862 case 0: // Expression 863 for _, v := range v { 864 c.emit(v) 865 } 866 c.expression(et, init.Expression) 867 c.emit(&ir.Store{TypeID: c.typ(n, et).ID(), Position: position(init)}) 868 c.emit(&ir.Drop{TypeID: c.typ(n, et).ID(), Position: position(init)}) 869 case 1: // '{' InitializerList CommaOpt '}' // Case 1 870 switch et.Kind() { 871 case cc.Struct: 872 c.exprInitializerStruct(v, et, pt, init.InitializerList) 873 default: 874 panic(fmt.Errorf("%s: %v, %v, %v", position(n.Initializer), t, et, pt)) 875 } 876 default: 877 panic("internal error") 878 } 879 i++ 880 return i 881 } 882 883 func (c *c) exprInitializerStruct(v []ir.Operation, t cc.Type, pt ir.Type, l *cc.InitializerList) { 884 i := 0 885 ma := c.members(t, true, false) 886 for ; l != nil; l = l.InitializerList { 887 i = c.exprInitializerListStructField(v, t, ma[i].Type, pt, i, ma[i].Name, l) 888 } 889 } 890 891 func (c *c) exprInitializerArray(v []ir.Operation, t cc.Type, pt ir.Type, l *cc.InitializerList) { 892 e := t.Element() 893 i := 0 894 for ; l != nil; l = l.InitializerList { 895 i = c.exprInitializerListArrayElement(v, t, e, pt, i, l) 896 } 897 } 898 899 func (c *c) exprInitializerList(t cc.Type, vi int, vp token.Position, l *cc.InitializerList) { 900 var pt ir.Type 901 switch t.Kind() { 902 case cc.Struct, cc.Union: 903 pt = c.typ(l, t).Pointer() 904 v := &ir.Variable{Address: true, Index: vi, TypeID: pt.ID(), Position: vp} 905 c.exprInitializerStruct([]ir.Operation{v}, t, pt, l) 906 case cc.Array: 907 pt = c.typ(l, t.Element().Pointer()) 908 ops := []ir.Operation{ 909 &ir.Variable{Address: true, Index: vi, TypeID: c.typ(l, t.Pointer()).ID(), Position: vp}, 910 &ir.Convert{TypeID: c.typ(l, t.Pointer()).ID(), Result: pt.ID(), Position: vp}, 911 } 912 c.exprInitializerArray(ops, t, pt, l) 913 default: 914 TODO(position(l.Initializer), t.Kind()) 915 } 916 } 917 918 func (c *c) staticDeclaration(d *cc.Declarator, l *cc.InitDeclaratorList, doc ir.NameID) { 919 typ := c.typ(l, d.Type).ID() 920 val, init := c.initializer(l.InitDeclarator.Declarator.Type, l.InitDeclarator.Initializer, false) 921 var b buffer.Bytes 922 // func\x00varname\x00index 923 b.Write(dict.S(int(c.f.f.NameID))) 924 b.WriteByte(0) 925 b.Write(dict.S(int(c.nm(d)))) 926 b.WriteByte(0) 927 fmt.Fprintf(&b, "%v", c.f.static) 928 snm := ir.NameID(dict.ID(b.Bytes())) 929 c.f.statics[c.nm(d)] = snm 930 b.Close() 931 c.f.variables[d] = varInfo{index: c.f.static, static: true, typ: typ, staticName: snm} 932 dd := ir.NewDataDefinition(position(d), snm, c.tnm(d), typ, ir.InternalLinkage, val) 933 dd.Comment = doc 934 c.out = append(c.out, dd) 935 c.f.static++ 936 if init != nil { 937 TODO(position(init)) 938 } 939 } 940 941 func (c *c) isStaticInitializer(t cc.Type, n *cc.Initializer, list bool) bool { 942 if n == nil { 943 return true 944 } 945 946 switch n.Case { 947 case 0: // Expression 948 switch x := n.Expression.Value.(type) { 949 case nil: 950 return false 951 case cc.StringLitID: 952 return !list && t != nil && t.Kind() == cc.Array 953 case int32, uint32, int64, uint64, float32, float64, complex64, complex128, uintptr: 954 return true 955 case cc.ComputedGotoID: 956 return true 957 default: 958 panic(fmt.Errorf("%s: TODO %T", position(n), x)) 959 } 960 case 1: // '{' InitializerList CommaOpt '}' // Case 1 961 for l := n.InitializerList; l != nil; l = l.InitializerList { 962 if !c.isStaticInitializer(t, l.Initializer, true) { 963 return false 964 } 965 } 966 967 return true 968 case 2: // IDENTIFIER ':' Initializer // Case 2 969 m, err := t.Member(n.Token.Val) 970 if err != nil { 971 panic(fmt.Errorf("%s: type %v has no member %s", position(n), t, dict.S(n.Token.Val))) 972 } 973 974 return c.isStaticInitializer(m.Type, n.Initializer, false) 975 } 976 panic("internal error") 977 } 978 979 func (c *c) isCompoundInitializer(n *cc.Initializer) bool { 980 return n != nil && n.Case == 1 // '{' InitializerList CommaOpt '}' // Case 1 981 } 982 983 func (c *c) variableDeclaration(d *cc.Declarator, l *cc.InitDeclaratorList, alwaysEvalInitializers bool) { 984 var val ir.Value 985 init := l.InitDeclarator.Initializer 986 if c.isCompoundInitializer(init) { 987 val = &ir.CompositeValue{} 988 } 989 if !alwaysEvalInitializers && c.isStaticInitializer(d.Type, init, false) { 990 val, init = c.initializer(l.InitDeclarator.Declarator.Type, init, false) 991 } 992 vx := c.f.variable 993 c.f.variable++ 994 typ := c.typ(d, d.Type).ID() 995 c.f.variables[d] = varInfo{index: vx, typ: typ} 996 c.emit(&ir.VariableDeclaration{Index: vx, NameID: c.nm(d), TypeID: typ, TypeName: c.tnm(d), Value: val, Position: position(d)}) 997 if init != nil { 998 switch init.Case { 999 case 0: // Expression 1000 pt := c.types.MustType(typ).Pointer().ID() 1001 c.emit(&ir.Variable{Address: true, Index: vx, TypeID: pt, Position: position(d)}) 1002 c.expression(d.Type, init.Expression) 1003 c.emit(&ir.Store{TypeID: typ, Position: position(d)}) 1004 c.emit(&ir.Drop{TypeID: typ, Position: position(d)}) 1005 case 1: // '{' InitializerList CommaOpt '}' // Case 1 1006 c.exprInitializerList(d.Type, vx, position(init), init.InitializerList) 1007 default: 1008 panic("internal error") 1009 } 1010 } 1011 } 1012 1013 func (c *c) declaration(n *cc.Declaration, alwaysEvalInitializers bool) { 1014 switch n.Case { 1015 case 0: // DeclarationSpecifiers InitDeclaratorListOpt ';' 1016 if n.DeclarationSpecifiers.IsTypedef() { 1017 return 1018 } 1019 1020 o := n.InitDeclaratorListOpt 1021 if o == nil { 1022 break 1023 } 1024 1025 doc := c.comment(n.Pos(), n.DeclarationSpecifiers.Pos()) 1026 for l := o.InitDeclaratorList; l != nil; l = l.InitDeclaratorList { 1027 d := l.InitDeclarator.Declarator 1028 id, _ := d.Identifier() 1029 isFunc := d.Type.Kind() == cc.Function 1030 if isFunc && virtual.IsBuiltin(ir.NameID(id)) { 1031 if _, ok := c.builtins[ir.NameID(id)]; ok { 1032 continue 1033 } 1034 1035 f := ir.NewFunctionDefinition(position(d), c.nm(d), c.tnm(d), c.typ(n, d.Type).ID(), c.linkage(d.Linkage), c.fnArgNames(d), nil) 1036 f.Comment = doc 1037 f.Body = []ir.Operation{&ir.Panic{Position: position(d)}} 1038 c.out = append(c.out, f) 1039 c.builtins[ir.NameID(id)] = struct{}{} 1040 continue 1041 } 1042 1043 if d.Type.Specifier().IsExtern() || isFunc { 1044 continue 1045 } 1046 1047 switch ln := c.linkage(d.Linkage); { 1048 case ln < 0: // linkage none 1049 if d.RawSpecifier().IsStatic() { 1050 c.staticDeclaration(d, l, doc) 1051 break 1052 } 1053 1054 c.variableDeclaration(d, l, alwaysEvalInitializers) 1055 default: // external, internal 1056 val, init := c.initializer(l.InitDeclarator.Declarator.Type, l.InitDeclarator.Initializer, false) 1057 if init != nil { 1058 TODO(position(init), val, c.typ(n, d.Type)) 1059 } 1060 1061 dd := ir.NewDataDefinition(position(d), c.nm(d), c.tnm(d), c.typ(n, d.Type).ID(), ln, val) 1062 dd.Comment = doc 1063 c.out = append(c.out, dd) 1064 } 1065 } 1066 case 1: // StaticAssertDeclaration // Case 1 1067 TODO(position(n)) 1068 default: 1069 panic("internal error") 1070 } 1071 } 1072 1073 func (c *c) newFData(t cc.Type, f *ir.FunctionDefinition) { 1074 variables := map[*cc.Declarator]varInfo{} 1075 params, _ := t.Parameters() 1076 f.Arguments = make([]ir.NameID, len(params)) 1077 for i, v := range params { 1078 f.Arguments[i] = ir.NameID(v.Name) 1079 variables[v.Declarator] = varInfo{index: i, arg: true, typ: c.typ(t.Declarator(), v.Type).ID()} 1080 } 1081 typ := c.types.MustType(f.TypeID).(*ir.FunctionType) 1082 var result ir.TypeID 1083 if len(typ.Results) != 0 { 1084 result = typ.Results[0].ID() 1085 c.typ(t.Declarator(), t.Result()) 1086 } 1087 arguments := make([]ir.TypeID, len(typ.Arguments)) 1088 for i, v := range typ.Arguments { 1089 arguments[i] = v.ID() 1090 } 1091 cResult := t.Result() 1092 if cResult.Kind() == cc.Void && f.NameID == idMain && f.Linkage == ir.ExternalLinkage { 1093 cResult = c.cint 1094 } 1095 c.f = fdata{ 1096 arguments: arguments, 1097 cResult: cResult, 1098 f: f, 1099 result: result, 1100 statics: map[ir.NameID]ir.NameID{}, 1101 variables: variables, 1102 } 1103 } 1104 1105 func (c *c) emit(op ir.Operation) { 1106 switch y := op.(type) { 1107 case *ir.Convert: 1108 if y.TypeID == y.Result { 1109 return 1110 } 1111 1112 n := len(c.f.f.Body) 1113 switch x := c.f.f.Body[n-1].(type) { 1114 case *ir.Convert: 1115 switch from := c.types.MustType(x.TypeID); from.Kind() { 1116 case ir.Pointer: 1117 switch y.Result { 1118 default: 1119 switch to := c.types.MustType(y.Result); to.Kind() { 1120 case ir.Pointer: 1121 x.Result = y.Result 1122 if x.Result == x.TypeID { 1123 c.f.f.Body = c.f.f.Body[:n-1] 1124 } 1125 return 1126 } 1127 } 1128 } 1129 } 1130 } 1131 c.f.f.Body = append(c.f.f.Body, op) 1132 } 1133 1134 func (c *c) arguments(f cc.Type, n *cc.ArgumentExpressionListOpt) int { 1135 args := 0 1136 if n != nil { 1137 for l := n.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 1138 args++ 1139 } 1140 } 1141 c.emit(&ir.Arguments{Position: position(n)}) 1142 p, _ := f.Parameters() 1143 if n != nil { 1144 i := 0 1145 for l := n.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 1146 var pt cc.Type 1147 if i < len(p) { 1148 pt = p[i].Type 1149 if isOpenMDArray(pt) { 1150 et := c.typ(n, c.expression(nil, l.Expression)) 1151 eet := et.(*ir.PointerType).Element 1152 eet = c.types.MustType(ir.TypeID(dict.ID(append([]byte("[0]"), dict.S(int(eet.ID()))...)))) 1153 c.convert2(l.Expression, et, eet.Pointer()) 1154 i++ 1155 continue 1156 } 1157 1158 if pt := c.typ(n, pt); pt.Kind() == ir.Array { 1159 et := c.expression(nil, l.Expression) 1160 c.convert2(l.Expression, c.typ(n, et), pt.Pointer()) 1161 i++ 1162 continue 1163 } 1164 } 1165 1166 if pt == nil { // 6.5.2.2/6 1167 switch l.Expression.Type.Kind() { 1168 case cc.Char, cc.SChar, cc.UChar, cc.Short, cc.UShort: 1169 pt = c.cint 1170 case cc.Float: 1171 pt = c.ast.Model.DoubleType 1172 } 1173 } 1174 1175 c.expression2(nil, l.Expression, l.Expression.Case == 0 || l.Expression.Case == 8) 1176 et := c.typ(n, l.Expression.Type) 1177 switch { 1178 case et.Kind() == ir.Function: 1179 et = et.Pointer() 1180 case et.Kind() == ir.Array: 1181 et = et.(*ir.ArrayType).Item.Pointer() 1182 case et.Kind() == ir.Pointer: 1183 if v := et.(*ir.PointerType).Element; v.Kind() == ir.Array { 1184 if l.Expression.Case != 0 { 1185 et = v.(*ir.ArrayType).Item.Pointer() 1186 break 1187 } 1188 } 1189 } 1190 if pt != nil { 1191 c.convert2(l.Expression, et, c.typ(n, pt)) 1192 } 1193 i++ 1194 } 1195 } 1196 return args 1197 } 1198 1199 func (c *c) dd(b *cc.Bindings, n cc.Node, nm int) (*cc.DirectDeclarator, *cc.Bindings) { 1200 switch x, s := b.Lookup2(cc.NSIdentifiers, nm); x := x.Node.(type) { 1201 case *cc.DirectDeclarator: 1202 return x, s 1203 case nil: 1204 var buf buffer.Bytes 1205 buf.Write(dict.S(idBuiltinPrefix)) 1206 buf.Write(dict.S(nm)) 1207 nm2 := dict.ID(buf.Bytes()) 1208 buf.Close() 1209 switch x, s := b.Lookup2(cc.NSIdentifiers, nm2); x := x.Node.(type) { 1210 case *cc.DirectDeclarator: 1211 return x, s 1212 } 1213 1214 panic(fmt.Errorf("%s: undefined %s", position(n), dict.S(nm))) 1215 default: 1216 panic(fmt.Errorf("%s: internal error %T", position(n), x)) 1217 } 1218 } 1219 1220 func (c *c) promoteBitfield(t cc.Type, bits int) cc.Type { 1221 if bits != 0 { 1222 if bits < c.cint.SizeOf()*8 { 1223 return c.cint 1224 } 1225 } 1226 1227 return t 1228 } 1229 1230 func (c *c) normalize(n *cc.Expression) (_ *cc.Expression, t cc.Type) { 1231 if n == nil { 1232 panic(fmt.Errorf("internal error")) 1233 } 1234 1235 for { 1236 switch n.Case { 1237 case 7: // '(' ExpressionList ')' 1238 l := n.ExpressionList 1239 if l.Len() != 1 { 1240 return n, n.Type 1241 } 1242 1243 n = l.Expression 1244 default: 1245 var bits int 1246 t = n.Type 1247 if n.Value != nil { 1248 return n, t 1249 } 1250 1251 switch n.Case { 1252 case 0: // IDENTIFIER 1253 if x, _ := c.dd(n.IdentResolutionScope(), n, n.Token.Val); x != nil { 1254 n.Type = x.TopDeclarator().Type 1255 return n, n.Type 1256 } 1257 1258 nm := n.Token.Val 1259 panic(fmt.Errorf("%s: undefined %s", position(n), dict.S(nm))) 1260 case 9: // Expression '(' ArgumentExpressionListOpt ')' // Case 9 1261 _, t = c.normalize(n.Expression) 1262 if t.Kind() == cc.Ptr { 1263 t = t.Element() 1264 } 1265 t = t.Result() 1266 n.Type = t 1267 case 10: // Expression '.' IDENTIFIER // Case 10 1268 _, bits, _, _, t = c.field(n, n.Expression.Type, n.Token2.Val) 1269 t = c.promoteBitfield(t, bits).SetBits(bits) 1270 case 11: // Expression "->" IDENTIFIER // Case 11 1271 _, bits, _, _, t = c.field(n, n.Expression.Type.Element(), n.Token2.Val) 1272 t = c.promoteBitfield(t, bits).SetBits(bits) 1273 case 1274 26, // Expression '*' Expression // Case 26 1275 27, // Expression '/' Expression // Case 27 1276 28, // Expression '%' Expression // Case 28 1277 29, // Expression '+' Expression // Case 29 1278 30, // Expression '-' Expression // Case 30 1279 39, // Expression '&' Expression // Case 39 1280 40, // Expression '^' Expression // Case 40 1281 41: // Expression '|' Expression // Case 41 1282 t = c.binopType(n) 1283 case 1284 31, // Expression "<<" Expression // Case 31 1285 32: // Expression ">>" Expression // Case 32 1286 _, u := c.normalize(n.Expression) 1287 t = c.ast.Model.BinOpType(u, u) 1288 if w, bits := u.SizeOf()*8, u.Bits(); w > bits { 1289 t = t.SetBits(bits) 1290 } 1291 case 1292 46, // Expression "*=" Expression // Case 46 1293 47, // Expression "/=" Expression // Case 47 1294 48, // Expression "%=" Expression // Case 48 1295 49, // Expression "+=" Expression // Case 49 1296 50, // Expression "-=" Expression // Case 50 1297 51, // Expression "<<=" Expression // Case 51 1298 52, // Expression ">>=" Expression // Case 52 1299 53, // Expression "&=" Expression // Case 53 1300 54, // Expression "^=" Expression // Case 54 1301 55: // Expression "|=" Expression // Case 55 1302 _, t = c.normalize(n.Expression) 1303 } 1304 return n, t 1305 } 1306 } 1307 } 1308 1309 func (c *c) field(n cc.Node, st cc.Type, nm int) (index, bits, bitoff int, bitFieldType, valueType cc.Type) { 1310 ms := c.members(st, false, false) 1311 1312 //dbg("==== %s: %v %q", position(n), st, dict.S(nm)) 1313 //for _, v := range ms { 1314 //dbg("\t%#v", v) 1315 //} 1316 1317 groups := -1 1318 for _, v := range ms { 1319 if v.Name == nm { 1320 if v.Bits != 0 { 1321 if v.BitFieldType == nil { 1322 v.BitFieldType = c.cint 1323 } 1324 if v.Type == nil { 1325 v.Type = c.cint 1326 } 1327 return index + v.BitFieldGroup, v.Bits, v.BitOffsetOf, v.BitFieldType, v.Type 1328 } 1329 1330 return index + groups + 1, 0, 0, nil, v.Type 1331 } 1332 1333 switch { 1334 case v.Bits != 0: 1335 groups = v.BitFieldGroup 1336 default: 1337 index++ 1338 } 1339 } 1340 panic(fmt.Errorf("%s: internal error: %s", position(n), st)) 1341 } 1342 1343 func (c *c) compoundLiteral(n *cc.Expression) varInfo { 1344 t := n.TypeName.Type 1345 typ := c.typ(n, t).ID() 1346 vx := c.f.variable 1347 c.f.variable++ 1348 nfo := varInfo{index: vx, typ: typ} 1349 c.emit(&ir.VariableDeclaration{Index: vx, TypeID: typ, Position: position(n)}) 1350 c.exprInitializerList(t, vx, position(n), n.InitializerList) 1351 return nfo 1352 } 1353 1354 func (c *c) addr(n *cc.Expression) (bits, bitoff int, bfType, vtype cc.Type) { 1355 return c.addr2(n, false) 1356 } 1357 1358 func (c *c) addr2(n *cc.Expression, f bool) (bits, bitoff int, bfType, vtype cc.Type) { 1359 return c.addr3(n, false, false) 1360 } 1361 1362 func (c *c) addr3(n *cc.Expression, f, isEvaluatingFnArg bool) (bits, bitoff int, bfType, vtype cc.Type) { 1363 n, _ = c.normalize(n) 1364 if n.Value != nil { 1365 TODO(position(n)) 1366 return 0, 0, nil, nil 1367 } 1368 1369 switch n.Case { 1370 case 0: // IDENTIFIER 1371 id := n.Token.Val 1372 dd, s := c.dd(n.IdentResolutionScope(), n, id) 1373 d := dd.TopDeclarator() 1374 switch s.Scope() { 1375 case cc.ScopeBlock: 1376 switch vi, ok := c.f.variables[d]; { 1377 case !ok: 1378 t := d.Type 1379 for s.Scope() == cc.ScopeBlock { 1380 s = s.Parent 1381 } 1382 dd, _ := c.dd(s, n, id) 1383 d := dd.TopDeclarator() 1384 n.Type = d.Type 1385 switch d.Linkage { 1386 case cc.External: 1387 c.emit(&ir.Global{Address: true, Index: -1, Linkage: ir.ExternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t.Pointer()).ID(), TypeName: c.tnm(d), Position: position(n)}) 1388 default: 1389 c.emit(&ir.Global{Address: true, Index: -1, Linkage: ir.InternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t.Pointer()).ID(), TypeName: c.tnm(d), Position: position(n)}) 1390 } 1391 case vi.static: 1392 t, _ := c.types.Type(vi.typ) 1393 switch { 1394 case t.Kind() == ir.Array: 1395 c.emit(&ir.Global{Address: true, Index: -1, Linkage: ir.InternalLinkage, NameID: vi.staticName, TypeID: t.Pointer().ID(), Position: position(n)}) 1396 c.convert2(n, t.Pointer(), t.(*ir.ArrayType).Item.Pointer()) 1397 default: 1398 c.emit(&ir.Global{Address: true, Index: -1, Linkage: ir.InternalLinkage, NameID: vi.staticName, TypeID: t.Pointer().ID(), Position: position(n)}) 1399 } 1400 case vi.arg: 1401 at := c.f.arguments[vi.index] 1402 t := c.types.MustType(at) 1403 if t.Kind() == ir.Pointer { 1404 u := t.(*ir.PointerType).Element 1405 if u.Kind() == ir.Array && !f { 1406 c.emit(&ir.Argument{Index: vi.index, TypeID: t.ID(), Position: position(n)}) 1407 c.convert2(n, t, u.(*ir.ArrayType).Item.Pointer()) 1408 break 1409 } 1410 1411 if u.Kind() == ir.Function { 1412 c.emit(&ir.Argument{Index: vi.index, TypeID: t.ID(), Position: position(n)}) 1413 break 1414 } 1415 } 1416 1417 c.emit(&ir.Argument{Address: true, Index: vi.index, TypeID: t.Pointer().ID(), Position: position(n)}) 1418 default: 1419 t, _ := c.types.Type(vi.typ) 1420 switch { 1421 case t.Kind() == ir.Array: 1422 c.emit(&ir.Variable{Address: true, Index: vi.index, TypeID: t.Pointer().ID(), Position: position(n)}) 1423 c.convert2(n, t.Pointer(), t.(*ir.ArrayType).Item.Pointer()) 1424 default: 1425 c.emit(&ir.Variable{Address: true, Index: vi.index, TypeID: t.Pointer().ID(), Position: position(n)}) 1426 } 1427 } 1428 case cc.ScopeFile: 1429 t := d.Type 1430 if t.Kind() == cc.Array { 1431 c.emit(&ir.Global{Address: true, Index: -1, Linkage: c.linkage(d.Linkage), NameID: c.nm(d), TypeID: c.typ(n, t.Pointer()).ID(), TypeName: c.tnm(d), Position: position(n)}) 1432 c.convert(n, t.Pointer(), t.Element().Pointer()) 1433 break 1434 } 1435 1436 c.emit(&ir.Global{Address: true, Index: -1, Linkage: c.linkage(d.Linkage), NameID: c.nm(d), TypeID: c.typ(n, t.Pointer()).ID(), TypeName: c.tnm(d), Position: position(n)}) 1437 default: 1438 panic("internal error") 1439 } 1440 return 0, 0, nil, nil 1441 case 1: // CHARCONST // Case 1 1442 TODO(position(n)) 1443 case 2: // FLOATCONST // Case 2 1444 TODO(position(n)) 1445 case 3: // INTCONST // Case 3 1446 TODO(position(n)) 1447 case 4: // LONGCHARCONST // Case 4 1448 TODO(position(n)) 1449 case 5: // LONGSTRINGLITERAL // Case 5 1450 TODO(position(n)) 1451 case 6: // STRINGLITERAL // Case 6 1452 TODO(position(n)) 1453 case 7: // '(' ExpressionList ')' // Case 7 1454 TODO(position(n)) 1455 case 8: // Expression '[' ExpressionList ']' // Case 8 1456 _, t := c.expression3(nil, n.Expression, false) 1457 c.expressionList(nil, n.ExpressionList) 1458 c.emit(&ir.Element{Address: true, IndexType: c.typ(n, n.ExpressionList.Type).ID(), TypeID: t.ID(), Position: position(n)}) 1459 if t := t.(*ir.PointerType); t.Element.Kind() == ir.Array { 1460 c.convert2(n, t, t.Element.(*ir.ArrayType).Item.Pointer()) 1461 } 1462 return 0, 0, nil, nil 1463 case 9: // Expression '(' ArgumentExpressionListOpt ')' // Case 9 1464 TODO(position(n)) 1465 case 10: // Expression '.' IDENTIFIER // Case 10 1466 c.addr(n.Expression) 1467 fi, bits, bitoff, bt, vt := c.field(n, n.Expression.Type, n.Token2.Val) 1468 c.emit(&ir.Field{Address: true, Index: fi, TypeID: c.typ(n, n.Expression.Type.Pointer()).ID(), Position: position(n)}) 1469 pt := c.typ(n, n.Expression.Type).(*ir.StructOrUnionType) 1470 if bits == 0 { 1471 if g, e := pt.Fields[fi].Pointer(), c.typ(n, n.Type).Pointer(); g != e { 1472 switch { 1473 case n.Type.Kind() == cc.Array: 1474 c.convert2(n.Token, g, c.typ(n, vt).(*ir.ArrayType).Item.Pointer()) 1475 default: 1476 c.convert2(n, g, e) 1477 } 1478 } 1479 } 1480 return bits, bitoff, bt, vt 1481 case 11: // Expression "->" IDENTIFIER // Case 11 1482 c.expression(nil, n.Expression) 1483 fi, bits, bitoff, bt, vt := c.field(n, n.Expression.Type.Element(), n.Token2.Val) 1484 t := n.Expression.Type 1485 if t.Kind() == cc.Array { 1486 t = t.Element().Pointer() 1487 } 1488 c.emit(&ir.Field{Address: true, Index: fi, TypeID: c.typ(n, t).ID(), Position: position(n.Token2)}) 1489 pt := c.typ(n, t).(*ir.PointerType).Element.(*ir.StructOrUnionType) 1490 if bits == 0 { 1491 if g, e := pt.Fields[fi].Pointer(), c.typ(n, n.Type).Pointer(); g != e { 1492 switch { 1493 case n.Type.Kind() == cc.Array: 1494 c.convert2(n.Token, g, c.typ(n, vt).(*ir.ArrayType).Item.Pointer()) 1495 default: 1496 c.convert2(n, g, e) 1497 } 1498 } 1499 } 1500 return bits, bitoff, bt, vt 1501 case 12: // Expression "++" // Case 12 1502 TODO(position(n)) 1503 case 13: // Expression "--" // Case 13 1504 TODO(position(n)) 1505 case 14: // '(' TypeName ')' '{' InitializerList CommaOpt '}' // Case 14 1506 vi := c.compoundLiteral(n) 1507 t, _ := c.types.Type(vi.typ) 1508 switch { 1509 case t.Kind() == ir.Array: 1510 TODO("", position(n)) 1511 t = t.(*ir.ArrayType).Item.Pointer() 1512 default: 1513 t = t.Pointer() 1514 } 1515 c.emit(&ir.Variable{Address: true, Index: vi.index, TypeID: t.ID(), Position: position(n)}) 1516 return 0, 0, nil, nil 1517 case 15: // "++" Expression // Case 15 1518 TODO(position(n)) 1519 case 16: // "--" Expression // Case 16 1520 TODO(position(n)) 1521 case 17: // '&' Expression // Case 17 1522 TODO(position(n)) 1523 case 18: // '*' Expression // Case 18 1524 c.expression(nil, n.Expression) 1525 return 0, 0, nil, nil 1526 case 19: // '+' Expression // Case 19 1527 TODO(position(n)) 1528 case 20: // '-' Expression // Case 20 1529 TODO(position(n)) 1530 case 21: // '~' Expression // Case 21 1531 TODO(position(n)) 1532 case 22: // '!' Expression // Case 22 1533 TODO(position(n)) 1534 case 23: // "sizeof" Expression // Case 23 1535 TODO(position(n)) 1536 case 24: // "sizeof" '(' TypeName ')' // Case 24 1537 TODO(position(n)) 1538 case 25: // '(' TypeName ')' Expression // Case 25 1539 TODO(position(n)) 1540 case 26: // Expression '*' Expression // Case 26 1541 TODO(position(n)) 1542 case 27: // Expression '/' Expression // Case 27 1543 TODO(position(n)) 1544 case 28: // Expression '%' Expression // Case 28 1545 TODO(position(n)) 1546 case 29: // Expression '+' Expression // Case 29 1547 TODO(position(n)) 1548 case 30: // Expression '-' Expression // Case 30 1549 TODO(position(n)) 1550 case 31: // Expression "<<" Expression // Case 31 1551 TODO(position(n)) 1552 case 32: // Expression ">>" Expression // Case 32 1553 TODO(position(n)) 1554 case 33: // Expression '<' Expression // Case 33 1555 TODO(position(n)) 1556 case 34: // Expression '>' Expression // Case 34 1557 TODO(position(n)) 1558 case 35: // Expression "<=" Expression // Case 35 1559 TODO(position(n)) 1560 case 36: // Expression ">=" Expression // Case 36 1561 TODO(position(n)) 1562 case 37: // Expression "==" Expression // Case 37 1563 TODO(position(n)) 1564 case 38: // Expression "!=" Expression // Case 38 1565 TODO(position(n)) 1566 case 39: // Expression '&' Expression // Case 39 1567 TODO(position(n)) 1568 case 40: // Expression '^' Expression // Case 40 1569 TODO(position(n)) 1570 case 41: // Expression '|' Expression // Case 41 1571 TODO(position(n)) 1572 case 42: // Expression "&&" Expression // Case 42 1573 TODO(position(n)) 1574 case 43: // Expression "||" Expression // Case 43 1575 TODO(position(n)) 1576 case 44: // Expression '?' ExpressionList ':' Expression // Case 44 1577 switch n.Type.Kind() { 1578 case cc.Function: 1579 c.condExpr(n) 1580 default: 1581 TODO(position(n)) 1582 } 1583 return 0, 0, nil, nil 1584 case 45: // Expression '=' Expression // Case 45 1585 TODO(position(n)) 1586 case 46: // Expression "*=" Expression // Case 46 1587 TODO(position(n)) 1588 case 47: // Expression "/=" Expression // Case 47 1589 TODO(position(n)) 1590 case 48: // Expression "%=" Expression // Case 48 1591 TODO(position(n)) 1592 case 49: // Expression "+=" Expression // Case 49 1593 TODO(position(n)) 1594 case 50: // Expression "-=" Expression // Case 50 1595 TODO(position(n)) 1596 case 51: // Expression "<<=" Expression // Case 51 1597 TODO(position(n)) 1598 case 52: // Expression ">>=" Expression // Case 52 1599 TODO(position(n)) 1600 case 53: // Expression "&=" Expression // Case 53 1601 TODO(position(n)) 1602 case 54: // Expression "^=" Expression // Case 54 1603 TODO(position(n)) 1604 case 55: // Expression "|=" Expression // Case 55 1605 TODO(position(n)) 1606 case 56: // "_Alignof" '(' TypeName ')' // Case 56 1607 TODO(position(n)) 1608 case 57: // '(' CompoundStatement ')' // Case 57 1609 t := n.Type 1610 if t.Kind() == cc.Void { 1611 panic("internal error") 1612 } 1613 1614 c.compoundStatement(&labels{-1, -1, -1}, n.CompoundStatement, stmtExprAddress) 1615 return 0, 0, nil, nil 1616 } 1617 panic(fmt.Errorf("internal error: %v", position(n))) 1618 } 1619 1620 func (c *c) convert(n cc.Node, from, to cc.Type) cc.Type { 1621 c.convert2(n, c.typ(n, from), c.typ(n, to)) 1622 return to 1623 } 1624 1625 func (c *c) convert2(n cc.Node, from, to ir.Type) { 1626 if from.ID() != to.ID() { 1627 c.emit(&ir.Convert{TypeID: from.ID(), Result: to.ID(), Position: position(n)}) 1628 } 1629 } 1630 1631 func (c *c) constant(t cc.Type, v interface{}, n cc.Node) { 1632 if t.Kind() == cc.Void { 1633 return 1634 } 1635 1636 switch x := v.(type) { 1637 case int8: 1638 c.emit(&ir.Const32{TypeID: idInt8, Value: int32(x), Position: position(n)}) 1639 c.convert(n, c.ast.Model.CharType, t) 1640 case uint8: 1641 c.emit(&ir.Const32{TypeID: idUint8, Value: int32(x), Position: position(n)}) 1642 c.convert(n, c.ast.Model.UCharType, t) 1643 case int16: 1644 c.emit(&ir.Const32{TypeID: idInt16, Value: int32(x), Position: position(n)}) 1645 c.convert(n, c.ast.Model.ShortType, t) 1646 case uint16: 1647 c.emit(&ir.Const32{TypeID: idUint16, Value: int32(x), Position: position(n)}) 1648 c.convert(n, c.ast.Model.UShortType, t) 1649 case int32: 1650 c.emit(&ir.Const32{TypeID: idInt32, Value: x, Position: position(n)}) 1651 c.convert(n, c.cint, t) 1652 case uint32: 1653 c.emit(&ir.Const32{TypeID: idUint32, Value: int32(x), Position: position(n)}) 1654 c.convert(n, c.ast.Model.UIntType, t) 1655 case int64: 1656 c.emit(&ir.Const64{TypeID: idInt64, Value: x, Position: position(n)}) 1657 c.convert(n, c.ast.Model.LongLongType, t) 1658 case uint64: 1659 c.emit(&ir.Const64{TypeID: idUint64, Value: int64(x), Position: position(n)}) 1660 c.convert(n, c.ast.Model.ULongLongType, t) 1661 case float32: 1662 c.emit(&ir.Const32{TypeID: idFloat32, Value: int32(math.Float32bits(x)), Position: position(n)}) 1663 c.convert(n, c.ast.Model.FloatType, t) 1664 case float64: 1665 c.emit(&ir.Const64{TypeID: idFloat64, Value: int64(math.Float64bits(x)), Position: position(n)}) 1666 c.convert(n, c.ast.Model.DoubleType, t) 1667 case complex64: 1668 c.emit(&ir.Const64{TypeID: idComplex64, Value: int64(math.Float32bits(real(x)))<<32 | int64(math.Float32bits(imag(x))), Position: position(n)}) 1669 c.convert(n, c.ast.Model.FloatComplexType, t) 1670 case complex128: 1671 c.emit(&ir.ConstC128{TypeID: idComplex128, Value: x, Position: position(n)}) 1672 c.convert(n, c.ast.Model.DoubleComplexType, t) 1673 case cc.StringLitID: 1674 t0 := c.ast.Model.CharType.Pointer() 1675 c.emit(&ir.StringConst{Value: ir.StringID(x), TypeID: c.typ(n, t0).ID(), Position: position(n)}) 1676 c.convert(n, t0, t) 1677 case cc.LongStringLitID: 1678 t0 := c.cint.Pointer() 1679 c.emit(&ir.StringConst{Value: ir.StringID(x), TypeID: c.typ(n, t0).ID(), Position: position(n)}) 1680 c.convert(n, t0, t) 1681 case cc.ComputedGotoID: 1682 addr := &ir.Const{Value: &ir.AddressValue{Index: -1, NameID: c.f.f.NameID, Linkage: c.f.f.Linkage, Label: ir.NameID(x)}, TypeID: idVoidPtr, Position: position(n)} 1683 c.emit(addr) 1684 case uintptr: 1685 switch { 1686 case x == 0: 1687 switch { 1688 case t.Kind() == cc.Array: 1689 c.emit(&ir.Nil{TypeID: c.typ(n, t.Pointer()).ID(), Position: position(n)}) 1690 default: 1691 c.emit(&ir.Nil{TypeID: c.typ(n, t).ID(), Position: position(n)}) 1692 } 1693 default: 1694 switch { 1695 case mathutil.BitLenUintptr(x) <= 32: 1696 c.emit(&ir.Const32{TypeID: idUint32, Value: int32(x), Position: position(n)}) 1697 c.convert(n, c.ast.Model.UIntType, t) 1698 default: 1699 c.emit(&ir.Const64{TypeID: idUint64, Value: int64(x), Position: position(n)}) 1700 c.convert(n, c.ast.Model.ULongLongType, t) 1701 } 1702 } 1703 default: 1704 TODO(position(n), fmt.Sprintf(" %T", x)) 1705 } 1706 } 1707 1708 func (c *c) binopType(n *cc.Expression) cc.Type { 1709 //dbg("", position(n.Token), " e ", n.Expression.Type, " e2 ", n.Expression2.Type) 1710 a := n.Expression.Type 1711 b := n.Expression2.Type 1712 switch n.Token.Rune { 1713 case 1714 '%', 1715 '*', 1716 '+', 1717 '-', 1718 '/', 1719 '<', 1720 '>', 1721 cc.EQ, 1722 cc.GEQ, 1723 cc.LEQ, 1724 cc.NEQ: 1725 1726 n.Expression, a = c.normalize(n.Expression) 1727 n.Expression2, b = c.normalize(n.Expression2) 1728 case 1729 '&', 1730 '^', 1731 '|': 1732 1733 n.Expression, _ = c.normalize(n.Expression) 1734 n.Expression2, _ = c.normalize(n.Expression2) 1735 default: 1736 panic(fmt.Errorf("%q", string(n.Token.Rune))) 1737 } 1738 //dbg("", position(n.Token), " e ", n.Expression.Type, " e2 ", n.Expression2.Type, " a ", a, " b ", b) 1739 switch { 1740 case (a.Kind() == cc.Ptr || a.Kind() == cc.Array) && (b.Kind() == cc.Ptr || b.Kind() == cc.Array) && n.Case == 30: // Expression '-' Expression // Case 30 1741 return n.Type 1742 case a.Kind() == cc.Ptr: 1743 return a 1744 case a.Kind() == cc.Array: 1745 return a.Element().Pointer() 1746 case b.Kind() == cc.Ptr: 1747 return b 1748 case b.Kind() == cc.Array: 1749 return b.Element().Pointer() 1750 case a.Kind() == cc.Function: 1751 return a.Pointer() 1752 } 1753 1754 if cc.IsArithmeticType(a) && cc.IsArithmeticType(b) { 1755 t := c.ast.Model.BinOpType(a, b) 1756 if cc.IsIntType(t) { 1757 t = t.SetBits(mathutil.Max(a.Bits(), b.Bits())) 1758 } 1759 //dbg("", position(n.Token), a, " op ", b, " -> ", t) 1760 return t 1761 } 1762 1763 TODO(position(n.Token), n.Type, a, b) 1764 panic("internal error") 1765 } 1766 1767 func (c *c) binop(ot cc.Type, n *cc.Expression, op ir.Operation) cc.Type { 1768 if n.Value != nil { 1769 TODO(position(n)) 1770 } 1771 1772 t := c.binopType(n) 1773 //dbg("%s: ot %v, n.Type %v, e.Type %v, e2.Type %v, binopType %v", position(n.Token), ot, n.Type, n.Expression.Type, n.Expression2.Type, t) 1774 c.expression(t, n.Expression) 1775 c.expression(t, n.Expression2) 1776 c.emit(op) 1777 if cc.IsIntType(t) { 1778 if bits, b := c.ast.Model.Items[t.Kind()].Size*8, t.Bits(); b < bits { 1779 if isUnsigned(t) { 1780 c.bitField(n, b, 0, t, t) 1781 } 1782 } 1783 } 1784 if ot != nil { 1785 return c.convert(n, t, ot) 1786 } 1787 1788 return t 1789 } 1790 1791 func (c *c) relop(ot cc.Type, n *cc.Expression, op ir.Operation) cc.Type { 1792 t := c.binopType(n) 1793 //dbg("%s: ot %v, n.Type %v, e.Type %v, e2.Type %v, binopType %v", position(n.Token), ot, n.Type, n.Expression.Type, n.Expression2.Type, t) 1794 c.expression(t, n.Expression) 1795 c.expression(t, n.Expression2) 1796 c.emit(op) 1797 if ot != nil { 1798 return c.convert(n, t, ot) 1799 } 1800 1801 return c.cint 1802 } 1803 1804 func (c *c) asopType(n *cc.Expression) cc.Type { 1805 a, b := n.Expression.Type, n.Expression2.Type 1806 switch { 1807 case a.Kind() == cc.Ptr: 1808 return a 1809 case cc.IsArithmeticType(a) && cc.IsArithmeticType(b): 1810 return c.ast.Model.BinOpType(a, b) 1811 default: 1812 panic(fmt.Errorf("internal error (%v, %v)", a, b)) 1813 } 1814 } 1815 1816 func (c *c) asop(n *cc.Expression, op ir.Operation, more ...cc.Type) cc.Type { 1817 evalType := c.asopType(n) 1818 bits, bitoff, ft, bt := c.addr(n.Expression) 1819 switch { 1820 case bits != 0: 1821 c.emit(&ir.Dup{TypeID: c.typ(n, ft.Pointer()).ID(), Position: position(n.Expression)}) 1822 c.emit(&ir.Load{TypeID: c.typ(n, ft.Pointer()).ID(), Position: position(n)}) 1823 c.convert(n, c.bitField(n, bits, bitoff, ft, bt), evalType) 1824 default: 1825 pt := c.typ(n, n.Expression.Type.Pointer()).ID() 1826 c.emit(&ir.Dup{TypeID: pt, Position: position(n.Expression)}) 1827 c.emit(&ir.Load{TypeID: pt, Position: position(n)}) 1828 c.convert(n, n.Expression.Type, evalType) 1829 } 1830 switch { 1831 case n.Expression.Type.Kind() == cc.Ptr: 1832 c.expression(nil, n.Expression2) 1833 default: 1834 e2t := evalType 1835 if len(more) != 0 && more[0] != nil { 1836 e2t = more[0] 1837 } 1838 c.expression(e2t, n.Expression2) 1839 } 1840 c.emit(op) 1841 switch { 1842 case bits != 0: 1843 c.convert(n, evalType, ft) 1844 c.emit(&ir.Store{Bits: bits, BitOffset: bitoff, TypeID: c.typ(n, ft).ID(), Position: position(n)}) 1845 return c.bitField(n, bits, bitoff, ft, bt) 1846 default: 1847 c.convert(n, evalType, n.Expression.Type) 1848 c.emit(&ir.Store{TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n)}) 1849 return n.Expression.Type 1850 } 1851 } 1852 1853 func (c *c) shift(n *cc.Expression, op ir.Operation) cc.Type { 1854 _, t := c.normalize(n) 1855 c.expression(t, n.Expression) 1856 t2 := n.Expression2.Type 1857 t2 = c.ast.Model.BinOpType(t2, t2) 1858 c.expression(t2, n.Expression2) 1859 c.convert(n.Expression2, t2, c.ast.Model.IntType) 1860 c.emit(op) 1861 if w, b := t.SizeOf()*8, t.Bits(); b > 0 && b < w { 1862 c.bitField(n, b, 0, t, t) 1863 } 1864 return t 1865 } 1866 1867 func (c *c) call(n *cc.Expression) cc.Type { 1868 fe, _ := c.normalize(n.Expression) 1869 switch t := fe.Type; t.Kind() { 1870 case cc.Function: 1871 if r := t.Result(); r.Kind() != cc.Void { 1872 c.emit(&ir.AllocResult{TypeID: c.typ(n, r).ID(), TypeName: 0, Position: position(n)}) 1873 } 1874 c.expression(t.Pointer(), n.Expression) 1875 args := c.arguments(n.Expression.Type, n.ArgumentExpressionListOpt) 1876 c.emit(&ir.CallFP{Arguments: args, TypeID: c.typ(n, t.Pointer()).ID(), Position: position(n)}) 1877 return fe.Type.Result() 1878 case cc.Ptr: 1879 ft := t.Element() 1880 if ft.Kind() != cc.Function { 1881 panic("internal error") 1882 } 1883 1884 if r := ft.Result(); r.Kind() != cc.Void { 1885 c.emit(&ir.AllocResult{TypeID: c.typ(n, r).ID(), TypeName: 0, Position: position(n)}) 1886 } 1887 c.expression(t, n.Expression) 1888 args := c.arguments(ft, n.ArgumentExpressionListOpt) 1889 c.emit(&ir.CallFP{Arguments: args, TypeID: c.typ(n, t).ID(), Position: position(n)}) 1890 return ft.Result() 1891 default: 1892 TODO(position(n), t.Kind()) 1893 } 1894 panic("internal error") 1895 } 1896 1897 func (c *c) condExpr(n *cc.Expression) { 1898 //case 44: // Expression '?' ExpressionList ':' Expression // Case 44 1899 switch v := n.Expression.Value.(type) { 1900 case int32: 1901 if v != 0 { 1902 c.expressionList(nil, n.ExpressionList) 1903 break 1904 } 1905 1906 c.expression(nil, n.Expression2) 1907 case nil: 1908 // eval expr 1909 // convert to bool if necessary 1910 // jz 0 nop 1911 // eval exprlist 1912 // jmp 1 nop 1913 // 0: nop 1914 // eval expr2 1915 // 1: cond 1916 t := n.Type 1917 if t.Kind() == cc.Function { 1918 t = t.Pointer() 1919 } 1920 c.expression(nil, n.Expression) 1921 c.bool(n, n.Expression.Type) 1922 l0 := c.label() 1923 c.emit(&ir.Jz{Number: l0, Position: position(n.Expression), LOp: true}) 1924 u := c.expressionList(nil, n.ExpressionList) 1925 c.convert(n, u, t) 1926 l1 := c.label() 1927 c.emit(&ir.Jmp{Number: l1, Position: position(n), Cond: true}) 1928 c.emit(&ir.Label{Number: l0, Position: position(n), Nop: true}) 1929 u = c.expression(nil, n.Expression2) 1930 c.convert(n, u, t) 1931 c.emit(&ir.Label{Number: l1, Position: position(n), Cond: true}) 1932 default: 1933 TODO(position(n), fmt.Sprintf(" %T", v)) 1934 } 1935 } 1936 1937 func (c *c) condExpr2(n *cc.Expression) { 1938 // Expression '?' ':' Expression // Case 59 1939 switch v := n.Expression.Value.(type) { 1940 case nil: 1941 // eval expr 1942 // dup 1943 // convert to bool if necessary 1944 // jnz 0 1945 // drop 1946 // eval expr2 1947 // 0: 1948 t := n.Type 1949 tid := c.typ(n, t).ID() 1950 c.expression(t, n.Expression) 1951 c.emit(&ir.Dup{TypeID: tid, Position: position(n)}) 1952 c.bool(n, t) 1953 l0 := c.label() 1954 c.emit(&ir.Jnz{Number: l0, Position: position(n.Token)}) 1955 c.emit(&ir.Drop{TypeID: tid, Position: position(n.Token2)}) 1956 c.expression(n.Type, n.Expression2) 1957 c.emit(&ir.Label{Number: l0, Position: position(n)}) 1958 default: 1959 TODO(position(n), fmt.Sprintf(" %T", v)) 1960 } 1961 } 1962 1963 func (c *c) bitField(n cc.Node, bits, bitoff int, ft, bt cc.Type) cc.Type { 1964 if bitoff != 0 { 1965 c.constant(c.cint, int32(bitoff), n) 1966 c.emit(&ir.Rsh{TypeID: c.typ(n, ft).ID(), Position: position(n)}) 1967 } 1968 c.convert(n, ft, bt) 1969 w := c.ast.Model.Items[bt.Kind()].Size * 8 1970 c.constant(c.cint, int32(w-bits), n) 1971 c.emit(&ir.Lsh{TypeID: c.typ(n, bt).ID(), Position: position(n)}) 1972 c.constant(c.cint, int32(w-bits), n) 1973 c.emit(&ir.Rsh{TypeID: c.typ(n, bt).ID(), Position: position(n)}) 1974 return bt 1975 } 1976 1977 func (c *c) fieldBits(n *cc.Expression, fi, bits, bitoff int, ft, bt cc.Type) cc.Type { 1978 t := n.Expression.Type 1979 switch t.Kind() { 1980 case cc.Array: 1981 t = t.Element().Pointer() 1982 case cc.Ptr: 1983 // nop 1984 default: 1985 t = t.Pointer() 1986 } 1987 c.emit(&ir.Field{Index: fi, TypeID: c.typ(n, t).ID(), Position: position(n.Token2)}) 1988 return c.bitField(n, bits, bitoff, ft, bt) 1989 } 1990 1991 func (c *c) dbg(n cc.Node, s string, a ...interface{}) { 1992 c.emit(&ir.StringConst{Value: ir.StringID(dict.SID(fmt.Sprintf(s, a...))), TypeID: idInt8Ptr, Position: position(n)}) 1993 c.emit(&ir.Drop{TypeID: idInt8Ptr, Position: position(n)}) 1994 } 1995 1996 func (c *c) isArg(n *cc.Expression) bool { 1997 n, _ = c.normalize(n) 1998 switch n.Case { 1999 case 0: // IDENTIFIER 2000 id := n.Token.Val 2001 b, s := n.IdentResolutionScope().Lookup2(cc.NSIdentifiers, id) 2002 d := b.Node.(*cc.DirectDeclarator).TopDeclarator() 2003 switch s.Scope() { 2004 case cc.ScopeBlock: 2005 vi, ok := c.f.variables[d] 2006 return ok && vi.arg 2007 } 2008 } 2009 return false 2010 } 2011 2012 func (c *c) expression(ot cc.Type, n *cc.Expression) cc.Type { // rvalue 2013 return c.expression2(ot, n, false) 2014 } 2015 2016 func (c *c) expression2(ot cc.Type, n *cc.Expression, isEvaluatingFnArg bool) cc.Type { // rvalue 2017 cct, _ := c.expression3(ot, n, isEvaluatingFnArg) 2018 return cct 2019 } 2020 2021 func (c *c) expression3(ot cc.Type, n *cc.Expression, isEvaluatingFnArg bool) (cct cc.Type, irt ir.Type) { // rvalue 2022 defer func() { 2023 if irt == nil && cct != nil { 2024 irt = c.typ(n, cct) 2025 } 2026 }() 2027 2028 n, _ = c.normalize(n) 2029 if v := n.Value; v != nil && n.Case != 7 && // '(' ExpressionList ')' // Case 7 2030 n.Case != 44 { // Expression '?' ExpressionList ':' Expression // Case 44 2031 t := n.Type 2032 if ot != nil { 2033 t = ot 2034 } 2035 c.constant(t, v, n) 2036 return t, nil 2037 } 2038 2039 t := n.Type 2040 if t == nil { 2041 TODO(position(n)) 2042 } 2043 2044 switch t.Kind() { 2045 case cc.Function: 2046 c.addr(n) 2047 if ot != nil { 2048 c.convert2(n, c.typ(n, t).Pointer(), c.typ(n, ot)) 2049 } 2050 return t.Pointer(), nil 2051 } 2052 2053 out: 2054 switch { 2055 case ot != nil && ot.Kind() != t.Kind(): 2056 switch ot.Kind() { 2057 case cc.Void: 2058 if t := c.expression(nil, n); t.Kind() != cc.Void { 2059 c.emit(&ir.Drop{TypeID: c.typ(n, t).ID(), Position: position(n)}) 2060 } 2061 default: 2062 switch { 2063 case cc.IsArithmeticType(ot) && cc.IsArithmeticType(t): 2064 c.convert(n, c.expression(nil, n), ot) 2065 case ot.Kind() == cc.Ptr && t.Kind() == cc.Array: 2066 break out 2067 case ot.Kind() == cc.Ptr && cc.IsIntType(t) || cc.IsIntType(ot) && t.Kind() == cc.Ptr: 2068 c.expression(nil, n) 2069 c.convert(n, t, ot) 2070 case ot.Kind() == cc.Array && t.Kind() == cc.Ptr: 2071 c.expression(nil, n) 2072 return ot, nil 2073 2074 // TODO("", position(n)) 2075 // c.expression(nil, n) 2076 // c.convert(n, t, ot) 2077 default: 2078 TODO(fmt.Sprint(position(n), ot, ot.Kind(), t, t.Kind())) 2079 } 2080 } 2081 return ot, nil 2082 } 2083 2084 if ot != nil && ot.Kind() == cc.Ptr && t.Kind() == cc.Ptr { 2085 x := c.typ(n, t) 2086 y := c.typ(n, ot) 2087 c.expression(nil, n) 2088 c.convert2(n, x, y) 2089 return ot, nil 2090 } 2091 2092 switch t.Kind() { 2093 case cc.Array: 2094 if n.Case != 45 { // Expression '=' Expression // Case 45 2095 c.addr3(n, false, isEvaluatingFnArg) 2096 t2 := ot 2097 if t2 != nil && t2.Kind() == cc.Ptr { 2098 t2 = t2.Element() 2099 } 2100 if ot == nil || t2.Kind() == cc.Array { 2101 return t.Element().Pointer(), nil 2102 } 2103 2104 c.convert(n, t.Element().Pointer(), ot) 2105 return ot, nil 2106 } 2107 } 2108 2109 switch n.Case { 2110 case 0: // IDENTIFIER 2111 id := n.Token.Val 2112 b, s := n.IdentResolutionScope().Lookup2(cc.NSIdentifiers, id) 2113 d := b.Node.(*cc.DirectDeclarator).TopDeclarator() 2114 switch s.Scope() { 2115 case cc.ScopeBlock: 2116 switch vi, ok := c.f.variables[d]; { 2117 case !ok: 2118 t := d.Type 2119 if t.Kind() == cc.Function { 2120 c.addr(n) 2121 break 2122 } 2123 for s.Scope() == cc.ScopeBlock { 2124 s = s.Parent 2125 } 2126 dd, _ := c.dd(s, n, id) 2127 d := dd.TopDeclarator() 2128 n.Type = d.Type 2129 switch d.Linkage { 2130 case cc.External: 2131 c.emit(&ir.Global{Index: -1, Linkage: ir.ExternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t).ID(), TypeName: c.tnm(d), Position: position(n)}) 2132 default: 2133 c.emit(&ir.Global{Index: -1, Linkage: ir.InternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t).ID(), TypeName: c.tnm(d), Position: position(n)}) 2134 } 2135 case vi.static: 2136 t, _ := c.types.Type(vi.typ) 2137 if t.Kind() == ir.Array { 2138 TODO("", position(n)) 2139 t = t.(*ir.ArrayType).Item.Pointer() 2140 break 2141 } 2142 2143 c.emit(&ir.Global{Index: -1, Linkage: ir.InternalLinkage, NameID: vi.staticName, TypeID: t.ID(), Position: position(n)}) 2144 case vi.arg: 2145 at := c.f.arguments[vi.index] 2146 t := c.types.MustType(at) 2147 if t.Kind() == ir.Pointer { 2148 if u := t.(*ir.PointerType).Element; !isEvaluatingFnArg && u.Kind() == ir.Array { 2149 c.emit(&ir.Argument{Index: vi.index, TypeID: t.ID(), Position: position(n)}) 2150 u := u.(*ir.ArrayType).Item.Pointer() 2151 c.convert2(n, t, u) 2152 return n.Type.Element().Pointer(), u 2153 } 2154 } 2155 2156 c.emit(&ir.Argument{Index: vi.index, TypeID: c.f.arguments[vi.index], Position: position(n)}) 2157 default: 2158 c.emit(&ir.Variable{Index: vi.index, TypeID: vi.typ, Position: position(n)}) 2159 } 2160 case cc.ScopeFile: 2161 switch d.Linkage { 2162 case cc.External: 2163 c.emit(&ir.Global{Index: -1, Linkage: ir.ExternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t).ID(), TypeName: c.tnm(d), Position: position(n)}) 2164 default: 2165 c.emit(&ir.Global{Index: -1, Linkage: ir.InternalLinkage, NameID: c.nm(d), TypeID: c.typ(n, t).ID(), TypeName: c.tnm(d), Position: position(n)}) 2166 } 2167 default: 2168 panic("internal error") 2169 } 2170 case 2171 1, // CHARCONST // Case 1 2172 2, // FLOATCONST // Case 2 2173 3, // INTCONST // Case 3 2174 4, // LONGCHARCONST // Case 4 2175 5, // LONGSTRINGLITERAL // Case 5 2176 6: // STRINGLITERAL // Case 6 2177 2178 panic("internal error") 2179 case 7: // '(' ExpressionList ')' // Case 7 2180 return c.expressionList(n.Type, n.ExpressionList), nil 2181 case 8: // Expression '[' ExpressionList ']' // Case 8 2182 t := n.Expression.Type 2183 u := n.ExpressionList.Type 2184 switch { 2185 case (t.Kind() == cc.Ptr || t.Kind() == cc.Array) && cc.IsIntType(u): 2186 if t.Kind() == cc.Array { 2187 t = t.Element().Pointer() 2188 } 2189 c.expression2(nil, n.Expression, isEvaluatingFnArg) 2190 c.expressionList(nil, n.ExpressionList) 2191 c.emit(&ir.Element{IndexType: c.typ(n, u).ID(), TypeID: c.typ(n, t).ID(), Position: position(n)}) 2192 case (u.Kind() == cc.Ptr || u.Kind() == cc.Array) && cc.IsIntType(t): 2193 if u.Kind() == cc.Array { 2194 TODO("", position(n)) 2195 u = u.Element().Pointer() 2196 } 2197 c.expressionList(nil, n.ExpressionList) 2198 c.expression(nil, n.Expression) 2199 c.emit(&ir.Element{IndexType: c.typ(n, t).ID(), TypeID: c.typ(n, u).ID(), Position: position(n)}) 2200 default: 2201 panic("internal error") 2202 } 2203 case 9: // Expression '(' ArgumentExpressionListOpt ')' // Case 9 2204 return c.call(n), nil 2205 case 10: // Expression '.' IDENTIFIER // Case 10 2206 fi, bits, bitoff, ft, vt := c.field(n, n.Expression.Type, n.Token2.Val) 2207 if e, _ := c.normalize(n.Expression); e.Case == 9 { // Expression '(' ArgumentExpressionListOpt ')' // Case 9 2208 c.call(e) 2209 ct := c.typ(n, n.Expression.Type) 2210 c.emit(&ir.FieldValue{Index: fi, TypeID: ct.ID(), Position: position(n.Token2)}) 2211 cft := ct.(*ir.StructOrUnionType).Fields[fi] 2212 if cft.Kind() == ir.Pointer { 2213 if t := cft.(*ir.PointerType).Element; t.Kind() == ir.Struct || t.Kind() == ir.Union { 2214 c.convert2(n, cft, c.typ(n, vt)) 2215 } 2216 } 2217 break 2218 } 2219 2220 c.addr(n.Expression) 2221 if bits != 0 { 2222 return c.fieldBits(n, fi, bits, bitoff, ft, vt), nil 2223 } 2224 2225 c.emit(&ir.Field{Index: fi, TypeID: c.typ(n, n.Expression.Type.Pointer()).ID(), Position: position(n.Token2)}) 2226 pt := c.typ(n, n.Expression.Type).(*ir.StructOrUnionType) 2227 if g, e := pt.Fields[fi], c.typ(n, n.Type); g != e { 2228 c.convert2(n, g, e) 2229 } 2230 case 11: // Expression "->" IDENTIFIER // Case 11 2231 c.expression(nil, n.Expression) 2232 t := n.Expression.Type 2233 if t.Kind() == cc.Array { 2234 t = t.Element().Pointer() 2235 } 2236 fi, bits, bitoff, ft, vt := c.field(n, n.Expression.Type.Element(), n.Token2.Val) 2237 if bits != 0 { 2238 return c.fieldBits(n, fi, bits, bitoff, ft, vt), nil 2239 } 2240 2241 c.emit(&ir.Field{Index: fi, TypeID: c.typ(n, t).ID(), Position: position(n.Token2)}) 2242 pt := c.typ(n, t).(*ir.PointerType).Element.(*ir.StructOrUnionType) 2243 if g, e := pt.Fields[fi], c.typ(n, n.Type); g != e { 2244 c.convert2(n, g, e) 2245 } 2246 case 12: // Expression "++" // Case 12 2247 bits, bitoff, bft, vt := c.addr(n.Expression) 2248 if bits != 0 { 2249 c.emit(&ir.PostIncrement{Bits: bits, BitOffset: bitoff, BitFieldType: c.typ(n, vt).ID(), Delta: 1, TypeID: c.typ(n, bft).ID(), Position: position(n)}) 2250 break 2251 } 2252 2253 delta := 1 2254 if t := n.Expression.Type; t.Kind() == cc.Ptr { 2255 delta = t.Element().SizeOf() 2256 } 2257 c.emit(&ir.PostIncrement{Delta: delta, TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n)}) 2258 case 13: // Expression "--" // Case 13 2259 bits, bitoff, bft, vt := c.addr(n.Expression) 2260 if bits != 0 { 2261 c.emit(&ir.PostIncrement{Bits: bits, BitOffset: bitoff, BitFieldType: c.typ(n, vt).ID(), Delta: -1, TypeID: c.typ(n, bft).ID(), Position: position(n)}) 2262 break 2263 } 2264 2265 delta := 1 2266 if t := n.Expression.Type; t.Kind() == cc.Ptr { 2267 delta = t.Element().SizeOf() 2268 } 2269 c.emit(&ir.PostIncrement{Delta: -delta, TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n)}) 2270 case 14: // '(' TypeName ')' '{' InitializerList CommaOpt '}' // Case 14 2271 vi := c.compoundLiteral(n) 2272 t, _ := c.types.Type(vi.typ) 2273 switch { 2274 case t.Kind() == ir.Array: 2275 TODO("", position(n)) 2276 t = t.(*ir.ArrayType).Item.Pointer() 2277 } 2278 c.emit(&ir.Variable{Index: vi.index, TypeID: t.ID(), Position: position(n)}) 2279 case 15: // "++" Expression // Case 15 2280 bits, bitoff, bft, vt := c.addr(n.Expression) 2281 if bits != 0 { 2282 c.emit(&ir.PreIncrement{Bits: bits, BitOffset: bitoff, BitFieldType: c.typ(n, vt).ID(), Delta: 1, TypeID: c.typ(n, bft).ID(), Position: position(n)}) 2283 break 2284 } 2285 2286 delta := 1 2287 if t := n.Expression.Type; t.Kind() == cc.Ptr { 2288 delta = t.Element().SizeOf() 2289 } 2290 c.emit(&ir.PreIncrement{Delta: delta, TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n)}) 2291 case 16: // "--" Expression // Case 16 2292 bits, bitoff, bft, vt := c.addr(n.Expression) 2293 if bits != 0 { 2294 c.emit(&ir.PreIncrement{Bits: bits, BitOffset: bitoff, BitFieldType: c.typ(n, vt).ID(), Delta: -1, TypeID: c.typ(n, bft).ID(), Position: position(n)}) 2295 break 2296 } 2297 2298 delta := 1 2299 if t := n.Expression.Type; t.Kind() == cc.Ptr { 2300 delta = t.Element().SizeOf() 2301 } 2302 c.emit(&ir.PreIncrement{Delta: -delta, TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n)}) 2303 case 17: // '&' Expression // Case 17 2304 c.addr(n.Expression) 2305 case 18: // '*' Expression // Case 18 2306 c.expression(n.Type.Pointer(), n.Expression) 2307 c.emit(&ir.Load{TypeID: c.typ(n, n.Type.Pointer()).ID(), Position: position(n)}) 2308 case 19: // '+' Expression // Case 19 2309 TODO(position(n)) 2310 case 20: // '-' Expression // Case 20 2311 c.expression(n.Type, n.Expression) 2312 c.emit(&ir.Neg{TypeID: c.typ(n, n.Type).ID(), Position: position(n)}) 2313 case 21: // '~' Expression // Case 21 2314 c.expression(n.Type, n.Expression) 2315 c.emit(&ir.Cpl{TypeID: c.typ(n, n.Type).ID(), Position: position(n)}) 2316 case 22: // '!' Expression // Case 22 2317 c.expression(nil, n.Expression) 2318 c.bool(n, n.Expression.Type) 2319 c.emit(&ir.Not{Position: position(n)}) 2320 case 23: // "sizeof" Expression // Case 23 2321 if n.Expression.Type.Kind() == cc.Array { 2322 TODO(position(n)) 2323 break 2324 } 2325 2326 TODO(position(n)) 2327 case 24: // "sizeof" '(' TypeName ')' // Case 24 2328 TODO(position(n)) 2329 case 25: // '(' TypeName ')' Expression // Case 25 2330 t := c.expression(nil, n.Expression) 2331 if n.Expression.Type.Kind() == cc.Function && n.TypeName.Type.Kind() == cc.Ptr { 2332 c.convert(n, t, n.TypeName.Type) 2333 break 2334 } 2335 2336 switch { 2337 case n.TypeName.Type.Kind() == cc.Void: 2338 u := c.typ(n, t) 2339 if u.Kind() == ir.Pointer { 2340 if u = u.(*ir.PointerType).Element; u.Kind() == ir.Array { 2341 c.emit(&ir.Drop{TypeID: u.(*ir.ArrayType).Item.Pointer().ID(), Position: position(n)}) 2342 break 2343 } 2344 } 2345 2346 if id := c.typ(n, t).ID(); id != idVoid { 2347 c.emit(&ir.Drop{TypeID: id, Position: position(n)}) 2348 } 2349 default: 2350 u := c.typ(n, t) 2351 if u.Kind() == ir.Pointer { 2352 if u = u.(*ir.PointerType).Element; u.Kind() == ir.Array { 2353 c.convert2(n, u.(*ir.ArrayType).Item.Pointer(), c.typ(n, n.TypeName.Type)) 2354 break 2355 } 2356 } 2357 2358 //dbg("%s: %v, %v, %v", position(n), t, n.Expression.Type, n.TypeName.Type) 2359 c.convert(n, t, n.TypeName.Type) 2360 } 2361 case 26: // Expression '*' Expression // Case 26 2362 return c.binop(ot, n, &ir.Mul{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2363 case 27: // Expression '/' Expression // Case 27 2364 return c.binop(ot, n, &ir.Div{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2365 case 28: // Expression '%' Expression // Case 28 2366 return c.binop(ot, n, &ir.Rem{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2367 case 29: // Expression '+' Expression // Case 29 2368 switch n.Expression.Type.Kind() { 2369 case cc.Ptr, cc.Array: 2370 t := c.expression(nil, n.Expression) 2371 c.expression(t, n.Expression2) 2372 tid := c.typ(n, t).ID() 2373 if sz := t.Element().SizeOf(); sz > 1 { 2374 c.emit(&ir.Const32{TypeID: tid, Value: int32(sz), Position: position(n)}) 2375 c.emit(&ir.Mul{TypeID: tid, Position: position(n)}) 2376 } 2377 c.emit(&ir.Add{TypeID: tid, Position: position(n.Token)}) 2378 return t, nil 2379 } 2380 2381 switch n.Expression2.Type.Kind() { 2382 case cc.Ptr, cc.Array: 2383 t := n.Expression2.Type 2384 c.expression(t, n.Expression) 2385 tid := c.typ(n, t).ID() 2386 if sz := t.Element().SizeOf(); sz > 1 { 2387 c.emit(&ir.Const32{TypeID: tid, Value: int32(sz), Position: position(n)}) 2388 c.emit(&ir.Mul{TypeID: tid, Position: position(n)}) 2389 } 2390 c.expression(nil, n.Expression2) 2391 c.emit(&ir.Add{TypeID: tid, Position: position(n.Token)}) 2392 return t, nil 2393 } 2394 2395 return c.binop(ot, n, &ir.Add{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2396 case 30: // Expression '-' Expression // Case 30 2397 switch n.Expression.Type.Kind() { 2398 case cc.Ptr, cc.Array: 2399 t := n.Expression.Type 2400 if t.Kind() == cc.Array { 2401 t = t.Element().Pointer() 2402 } 2403 switch n.Expression2.Type.Kind() { 2404 case cc.Ptr, cc.Array: 2405 c.expression(t, n.Expression) 2406 c.expression(t, n.Expression2) 2407 c.emit(&ir.PtrDiff{PtrType: c.typ(n, t).ID(), TypeID: c.typ(n, n.Type).ID(), Position: position(n)}) 2408 default: 2409 c.expression(nil, n.Expression) 2410 c.expression(t, n.Expression2) 2411 tid := c.typ(n, t).ID() 2412 if sz := t.Element().SizeOf(); sz > 1 { 2413 c.emit(&ir.Const32{TypeID: tid, Value: int32(sz), Position: position(n)}) 2414 c.emit(&ir.Mul{TypeID: tid, Position: position(n)}) 2415 } 2416 c.emit(&ir.Sub{TypeID: tid, Position: position(n.Token)}) 2417 } 2418 return n.Type, nil 2419 } 2420 2421 switch n.Expression2.Type.Kind() { 2422 case cc.Ptr, cc.Array: 2423 TODO(position(n)) 2424 return n.Type, nil 2425 } 2426 2427 //TODO if n.Expression.Type.Kind() == cc.Ptr || n.Expression2.Type.Kind() == cc.Ptr { 2428 //TODO c.expression(nil, n.Expression) 2429 //TODO c.expression(nil, n.Expression2) 2430 //TODO c.emit(&ir.PtrDiff{TypeID: c.typ(n.Type).ID(), Position: position(n)}) 2431 //TODO break 2432 //TODO } 2433 2434 return c.binop(ot, n, &ir.Sub{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2435 case 31: // Expression "<<" Expression // Case 31 2436 return c.shift(n, &ir.Lsh{TypeID: c.typ(n, n.Type).ID(), Position: position(n.Token)}), nil 2437 case 32: // Expression ">>" Expression // Case 32 2438 return c.shift(n, &ir.Rsh{TypeID: c.typ(n, n.Type).ID(), Position: position(n.Token)}), nil 2439 case 33: // Expression '<' Expression // Case 33 2440 return c.relop(nil, n, &ir.Lt{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2441 case 34: // Expression '>' Expression // Case 34 2442 return c.relop(nil, n, &ir.Gt{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2443 case 35: // Expression "<=" Expression // Case 35 2444 return c.relop(nil, n, &ir.Leq{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2445 case 36: // Expression ">=" Expression // Case 36 2446 return c.relop(nil, n, &ir.Geq{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2447 case 37: // Expression "==" Expression // Case 37 2448 return c.relop(nil, n, &ir.Eq{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2449 case 38: // Expression "!=" Expression // Case 38 2450 return c.relop(nil, n, &ir.Neq{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2451 case 39: // Expression '&' Expression // Case 39 2452 return c.binop(ot, n, &ir.And{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2453 case 40: // Expression '^' Expression // Case 40 2454 return c.binop(ot, n, &ir.Xor{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2455 case 41: // Expression '|' Expression // Case 41 2456 return c.binop(ot, n, &ir.Or{TypeID: c.typ(n, c.binopType(n)).ID(), Position: position(n.Token)}), nil 2457 case 42: // Expression "&&" Expression // Case 42 2458 // push 0 nop 2459 // eval expr 2460 // convert to bool if necessary 2461 // jz A nop 2462 // eval expr2 2463 // convert to bool if necessary 2464 // jz A nop 2465 // drop nop 2466 // push 1 nop 2467 // A: land 2468 c.emit(&ir.Const32{TypeID: idInt32, Position: position(n), LOp: true}) 2469 c.expression(nil, n.Expression) 2470 c.bool(n, n.Expression.Type) 2471 a := c.label() 2472 c.emit(&ir.Jz{Number: a, Position: position(n.Expression), LOp: true}) 2473 c.expression(nil, n.Expression2) 2474 c.bool(n, n.Expression2.Type) 2475 c.emit(&ir.Jz{Number: a, Position: position(n.Expression), LOp: true}) 2476 c.emit(&ir.Drop{TypeID: idInt32, Position: position(n), LOp: true}) 2477 c.emit(&ir.Const32{TypeID: idInt32, Value: 1, Position: position(n), LOp: true}) 2478 c.emit(&ir.Label{Number: a, Position: position(n), LAnd: true}) 2479 case 43: // Expression "||" Expression // Case 43 2480 // push 1 nop 2481 // eval expr 2482 // convert to bool if necessary 2483 // jnz A nop 2484 // eval expr2 2485 // convert to bool if necessary 2486 // jnz A nop 2487 // drop nop 2488 // push 0 nop 2489 // A: lor 2490 c.emit(&ir.Const32{TypeID: idInt32, Value: 1, Position: position(n), LOp: true}) 2491 c.expression(nil, n.Expression) 2492 c.bool(n, n.Expression.Type) 2493 a := c.label() 2494 c.emit(&ir.Jnz{Number: a, Position: position(n.Expression), LOp: true}) 2495 c.expression(nil, n.Expression2) 2496 c.bool(n, n.Expression2.Type) 2497 c.emit(&ir.Jnz{Number: a, Position: position(n.Expression), LOp: true}) 2498 c.emit(&ir.Drop{TypeID: idInt32, Position: position(n), LOp: true}) 2499 c.emit(&ir.Const32{TypeID: idInt32, Position: position(n), LOp: true}) 2500 c.emit(&ir.Label{Number: a, Position: position(n), LOr: true}) 2501 case 44: // Expression '?' ExpressionList ':' Expression // Case 44 2502 c.condExpr(n) 2503 case 45: // Expression '=' Expression // Case 45 2504 lt := n.Expression.Type 2505 rt := n.Expression2.Type 2506 if lt.Kind() == cc.Array && rt.Kind() == cc.Array && c.isArg(n.Expression) && c.isArg(n.Expression2) { 2507 c.addr2(n.Expression, true) 2508 x := c.expression(nil, n.Expression2) 2509 c.convert(n, x, n.Expression2.Type.Pointer()) 2510 c.emit(&ir.Store{TypeID: c.typ(n, n.Expression2.Type.Pointer()).ID(), Position: position(n.Token)}) 2511 return lt.Pointer(), nil 2512 } 2513 2514 if lt.Kind() == cc.Array && rt.Kind() == cc.Ptr && c.isArg(n.Expression) { 2515 c.addr2(n.Expression, true) 2516 c.expression(nil, n.Expression2) 2517 c.emit(&ir.Store{TypeID: c.typ(n, n.Expression2.Type).ID(), Position: position(n.Token)}) 2518 return rt, nil 2519 } 2520 2521 bits, bitoff, ft, bt := c.addr(n.Expression) 2522 if bits != 0 { 2523 t := c.expression(nil, n.Expression2) 2524 c.convert(n, t, ft) 2525 c.emit(&ir.Store{Bits: bits, BitOffset: bitoff, TypeID: c.typ(n, ft).ID(), Position: position(n)}) 2526 return c.bitField(n, bits, bitoff, ft, bt), nil 2527 } 2528 2529 switch { 2530 case lt.Kind() == cc.Array && rt.Kind() == cc.Array: 2531 c.convert(n, lt.Element().Pointer(), lt.Pointer()) 2532 u := c.expression(n.Expression.Type, n.Expression2) 2533 c.convert(n, u, n.Expression.Type.Pointer()) 2534 c.emit(&ir.Copy{TypeID: c.typ(n, n.Expression2.Type).ID(), Position: position(n)}) 2535 return lt.Pointer(), nil 2536 default: 2537 u := c.expression(n.Expression.Type, n.Expression2) 2538 c.convert(n, u, n.Expression.Type) 2539 c.emit(&ir.Store{TypeID: c.typ(n, n.Expression.Type).ID(), Position: position(n.Token)}) 2540 } 2541 case 46: // Expression "*=" Expression // Case 46 2542 return c.asop(n, &ir.Mul{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2543 case 47: // Expression "/=" Expression // Case 47 2544 return c.asop(n, &ir.Div{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2545 case 48: // Expression "%=" Expression // Case 48 2546 return c.asop(n, &ir.Rem{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2547 case 49: // Expression "+=" Expression // Case 49 2548 if t := n.Expression.Type; t.Kind() == cc.Ptr { 2549 return c.asop(n, &ir.Element{Address: true, TypeID: c.typ(n, t).ID(), IndexType: c.typ(n, n.Expression2.Type).ID(), Position: position(n)}), nil 2550 } 2551 2552 return c.asop(n, &ir.Add{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2553 case 50: // Expression "-=" Expression // Case 50 2554 if n.Expression.Type.Kind() == cc.Ptr { 2555 return c.asop(n, &ir.Element{Address: true, Neg: true, TypeID: c.typ(n, t).ID(), IndexType: c.typ(n, n.Expression2.Type).ID(), Position: position(n)}), nil 2556 } 2557 2558 return c.asop(n, &ir.Sub{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2559 case 51: // Expression "<<=" Expression // Case 51 2560 return c.asop(n, &ir.Lsh{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}, c.cint), nil 2561 case 52: // Expression ">>=" Expression // Case 52 2562 return c.asop(n, &ir.Rsh{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}, c.cint), nil 2563 case 53: // Expression "&=" Expression // Case 53 2564 return c.asop(n, &ir.And{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2565 case 54: // Expression "^=" Expression // Case 54 2566 return c.asop(n, &ir.Xor{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2567 case 55: // Expression "|=" Expression // Case 55 2568 return c.asop(n, &ir.Or{TypeID: c.typ(n, c.asopType(n)).ID(), Position: position(n)}), nil 2569 case 56: // "_Alignof" '(' TypeName ')' // Case 56 2570 TODO(position(n)) 2571 case 57: // '(' CompoundStatement ')' // Case 57 2572 stmtExpr := 0 2573 if n.Type.Kind() != cc.Void { 2574 stmtExpr = stmtExprValue 2575 } 2576 c.compoundStatement(&labels{-1, -1, -1}, n.CompoundStatement, stmtExpr) 2577 case 59: // Expression '?' ':' Expression // Case 59 2578 c.condExpr2(n) 2579 default: 2580 panic(fmt.Errorf("%s: internal error: Expression.Case %v", position(n), n.Case)) 2581 } 2582 2583 return t, nil 2584 } 2585 2586 func (c *c) expressionList(ot cc.Type, n *cc.ExpressionList) (r cc.Type) { 2587 t := c.ast.Model.VoidType 2588 for l := n; l != nil; l = l.ExpressionList { 2589 comma := true 2590 if l.ExpressionList == nil { 2591 t = ot 2592 comma = false 2593 } 2594 r = c.expression(t, l.Expression) 2595 p := &c.f.f.Body[len(c.f.f.Body)-1] 2596 switch x := (*p).(type) { 2597 case *ir.Drop: 2598 x.Comma = comma 2599 case *ir.Call: 2600 x.Comma = comma 2601 case *ir.CallFP: 2602 x.Comma = comma 2603 } 2604 } 2605 return r 2606 } 2607 2608 func (c *c) expressionListOpt(ot cc.Type, n *cc.ExpressionListOpt, stmtExpr int) { 2609 if n == nil { 2610 return 2611 } 2612 2613 switch stmtExpr { 2614 case stmtExprValue: 2615 ot = n.ExpressionList.Type 2616 case stmtExprAddress: 2617 t := c.ast.Model.VoidType 2618 for l := n.ExpressionList; l != nil; l = l.ExpressionList { 2619 if l.ExpressionList == nil { 2620 c.addr(l.Expression) 2621 return 2622 } 2623 2624 c.expression(t, l.Expression) 2625 } 2626 return 2627 } 2628 c.expressionList(ot, n.ExpressionList) 2629 } 2630 2631 func (c *c) expressionStatement(n *cc.ExpressionStatement, stmtExpr int) { 2632 c.expressionListOpt(c.ast.Model.VoidType, n.ExpressionListOpt, stmtExpr) 2633 } 2634 2635 func (c *c) jumpStatement(labels *labels, n *cc.JumpStatement) { 2636 switch n.Case { 2637 case 0: // "goto" IDENTIFIER ';' 2638 c.emit(&ir.Jmp{NameID: ir.NameID(n.Token2.Val), Position: position(n)}) 2639 case 1: // "continue" ';' // Case 1 2640 c.emit(&ir.Jmp{Number: labels.continueLabel, Position: position(n)}) 2641 case 2: // "break" ';' // Case 2 2642 label := labels.breakLabel 2643 if label < 0 { 2644 label = c.label() 2645 labels.breakLabel = label 2646 } 2647 c.emit(&ir.Jmp{Number: label, Position: position(n)}) 2648 case 3: // "return" ExpressionListOpt ';' // Case 3 2649 if o := n.ExpressionListOpt; o != nil { 2650 switch r := c.f.result; r { 2651 case 0: 2652 c.expressionList(c.ast.Model.VoidType, o.ExpressionList) 2653 default: 2654 c.emit(&ir.Result{Address: true, TypeID: c.types.MustType(r).Pointer().ID(), Position: position(n)}) 2655 l := o.ExpressionList 2656 t := c.expressionList(nil, l) 2657 c.convert2(n, c.typ(n, t), c.types.MustType(r)) 2658 c.emit(&ir.Store{TypeID: r, Position: position(n)}) 2659 c.emit(&ir.Drop{TypeID: r, Position: position(n)}) 2660 } 2661 } 2662 c.emit(&ir.Return{Position: position(n)}) 2663 case 4: // "goto" Expression ';' // Case 4 2664 switch e := n.Expression; e.Case { 2665 case 18: // '*' Expression // Case 18 2666 c.expression(nil, e.Expression) 2667 default: 2668 TODO(position(n), e.Case) 2669 } 2670 c.emit(&ir.JmpP{Position: position(n)}) 2671 default: 2672 panic("internal error") 2673 } 2674 } 2675 2676 func (c *c) label() int { 2677 r := c.f.label 2678 c.f.label++ 2679 return r 2680 } 2681 2682 func (c *c) forStmt(n *cc.IterationStatement, labels *labels, init, cond, iter *cc.ExpressionListOpt) { 2683 switch { 2684 case n.Declaration != nil: 2685 c.declaration(n.Declaration, true) 2686 case init != nil: 2687 c.expressionListOpt(c.ast.Model.VoidType, init, 0) 2688 } 2689 test := c.label() 2690 cont := c.label() 2691 cl := labels.setContinue(cont) 2692 c.emit(&ir.Label{Number: test, Position: position(n)}) 2693 end := c.label() 2694 if o := cond; o != nil { 2695 el := o.ExpressionList 2696 c.expressionList(el.Type, el) 2697 end = c.label() 2698 c.bool(n, el.Type) 2699 c.emit(&ir.Jz{Number: end, Position: position(n)}) 2700 } 2701 breakLabel := labels.setBreak(end) 2702 loop := c.f.loop 2703 c.f.loop = true 2704 c.statement(labels, n.Statement, 0) 2705 c.f.loop = loop 2706 labels.setBreak(breakLabel) 2707 labels.setContinue(cl) 2708 c.emit(&ir.Label{Number: cont, Position: position(n)}) 2709 c.expressionListOpt(c.ast.Model.VoidType, iter, 0) 2710 c.emit(&ir.Jmp{Number: test, Position: position(n)}) 2711 c.emit(&ir.Label{Number: end, Position: position(n)}) 2712 } 2713 2714 func (c *c) iterationStatement(labels *labels, n *cc.IterationStatement) { 2715 switch n.Case { 2716 case 0: // "while" '(' ExpressionList ')' Statement 2717 begin := c.label() 2718 cl := labels.setContinue(begin) 2719 end := c.label() 2720 c.emit(&ir.Label{Number: begin, Position: position(n)}) 2721 el := n.ExpressionList 2722 c.expressionList(el.Type, el) 2723 c.bool(n, el.Type) 2724 c.emit(&ir.Jz{Number: end, Position: position(n)}) 2725 breakLabel := labels.setBreak(end) 2726 loop := c.f.loop 2727 c.f.loop = true 2728 c.statement(labels, n.Statement, 0) 2729 c.f.loop = loop 2730 labels.setBreak(breakLabel) 2731 labels.setContinue(cl) 2732 c.emit(&ir.Jmp{Number: begin, Position: position(n)}) 2733 c.emit(&ir.Label{Number: end, Position: position(n)}) 2734 case 1: // "do" Statement "while" '(' ExpressionList ')' ';' // Case 1 2735 begin := c.label() 2736 c.emit(&ir.Label{Number: begin, Position: position(n)}) 2737 breakLabel := labels.setBreak(-1) 2738 cl := labels.setContinue(begin) 2739 loop := c.f.loop 2740 c.f.loop = true 2741 c.statement(labels, n.Statement, 0) 2742 c.f.loop = loop 2743 el := n.ExpressionList 2744 c.expressionList(el.Type, el) 2745 c.bool(n, el.Type) 2746 c.emit(&ir.Jnz{Number: begin, Position: position(n.ExpressionList)}) 2747 if e := labels.breakLabel; e >= 0 { 2748 c.emit(&ir.Label{Number: e, Position: position(n)}) 2749 } 2750 labels.setBreak(breakLabel) 2751 labels.setContinue(cl) 2752 case 2: // "for" '(' ExpressionListOpt ';' ExpressionListOpt ';' ExpressionListOpt ')' Statement // Case 2 2753 c.forStmt(n, labels, n.ExpressionListOpt, n.ExpressionListOpt2, n.ExpressionListOpt3) 2754 case 3: // "for" '(' Declaration ExpressionListOpt ';' ExpressionListOpt ')' Statement // Case 3 2755 c.forStmt(n, labels, nil, n.ExpressionListOpt, n.ExpressionListOpt2) 2756 default: 2757 panic("internal error") 2758 } 2759 } 2760 2761 func (c *c) switchStatement(n *cc.SelectionStatement) { 2762 // "switch" '(' ExpressionList ')' Statement // Case 2 2763 t := n.ExpressionList.Type 2764 t = c.ast.Model.BinOpType(t, t) 2765 c.expressionList(t, n.ExpressionList) 2766 firstCase := -1 2767 defaultCase := -1 2768 c.label() 2769 var defaultPosition token.Position 2770 var cases []*cc.ConstantExpression 2771 var f func(*cc.Statement) 2772 f = func(n *cc.Statement) { 2773 switch n.Case { 2774 case 0: // LabeledStatement 2775 switch n := n.LabeledStatement; n.Case { 2776 case 0: // IDENTIFIER ':' Statement 2777 f(n.Statement) 2778 case 1: // "case" ConstantExpression ':' Statement // Case 1 2779 label := c.label() 2780 if firstCase < 0 { 2781 firstCase = label 2782 } 2783 cases = append(cases, n.ConstantExpression) 2784 f(n.Statement) 2785 case 2: // "default" ':' Statement // Case 2 2786 defaultPosition = position(n) 2787 label := c.label() 2788 if defaultCase >= 0 { 2789 panic("internal error") 2790 } 2791 2792 defaultCase = label 2793 if firstCase < 0 { 2794 firstCase = label 2795 } 2796 cases = append(cases, n.ConstantExpression) 2797 f(n.Statement) 2798 default: 2799 panic("internal error") 2800 } 2801 case 1: // CompoundStatement // Case 1 2802 o := n.CompoundStatement.BlockItemListOpt 2803 if o == nil { 2804 break 2805 } 2806 2807 for l := o.BlockItemList; l != nil; l = l.BlockItemList { 2808 switch n := l.BlockItem; n.Case { 2809 case 0: // Declaration 2810 // nop 2811 case 1: // Statement // Case 1 2812 f(n.Statement) 2813 default: 2814 panic("internal error") 2815 } 2816 } 2817 case 2: // ExpressionStatement // Case 2 2818 // nop 2819 case 3: // SelectionStatement // Case 3 2820 switch n := n.SelectionStatement; n.Case { 2821 case 0: // "if" '(' ExpressionList ')' Statement 2822 f(n.Statement) 2823 case 1: // "if" '(' ExpressionList ')' Statement "else" Statement // Case 1 2824 f(n.Statement) 2825 case 2: // "switch" '(' ExpressionList ')' Statement // Case 2 2826 // nop 2827 default: 2828 panic("internal error") 2829 } 2830 case 4: // IterationStatement // Case 4 2831 switch n := n.IterationStatement; n.Case { 2832 case 2833 0, // "while" '(' ExpressionList ')' Statement 2834 1, // "do" Statement "while" '(' ExpressionList ')' ';' // Case 1 2835 2, // "for" '(' ExpressionListOpt ';' ExpressionListOpt ';' ExpressionListOpt ')' Statement // Case 2 2836 3: // "for" '(' Declaration ExpressionListOpt ';' ExpressionListOpt ')' Statement // Case 3 2837 f(n.Statement) 2838 default: 2839 panic("internal error") 2840 } 2841 case 5: // JumpStatement // Case 5 2842 // nop 2843 case 9: // AssemblerStatement // Case 6 2844 TODO(position(n)) 2845 default: 2846 panic("internal error") 2847 } 2848 } 2849 f(n.Statement) 2850 typ := c.typ(n, t).ID() 2851 if len(cases) == 0 { 2852 c.emit(&ir.Drop{TypeID: typ, Position: position(n.ExpressionList)}) 2853 return 2854 } 2855 2856 sw := &ir.Switch{TypeID: typ, Position: position(n)} 2857 for i, v := range cases { 2858 if v == nil { // default: 2859 continue 2860 } 2861 2862 switch typ { 2863 case idInt32, idUint32: 2864 switch x := v.Value.(type) { 2865 case int32: 2866 sw.Values = append(sw.Values, &ir.Int32Value{Value: x}) 2867 case uint32: 2868 sw.Values = append(sw.Values, &ir.Int32Value{Value: int32(x)}) 2869 default: 2870 TODO(position(n), fmt.Sprintf(" %T", x)) 2871 } 2872 case idInt64, idUint64: 2873 switch x := v.Value.(type) { 2874 case int32: 2875 sw.Values = append(sw.Values, &ir.Int64Value{Value: int64(x)}) 2876 default: 2877 TODO(position(n), fmt.Sprintf(" %T", x)) 2878 } 2879 default: 2880 TODO(position(n), fmt.Sprintf(" %v", typ)) 2881 } 2882 sw.Labels = append(sw.Labels, ir.Label{Number: i + firstCase, Position: position(v)}) 2883 2884 } 2885 labels := labels{ 2886 breakLabel: -1, 2887 caseLabel: firstCase, 2888 continueLabel: -1, 2889 } 2890 switch { 2891 case defaultCase < 0: 2892 labels.breakLabel = c.label() 2893 sw.Default = ir.Label{Number: labels.breakLabel} 2894 default: 2895 sw.Default = ir.Label{Number: defaultCase, Position: defaultPosition} 2896 } 2897 c.emit(sw) 2898 c.statement(&labels, n.Statement, 0) 2899 if labels.breakLabel >= 0 { 2900 c.emit(&ir.Label{Number: labels.breakLabel, Position: position(n.ExpressionList)}) 2901 } 2902 } 2903 2904 func (c *c) bool(n cc.Node, from cc.Type) { 2905 switch from.Kind() { 2906 case cc.Ptr: 2907 if t := from.Element(); t.Kind() == cc.Array { 2908 from = t.Element().Pointer() 2909 } 2910 case cc.Array: 2911 from = from.Element().Pointer() 2912 } 2913 if from.Kind() != cc.Int { 2914 c.emit(&ir.Bool{TypeID: c.typ(n, from).ID(), Position: position(n)}) 2915 } 2916 } 2917 2918 func (c *c) selectionStatement(labels *labels, n *cc.SelectionStatement) { 2919 switch n.Case { 2920 case 0: // "if" '(' ExpressionList ')' Statement 2921 // expr; jz 1; stmt; 1: 2922 c.expressionList(nil, n.ExpressionList) 2923 c.bool(n, n.ExpressionList.Type) 2924 l1 := c.label() 2925 c.emit(&ir.Jz{Number: l1, Position: position(n)}) 2926 c.statement(labels, n.Statement, 0) 2927 c.emit(&ir.Label{Number: l1, Position: position(n)}) 2928 case 1: // "if" '(' ExpressionList ')' Statement "else" Statement // Case 1 2929 // expr; jz 1; stmt; jmp 2; 1: stmt2; 2: 2930 c.expressionList(nil, n.ExpressionList) 2931 c.bool(n, n.ExpressionList.Type) 2932 l1 := c.label() 2933 c.emit(&ir.Jz{Number: l1, Position: position(n)}) 2934 c.statement(labels, n.Statement, 0) 2935 l2 := c.label() 2936 c.emit(&ir.Jmp{Number: l2, Position: position(n)}) 2937 c.emit(&ir.Label{Number: l1, Position: position(n)}) 2938 c.statement(labels, n.Statement2, 0) 2939 c.emit(&ir.Label{Number: l2, Position: position(n)}) 2940 case 2: // "switch" '(' ExpressionList ')' Statement // Case 2 2941 c.switchStatement(n) 2942 default: 2943 panic("internal error") 2944 } 2945 } 2946 2947 func (c *c) labeledStatement(labels *labels, n *cc.LabeledStatement) { 2948 switch n.Case { 2949 case 0: // IDENTIFIER ':' Statement 2950 c.emit(&ir.Label{NameID: ir.NameID(n.Token.Val), Position: position(n)}) 2951 case 2952 1, // "case" ConstantExpression ':' Statement // Case 1 2953 2: // "default" ':' Statement // Case 2 2954 c.emit(&ir.Label{Number: labels.caseLabel, Position: position(n)}) 2955 labels.caseLabel++ 2956 default: 2957 panic("internal error") 2958 } 2959 c.statement(labels, n.Statement, 0) 2960 } 2961 2962 func (c *c) assemblerStatement(n *cc.AssemblerStatement) { 2963 switch n.Case { 2964 case 0: // BasicAssemblerStatement 2965 for l := n.BasicAssemblerStatement.AssemblerInstructions; l != nil; l = l.AssemblerInstructions { 2966 if v := l.Token.Val; v != idEmptyString { 2967 panic(fmt.Errorf("%s: assembler instructions not supported: %s", position(l.Token), dict.S(v))) 2968 } 2969 } 2970 default: 2971 panic(fmt.Errorf("%s: assembler instructions not supported", position(n))) 2972 } 2973 } 2974 2975 func (c *c) statement(labels *labels, n *cc.Statement, stmtExpr int) { 2976 switch n.Case { 2977 case 0: // LabeledStatement 2978 c.labeledStatement(labels, n.LabeledStatement) 2979 case 1: // CompoundStatement // Case 1 2980 c.compoundStatement(labels, n.CompoundStatement, 0) 2981 case 2: // ExpressionStatement // Case 2 2982 c.expressionStatement(n.ExpressionStatement, stmtExpr) 2983 case 3: // SelectionStatement // Case 3 2984 c.selectionStatement(labels, n.SelectionStatement) 2985 case 4: // IterationStatement // Case 4 2986 c.iterationStatement(labels, n.IterationStatement) 2987 case 5: // JumpStatement // Case 5 2988 c.jumpStatement(labels, n.JumpStatement) 2989 case 6: // AssemblerStatement // Case 6 2990 c.assemblerStatement(n.AssemblerStatement) 2991 default: 2992 panic("internal error") 2993 } 2994 } 2995 2996 func (c *c) blockItem(labels *labels, n *cc.BlockItem, stmtExpr int, alwaysEvalInitializers bool) { 2997 switch n.Case { 2998 case 0: // Declaration 2999 c.declaration(n.Declaration, alwaysEvalInitializers) 3000 case 1: // Statement // Case 1 3001 c.statement(labels, n.Statement, stmtExpr) 3002 default: 3003 panic("internal error") 3004 } 3005 } 3006 3007 func (c *c) compoundStatement(labels *labels, n *cc.CompoundStatement, stmtExpr int) { 3008 v := stmtExpr == stmtExprValue || stmtExpr == stmtExprAddress 3009 c.f.blockLevel++ 3010 c.emit(&ir.BeginScope{Position: position(n), Value: v}) 3011 if o := n.BlockItemListOpt; o != nil { 3012 for l := o.BlockItemList; l != nil; l = l.BlockItemList { 3013 se := 0 3014 if l.BlockItemList == nil { 3015 se = stmtExpr 3016 } 3017 c.blockItem(labels, l.BlockItem, se, c.f.loop) 3018 } 3019 } 3020 c.f.blockLevel-- 3021 if c.f.blockLevel == 0 { 3022 b := c.f.f.Body 3023 if _, ok := b[len(b)-1].(*ir.Return); !ok { 3024 c.emit(&ir.Return{Position: position(n.Token2)}) 3025 } 3026 } 3027 c.emit(&ir.EndScope{Position: position(n.Token2), Value: v}) 3028 } 3029 3030 func (c *c) functionBody(n *cc.FunctionBody) { 3031 if c.f.f.NameID == idMain && c.f.f.Linkage == ir.ExternalLinkage { 3032 c.emit(&ir.Result{Address: true, TypeID: idPInt32, Position: position(n)}) 3033 c.emit(&ir.Const32{TypeID: idInt32, Position: position(n)}) 3034 c.emit(&ir.Store{TypeID: idInt32, Position: position(n)}) 3035 c.emit(&ir.Drop{TypeID: idInt32, Position: position(n)}) 3036 } 3037 switch n.Case { 3038 case 0: // CompoundStatement 3039 c.compoundStatement(&labels{-1, -1, -1}, n.CompoundStatement, 0) 3040 case 1: // AssemblerStatement ';' // Case 1 3041 TODO(position(n)) 3042 default: 3043 panic("internal error") 3044 } 3045 } 3046 3047 func (c *c) fnArgNames(d *cc.Declarator) []ir.NameID { 3048 p, _ := d.Type.Parameters() 3049 var args []ir.NameID 3050 if len(p) != 0 && p[0].Name != 0 { 3051 args = make([]ir.NameID, len(p)) 3052 for i, v := range p { 3053 args[i] = ir.NameID(v.Name) 3054 } 3055 } 3056 return args 3057 } 3058 3059 func (c *c) comment(p ...token.Pos) ir.NameID { 3060 for _, v := range p { 3061 if n := c.ast.Comments[v]; n != 0 { 3062 return ir.NameID(dict.SID(tidyComments(dict.S(n)))) 3063 } 3064 3065 v -= token.Pos(xc.FileSet.Position(v).Column - 1) 3066 if n := c.ast.Comments[v]; n != 0 { 3067 return ir.NameID(dict.SID(tidyComments(dict.S(n)))) 3068 } 3069 } 3070 return 0 3071 } 3072 3073 func (c *c) functionDefinition(n *cc.FunctionDefinition, doc ir.NameID) { 3074 switch n.Case { 3075 case 3076 0, // DeclarationSpecifiers Declarator DeclarationListOpt FunctionBody 3077 1: // Declarator DeclarationListOpt FunctionBody // Case 1 3078 3079 d := n.Declarator 3080 t := c.typ(n, d.Type) 3081 nm := c.nm(d) 3082 ln := c.linkage(d.Linkage) 3083 if ln == ir.ExternalLinkage && nm == idMain && len(t.(*ir.FunctionType).Results) == 0 { 3084 t = c.types.MustType(ir.TypeID(dict.SID(string(dict.S(int(t.ID()))) + "int32"))) 3085 } 3086 fd := ir.NewFunctionDefinition(position(n), nm, c.tnm(d), t.ID(), ln, c.fnArgNames(d), nil) 3087 fd.Comment = doc 3088 c.newFData(d.Type, fd) 3089 c.f.index = len(c.out) 3090 c.out = append(c.out, c.f.f) 3091 c.functionBody(n.FunctionBody) 3092 c.f = fdata{} 3093 default: 3094 panic("internal error") 3095 } 3096 } 3097 3098 func (c *c) externalDeclaration(n *cc.ExternalDeclaration) { 3099 switch n.Case { 3100 case 0: // FunctionDefinition 3101 fd := n.FunctionDefinition 3102 doc := c.comment(n.Pos(), fd.Pos(), fd.Declarator.Pos(), fd.Pos()-(token.Pos(position(fd).Column-1))) 3103 c.functionDefinition(fd, doc) 3104 case 1: // Declaration // Case 1 3105 c.declaration(n.Declaration, false) 3106 case 2: // BasicAssemblerStatement ';' // Case 2 3107 TODO(position(n)) 3108 case 3: // ';' // Case 3 3109 // nop 3110 default: 3111 panic("internal error") 3112 } 3113 } 3114 3115 func (c *c) gen() { 3116 for l := c.ast; l != nil; l = l.TranslationUnit { 3117 c.externalDeclaration(l.ExternalDeclaration) 3118 } 3119 } 3120 3121 type options struct { 3122 tc ir.TypeCache 3123 } 3124 3125 // Option is a configuration/setup function that can be passed to the New 3126 // function. 3127 type Option func(*options) error 3128 3129 // TypeCache option requests to use a shared type cache tc. 3130 func TypeCache(tc ir.TypeCache) Option { 3131 return func(o *options) error { 3132 o.tc = tc 3133 return nil 3134 } 3135 } 3136 3137 // New returns ir.Objects generated from ast or an error, if any. It's the 3138 func New(ast *cc.TranslationUnit, opts ...Option) (_ []ir.Object, err error) { 3139 if !Testing { 3140 defer func() { 3141 switch x := recover().(type) { 3142 case nil: 3143 // nop 3144 case error: 3145 err = x 3146 default: 3147 err = fmt.Errorf("ccir.New: PANIC: %v", x) 3148 } 3149 }() 3150 } 3151 3152 model, err := ir.NewMemoryModel() 3153 if err != nil { 3154 return nil, err 3155 } 3156 3157 var o options 3158 for _, v := range opts { 3159 if err = v(&o); err != nil { 3160 return nil, err 3161 } 3162 } 3163 if o.tc == nil { 3164 o.tc = ir.TypeCache{} 3165 } 3166 c := newC(model, ast, &o) 3167 c.gen() 3168 return c.out, nil 3169 }