check.go (149219B)
1 // Copyright 2019 The CC 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 cc // import "modernc.org/cc/v3" 6 7 import ( 8 "fmt" 9 "go/token" 10 "math" 11 "math/big" 12 "math/bits" 13 "path/filepath" 14 "strconv" 15 "strings" 16 17 "modernc.org/mathutil" 18 "modernc.org/strutil" 19 ) 20 21 const longDoublePrec = 256 22 23 type mode = int 24 25 var ( 26 idBuiltinConstantPImpl = dict.sid("__builtin_constant_p_impl") 27 idClosure = dict.sid("0closure") // Must be invalid indentifier. 28 idWcharT = dict.sid("wchar_t") 29 idWinWchar = dict.sid("WCHAR") 30 31 _ fmt.State 32 ) 33 34 const ( 35 // [2], 6.6 Constant expressions, 6 36 // 37 // An integer constant expression shall have integer type and shall 38 // only have operands that are integer constants, enumeration 39 // constants, character constants, sizeof expressions whose results are 40 // integer constants, _Alignof expressions, and floating constants that 41 // are the immediate operands of casts. Cast operators in an integer 42 // constant expression shall only convert arithmetic types to integer 43 // types, except as part of an operand to the sizeof or _Alignof 44 // operator. 45 mIntConstExpr = 1 << iota 46 47 mIntConstExprFloat // As mIntConstExpr plus accept floating point constants. 48 mIntConstExprAnyCast // As mIntConstExpr plus accept any cast. 49 ) 50 51 // Parameter represents a function parameter. 52 type Parameter struct { 53 d *Declarator 54 typ Type 55 } 56 57 // NewParameter returns a newly created parameter 58 func NewParameter(d *Declarator, t Type) *Parameter { 59 return &Parameter{d, t} 60 } 61 62 func (p *Parameter) Declarator() *Declarator { return p.d } 63 func (p *Parameter) Name() StringID { return p.d.Name() } 64 func (p *Parameter) Type() Type { return p.typ } 65 66 func (n *TranslationUnit) check(ctx *context) { 67 for n := n; n != nil; n = n.TranslationUnit { 68 n.ExternalDeclaration.check(ctx) 69 } 70 for ; n != nil; n = n.TranslationUnit { 71 n.ExternalDeclaration.checkFnBodies(ctx) 72 } 73 } 74 75 func (n *ExternalDeclaration) checkFnBodies(ctx *context) { 76 if n == nil { 77 return 78 } 79 80 switch n.Case { 81 case ExternalDeclarationFuncDef: // FunctionDefinition 82 n.FunctionDefinition.checkBody(ctx) 83 } 84 } 85 86 // https://gcc.gnu.org/onlinedocs/gcc/Inline.html 87 // 88 // If you specify both inline and extern in the function definition, then the 89 // definition is used only for inlining. In no case is the function compiled on 90 // its own, not even if you refer to its address explicitly. Such an address 91 // becomes an external reference, as if you had only declared the function, and 92 // had not defined it. 93 // 94 // This combination of inline and extern has almost the effect of a macro. The 95 // way to use it is to put a function definition in a header file with these 96 // keywords, and put another copy of the definition (lacking inline and extern) 97 // in a library file. The definition in the header file causes most calls to 98 // the function to be inlined. If any uses of the function remain, they refer 99 // to the single copy in the library. 100 func (n *Declarator) isExternInline() bool { 101 return n.IsExtern() && n.Type() != nil && n.Type().Inline() 102 } 103 104 // DeclarationSpecifiers Declarator DeclarationList CompoundStatement 105 func (n *FunctionDefinition) checkBody(ctx *context) { 106 if n == nil { 107 return 108 } 109 110 if n.checked { 111 return 112 } 113 114 n.checked = true 115 if n.Declarator.isExternInline() && !ctx.cfg.CheckExternInlineFnBodies { 116 return 117 } 118 119 ctx.checkFn = n 120 rd := ctx.readDelta 121 ctx.readDelta = 1 122 n.CompoundStatement.check(ctx) 123 ctx.checkFn = nil 124 for k, v := range n.ComputedGotos { 125 if _, ok := n.Labels[k]; !ok { 126 ctx.errNode(v, "label %s undefined", k) 127 } 128 } 129 for k, v := range n.Gotos { 130 if _, ok := n.Labels[k]; !ok { 131 ctx.errNode(v, "label %s undefined", k) 132 } 133 } 134 for _, n := range n.InitDeclarators { 135 d := n.Declarator 136 if d.Type().IsIncomplete() && d.Linkage != External { 137 ctx.errNode(d, "declarator has incomplete type") 138 } 139 if ctx.cfg.RejectUninitializedDeclarators && d.Linkage == None && d.Write == 0 && !d.AddressTaken && d.Read != 0 { 140 switch d.Type().Kind() { 141 case Array, Struct, Union, Invalid: 142 // nop 143 default: 144 ctx.errNode(d, "%s may be used uninitialized in this function", d.Name()) 145 } 146 } 147 } 148 for _, n := range n.CompositeLiterals { 149 switch t := n.Operand.Type(); t.Kind() { 150 case Invalid: 151 ctx.errNode(n, "composite literal has invalid type") 152 default: 153 if t.IsIncomplete() { 154 ctx.errNode(n, "composite literal has incomplete type") 155 } 156 } 157 } 158 ctx.readDelta = rd 159 } 160 161 func (n *ExternalDeclaration) check(ctx *context) { 162 if n == nil { 163 return 164 } 165 166 switch n.Case { 167 case ExternalDeclarationFuncDef: // FunctionDefinition 168 n.FunctionDefinition.checkDeclarator(ctx) 169 case ExternalDeclarationDecl: // Declaration 170 n.Declaration.check(ctx, true) 171 case ExternalDeclarationAsm: // AsmFunctionDefinition 172 n.AsmFunctionDefinition.check(ctx) 173 case ExternalDeclarationAsmStmt: // AsmStatement 174 n.AsmStatement.check(ctx) 175 case ExternalDeclarationEmpty: // ';' 176 // nop 177 case ExternalDeclarationPragma: // PragmaSTDC 178 n.PragmaSTDC.check(ctx) 179 default: 180 panic(todo("")) 181 } 182 } 183 184 func (n *PragmaSTDC) check(ctx *context) { 185 // nop 186 } 187 188 func (n *AsmFunctionDefinition) check(ctx *context) { 189 if n == nil { 190 return 191 } 192 193 typ, inline, noret := n.DeclarationSpecifiers.check(ctx, false) 194 typ.setFnSpecs(inline, noret) 195 n.Declarator.check(ctx, n.DeclarationSpecifiers, typ, true) 196 n.AsmStatement.check(ctx) 197 } 198 199 func (n *AsmStatement) check(ctx *context) { 200 if n == nil { 201 return 202 } 203 204 n.Asm.check(ctx) 205 n.AttributeSpecifierList.check(ctx, nil) 206 } 207 208 func (n *Declaration) check(ctx *context, tld bool) { 209 if n == nil { 210 return 211 } 212 213 typ, _, _ := n.DeclarationSpecifiers.check(ctx, false) 214 n.InitDeclaratorList.check(ctx, n.DeclarationSpecifiers, typ, tld) 215 } 216 217 func (n *InitDeclaratorList) check(ctx *context, td typeDescriptor, typ Type, tld bool) { 218 for ; n != nil; n = n.InitDeclaratorList { 219 n.AttributeSpecifierList.check(ctx, typ.baseP()) 220 n.InitDeclarator.check(ctx, td, typ, tld) 221 } 222 } 223 224 func (n *InitDeclarator) check(ctx *context, td typeDescriptor, typ Type, tld bool) { 225 if n == nil { 226 return 227 } 228 229 if f := ctx.checkFn; f != nil { 230 f.InitDeclarators = append(f.InitDeclarators, n) 231 } 232 if attr := n.AttributeSpecifierList.check(ctx, typ.baseP()); len(attr) != 0 { 233 typ = &attributedType{typ, attr} 234 } 235 switch n.Case { 236 case InitDeclaratorDecl: // Declarator AttributeSpecifierList 237 n.Declarator.check(ctx, td, typ, tld) 238 case InitDeclaratorInit: // Declarator AttributeSpecifierList '=' Initializer 239 typ := n.Declarator.check(ctx, td, typ, tld) 240 n.Declarator.hasInitializer = true 241 n.Declarator.Write++ 242 n.Initializer.check(ctx, &n.Initializer.list, typ, n.Declarator.StorageClass, nil, 0, nil, nil, false) 243 n.Initializer.setConstZero() 244 n.initializer = &InitializerValue{typ: typ, initializer: n.Initializer} 245 if ctx.cfg.TrackAssignments { 246 setLHS(map[*Declarator]struct{}{n.Declarator: {}}, n.Initializer) 247 } 248 default: 249 panic(todo("")) 250 } 251 } 252 253 func (n *Initializer) setConstZero() { 254 switch n.Case { 255 case InitializerExpr: // AssignmentExpression 256 if op := n.AssignmentExpression.Operand; op != nil { 257 n.isConst = op.IsConst() 258 n.isZero = op.IsZero() 259 } 260 case InitializerInitList: // '{' InitializerList ',' '}' 261 li := n.InitializerList 262 li.setConstZero() 263 n.isConst = li.IsConst() 264 n.isZero = li.IsZero() 265 default: 266 panic(todo("%v:", n.Position())) 267 } 268 } 269 270 func (n *InitializerList) setConstZero() { 271 if n == nil { 272 return 273 } 274 275 n0 := n 276 n0.isConst = true 277 n0.isZero = true 278 for ; n != nil; n = n.InitializerList { 279 in := n.Initializer 280 in.setConstZero() 281 n0.isConst = n0.isConst && in.isConst 282 n0.isZero = n0.isZero && in.isZero 283 } 284 } 285 286 // [0], 6.7.8 Initialization 287 func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, fld Field, off uintptr, il *InitializerList, designatorList *DesignatorList, inList bool) *InitializerList { 288 // trc("==== %v: case %v, t %v, off %v, designatorList != nil %v, inList %v", n.Position(), n.Case, t.Alias(), off, designatorList != nil, inList) 289 // if fld != nil { 290 // trc("\tfld %q", fld.Name()) 291 // } 292 293 // 3 - The type of the entity to be initialized shall be an array of 294 // unknown size or an object type that is not a variable length array 295 // type. 296 if t.Kind() == Array && t.IsVLA() { 297 ctx.errNode(n, "cannot initialize a variable length array: %v", t) 298 if il != nil { 299 return il.InitializerList 300 } 301 302 return nil 303 } 304 305 defer func(d int) { ctx.readDelta = d }(ctx.readDelta) 306 307 ctx.readDelta = 1 308 n.typ = t 309 single := n.single() 310 var op Operand 311 if single != nil { 312 op = single.AssignmentExpression.check(ctx, false) 313 single.typ = t 314 single.Field = fld 315 single.Offset = off 316 } 317 318 // 11: The initializer for a scalar shall be a single expression, optionally 319 // enclosed in braces. The initial value of the object is that of the 320 // expression (after conversion); the same type constraints and conversions as 321 // for simple assignment apply, taking the type of the scalar to be the 322 // unqualified version of its declared type. 323 if t.IsScalarType() && single != nil { 324 if designatorList != nil { 325 panic(todo("", n.Position())) 326 } 327 328 //TODO check compatible 329 *list = append(*list, single) 330 switch { 331 case t.Kind() == op.Type().Kind(): 332 single.AssignmentExpression.InitializerOperand = op 333 default: 334 single.AssignmentExpression.InitializerOperand = op.convertTo(ctx, n, t) 335 } 336 if il != nil { 337 return il.InitializerList 338 } 339 340 return nil 341 } 342 343 // 12: The rest of this subclause deals with initializers for objects that have 344 // aggregate or union type. 345 346 k := t.Kind() 347 348 // 13: The initializer for a structure or union object that has automatic 349 // storage duration shall be either an initializer list as described below, or 350 // a single expression that has compatible structure or union type. In the 351 // latter case, the initial value of the object, including unnamed members, is 352 // that of the expression. 353 if n.Case == InitializerExpr && sc == Automatic && (k == Struct || k == Union || k == Vector) && t.IsCompatible(op.Type()) { 354 if designatorList != nil { 355 panic(todo("", n.Position())) 356 } 357 358 *list = append(*list, single) 359 if il != nil { 360 return il.InitializerList 361 } 362 363 return nil 364 } 365 366 if k == Array && single != nil { 367 et := t.Elem() 368 switch { 369 case isCharType(et): 370 // 14: An array of character type may be initialized by a character string 371 // literal, optionally enclosed in braces. Successive characters of the 372 // character string literal (including the terminating null character if there 373 // is room or if the array is of unknown size) initialize the elements of the 374 // array. 375 if x, ok := op.Value().(StringValue); ok { 376 if designatorList != nil { 377 panic(todo("", n.Position())) 378 } 379 380 *list = append(*list, single) 381 str := StringID(x).String() 382 if t.IsIncomplete() { 383 t.setLen(uintptr(len(str)) + 1) 384 } 385 if il != nil { 386 return il.InitializerList 387 } 388 389 return nil 390 } 391 case isWCharType(et): 392 // 15: An array with element type compatible with wchar_t may be initialized by 393 // a wide string literal, optionally enclosed in braces. Successive wide 394 // characters of the wide string literal (including the terminating null wide 395 // character if there is room or if the array is of unknown size) initialize 396 // the elements of the array. 397 if x, ok := op.Value().(WideStringValue); ok { 398 if designatorList != nil { 399 panic(todo("", n.Position())) 400 } 401 402 *list = append(*list, single) 403 str := []rune(StringID(x).String()) 404 if t.IsIncomplete() { 405 t.setLen(uintptr(len(str)) + 1) 406 } 407 if il != nil { 408 panic(todo("")) 409 } 410 411 return nil 412 } 413 } 414 } 415 416 // 16: Otherwise, the initializer for an object that has aggregate or union 417 // type shall be a brace-enclosed list of initializers for the elements or 418 // named members. 419 if n.Case == InitializerExpr { 420 if il != nil { 421 switch t.Kind() { 422 case Array: 423 return il.checkArray(ctx, list, t, sc, off, designatorList, inList) 424 case Struct: 425 return il.checkStruct(ctx, list, t, sc, off, designatorList, inList) 426 case Union: 427 return il.checkUnion(ctx, list, t, sc, off, designatorList, inList) 428 case Vector: 429 return il.InitializerList //TODO 430 default: 431 panic(todo("", n.Position(), t, t.Kind())) 432 } 433 } 434 435 var l *InitializerList 436 Inspect(n.AssignmentExpression, func(m Node, b bool) bool { 437 if x, ok := m.(*PostfixExpression); ok && x.Case == PostfixExpressionComplit { 438 if !b { 439 return true 440 } 441 442 if l == nil { 443 l = x.InitializerList 444 return true 445 } 446 447 l = nil 448 return false 449 } 450 return true 451 }) 452 if l != nil { 453 l.check(ctx, list, t, sc, off, designatorList, inList) 454 return nil 455 } 456 457 ctx.errNode(n, "initializer for an object that has aggregate or union type shall be a brace-enclosed list of initializers for the elements or named members: %v", t) 458 return nil 459 } 460 461 n.InitializerList.check(ctx, list, t, sc, off, designatorList, inList) 462 if il != nil { 463 return il.InitializerList 464 } 465 466 return nil 467 } 468 469 func (n *InitializerList) checkArray(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList { 470 elem := t.Elem() 471 esz := elem.Size() 472 length := t.Len() 473 var i, maxI uintptr 474 nestedDesignator := designatorList != nil 475 retOnDesignator := false 476 loop: 477 for n != nil { 478 switch { 479 case retOnDesignator && n.Designation != nil: 480 return n 481 case designatorList == nil && !inList && n.Designation != nil: 482 designatorList = n.Designation.DesignatorList 483 fallthrough 484 case designatorList != nil: 485 d := designatorList.Designator 486 designatorList = designatorList.DesignatorList 487 switch d.Case { 488 case DesignatorIndex: // '[' ConstantExpression ']' 489 switch x := d.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) { 490 case Int64Value: 491 i = uintptr(x) 492 case Uint64Value: 493 i = uintptr(x) 494 default: 495 panic(todo("%v: %T", n.Position(), x)) 496 } 497 if !inList && i > maxI { 498 maxI = i 499 } 500 case DesignatorField: // '.' IDENTIFIER 501 panic(todo("", n.Position(), d.Position())) 502 case DesignatorField2: // IDENTIFIER ':' 503 panic(todo("", n.Position(), d.Position())) 504 default: 505 panic(todo("")) 506 } 507 508 n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, designatorList, designatorList != nil) 509 designatorList = nil 510 if nestedDesignator { 511 retOnDesignator = true 512 } 513 i++ 514 default: 515 if !t.IsIncomplete() && i >= length { 516 break loop 517 } 518 519 if i > maxI { 520 maxI = i 521 } 522 n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, nil, inList) 523 i++ 524 } 525 } 526 if t.IsIncomplete() { 527 t.setLen(maxI + 1) 528 } 529 return n 530 } 531 532 func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList { 533 // trc("==== (A) %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList) 534 // defer trc("==== (Z) %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList) 535 t = t.underlyingType() 536 // trc("%v: %v, off %v", n.Position(), t, off) //TODO- 537 nf := t.NumField() 538 i := []int{0} 539 var f Field 540 nestedDesignator := designatorList != nil 541 retOnDesignator := false 542 for n != nil { 543 switch { 544 case retOnDesignator && n.Designation != nil: 545 return n 546 case designatorList == nil && !inList && n.Designation != nil: 547 designatorList = n.Designation.DesignatorList 548 fallthrough 549 case designatorList != nil: 550 d := designatorList.Designator 551 designatorList = designatorList.DesignatorList 552 var nm StringID 553 switch d.Case { 554 case DesignatorIndex: // '[' ConstantExpression ']' 555 panic(todo("", n.Position(), d.Position())) 556 case DesignatorField: // '.' IDENTIFIER 557 nm = d.Token2.Value 558 case DesignatorField2: // IDENTIFIER ':' 559 nm = d.Token.Value 560 default: 561 panic(todo("")) 562 } 563 564 f, xa, ok := t.FieldByName2(nm) 565 if !ok { 566 panic(todo("%v: t %v %q", d.Position(), t, nm)) 567 } 568 569 t0 := t 570 switch { 571 case len(xa) != 1: 572 var f2 Field 573 var off2 uintptr 574 for len(xa) != 1 { 575 f2 = t.FieldByIndex(xa[:1]) 576 off2 += f2.Offset() 577 t = f2.Type() 578 xa = xa[1:] 579 } 580 n = n.Initializer.check(ctx, list, t, sc, f, off+off2, n, designatorList, designatorList != nil) 581 if t.Kind() == Union { 582 t = t0 583 } 584 default: 585 n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList, designatorList != nil) 586 } 587 designatorList = nil 588 if nestedDesignator { 589 retOnDesignator = true 590 } 591 i[0] = xa[0] + 1 592 default: 593 // [0], 6.7.8 Initialization 594 // 595 // 9 - Except where explicitly stated otherwise, for the 596 // purposes of this subclause unnamed members of objects of 597 // structure and union type do not participate in 598 // initialization. Unnamed members of structure objects have 599 // indeterminate value even after initialization. 600 for ; ; i[0]++ { 601 if i[0] >= nf { 602 return n 603 } 604 605 f = t.FieldByIndex(i) 606 if f.Name() != 0 || !f.Type().IsBitFieldType() { 607 n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil, inList) 608 i[0]++ 609 break 610 } 611 } 612 } 613 } 614 return n 615 } 616 617 func spos(n Node) string { 618 p := n.Position() 619 p.Filename = filepath.Base(p.Filename) 620 return p.String() 621 } 622 623 func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList { 624 // trc("==== %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList) 625 t = t.underlyingType() 626 // trc("%v: %v, off %v", n.Position(), t, off) //TODO- 627 nf := t.NumField() 628 i := []int{0} 629 for pass := 0; n != nil; pass++ { 630 switch { 631 case designatorList == nil && !inList && n.Designation != nil: 632 designatorList = n.Designation.DesignatorList 633 fallthrough 634 case designatorList != nil: 635 d := designatorList.Designator 636 designatorList = designatorList.DesignatorList 637 var nm StringID 638 switch d.Case { 639 case DesignatorIndex: // '[' ConstantExpression ']' 640 panic(todo("", n.Position(), d.Position())) 641 case DesignatorField: // '.' IDENTIFIER 642 nm = d.Token2.Value 643 case DesignatorField2: // IDENTIFIER ':' 644 nm = d.Token.Value 645 default: 646 panic(todo("")) 647 } 648 649 f, xa, ok := t.FieldByName2(nm) 650 if !ok { 651 panic(todo("", d.Position())) 652 } 653 654 if !inList && pass == 0 { 655 n.Initializer.field0 = f 656 } 657 switch { 658 case len(xa) != 1: 659 var f2 Field 660 var off2 uintptr 661 for len(xa) != 1 { 662 f2 = t.FieldByIndex(xa[:1]) 663 off2 += f2.Offset() 664 t = f2.Type() 665 xa = xa[1:] 666 } 667 next := n.Initializer.check(ctx, list, t, sc, f, off+off2+f.Offset(), n, designatorList, designatorList != nil) 668 if designatorList != nil && designatorList.DesignatorList != nil { 669 panic(todo("", n.Position(), d.Position())) 670 } 671 672 return next 673 default: 674 next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList, designatorList != nil) 675 if designatorList != nil && designatorList.DesignatorList != nil { 676 panic(todo("", n.Position(), d.Position())) 677 } 678 679 return next 680 } 681 default: 682 // [0], 6.7.8 Initialization 683 // 684 // 9 - Except where explicitly stated otherwise, for the 685 // purposes of this subclause unnamed members of objects of 686 // structure and union type do not participate in 687 // initialization. Unnamed members of structure objects have 688 // indeterminate value even after initialization. 689 for ; ; i[0]++ { 690 if i[0] >= nf { 691 panic(todo("")) 692 } 693 694 f := t.FieldByIndex(i) 695 if f.Name() != 0 || !f.Type().IsBitFieldType() { 696 next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil, inList) 697 return next 698 } 699 } 700 panic(todo("", n.Position())) 701 } 702 } 703 return nil 704 } 705 706 // Accept a single initializer, optionally enclosed in braces, but nested 707 // braces. Implements eg. [0]6.7.8.11. 708 // 709 // 42 // ok 710 // {42} // ok 711 // {{42}} // not ok 712 func (n *Initializer) single() *Initializer { 713 switch n.Case { 714 case InitializerExpr: // AssignmentExpression 715 return n 716 case InitializerInitList: // '{' InitializerList ',' '}' 717 if n.InitializerList == nil { // 718 return nil 719 } 720 721 if n.InitializerList.InitializerList == nil { 722 if in := n.InitializerList.Initializer; in.Case == InitializerExpr { 723 return in 724 } 725 } 726 } 727 return nil 728 } 729 730 // [0], 6.7.8 Initialization 731 func (n *InitializerList) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) { 732 switch t.Kind() { 733 case Array, Vector: 734 if n == nil { // {} 735 if t.IsIncomplete() { 736 t.setLen(0) 737 } 738 return 739 } 740 741 n.checkArray(ctx, list, t, sc, off, designatorList, inList) 742 case Struct: 743 if n == nil { // {} 744 return 745 } 746 747 n.checkStruct(ctx, list, t, sc, off, designatorList, inList) 748 case Union: 749 if n == nil { // {} 750 return 751 } 752 753 n.checkUnion(ctx, list, t, sc, off, designatorList, inList) 754 default: 755 if n == nil || t == nil || t.Kind() == Invalid { 756 return 757 } 758 759 n.Initializer.check(ctx, list, t, sc, nil, off, nil, designatorList, inList) 760 } 761 } 762 763 func setLHS(lhs map[*Declarator]struct{}, rhs Node) { 764 inCall := 0 765 Inspect(rhs, func(n Node, enter bool) bool { 766 switch x := n.(type) { 767 case *PostfixExpression: 768 switch x.Case { 769 case PostfixExpressionCall: // PostfixExpression '(' ArgumentExpressionList ')' 770 switch { 771 case enter: 772 inCall++ 773 if d := x.Declarator(); d != nil { 774 for v := range lhs { 775 d.setLHS(v) 776 } 777 } 778 default: 779 inCall-- 780 } 781 } 782 case *PrimaryExpression: 783 if inCall != 0 || !enter { 784 break 785 } 786 787 if d := x.Declarator(); d != nil { 788 for v := range lhs { 789 d.setLHS(v) 790 } 791 } 792 } 793 return true 794 }) 795 } 796 797 func (n *AssignmentExpression) check(ctx *context, isAsmArg bool) Operand { 798 if n == nil { 799 return noOperand 800 } 801 802 if n.Operand != nil { 803 return n.Operand 804 } 805 806 if ctx.cfg.TrackAssignments && n.AssignmentExpression != nil { 807 defer func() { 808 lhs := map[*Declarator]struct{}{} 809 Inspect(n.UnaryExpression, func(n Node, enter bool) bool { 810 if !enter { 811 return true 812 } 813 814 if x, ok := n.(*PrimaryExpression); ok { 815 lhs[x.Declarator()] = struct{}{} 816 } 817 return true 818 }) 819 setLHS(lhs, n.AssignmentExpression) 820 }() 821 } 822 823 //TODO check for "modifiable lvalue" in left operand 824 n.Operand = noOperand 825 switch n.Case { 826 case AssignmentExpressionCond: // ConditionalExpression 827 n.Operand = n.ConditionalExpression.check(ctx, isAsmArg) 828 n.IsSideEffectsFree = n.ConditionalExpression.IsSideEffectsFree 829 case AssignmentExpressionAssign: // UnaryExpression '=' AssignmentExpression 830 l := n.UnaryExpression.check(ctx, isAsmArg) 831 if d := n.UnaryExpression.Declarator(); d != nil { 832 d.Read -= ctx.readDelta 833 } 834 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 835 d.Write++ 836 if l.Type().Kind() == Array && !d.IsParameter && l.Type().String() != "va_list" { 837 ctx.errNode(n.UnaryExpression, "assignment to expression with array type") 838 break 839 } 840 } 841 842 if !l.IsLValue() { 843 //TODO ctx.errNode(n.UnaryExpression, "expected lvalue") 844 break 845 } 846 847 r := n.AssignmentExpression.check(ctx, isAsmArg) 848 _ = r //TODO check assignability 849 n.Operand = l.(*lvalue).Operand 850 case AssignmentExpressionMul: // UnaryExpression "*=" AssignmentExpression 851 l := n.UnaryExpression.check(ctx, isAsmArg) 852 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 853 d.SubjectOfAsgnOp = true 854 d.Read += ctx.readDelta 855 d.Write++ 856 } 857 if !l.IsLValue() { 858 //TODO panic(n.Position().String()) // report error 859 break 860 } 861 862 r := n.AssignmentExpression.check(ctx, isAsmArg) 863 //TODO check assignability 864 if l.Type().IsArithmeticType() { 865 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 866 n.promote = op.Type() 867 } 868 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 869 case AssignmentExpressionDiv: // UnaryExpression "/=" AssignmentExpression 870 l := n.UnaryExpression.check(ctx, isAsmArg) 871 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 872 d.SubjectOfAsgnOp = true 873 d.Read += ctx.readDelta 874 d.Write++ 875 } 876 if !l.IsLValue() { 877 //TODO panic(n.Position().String()) // report error 878 break 879 } 880 881 r := n.AssignmentExpression.check(ctx, isAsmArg) 882 //TODO check assignability 883 if l.Type().IsArithmeticType() { 884 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 885 n.promote = op.Type() 886 } 887 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 888 case AssignmentExpressionMod: // UnaryExpression "%=" AssignmentExpression 889 l := n.UnaryExpression.check(ctx, isAsmArg) 890 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 891 d.SubjectOfAsgnOp = true 892 d.Read += ctx.readDelta 893 d.Write++ 894 } 895 if !l.IsLValue() { 896 //TODO panic(n.Position().String()) // report error 897 break 898 } 899 900 r := n.AssignmentExpression.check(ctx, isAsmArg) 901 //TODO check assignability 902 if l.Type().IsArithmeticType() { 903 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 904 n.promote = op.Type() 905 } 906 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 907 case AssignmentExpressionAdd: // UnaryExpression "+=" AssignmentExpression 908 l := n.UnaryExpression.check(ctx, isAsmArg) 909 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 910 d.SubjectOfAsgnOp = true 911 d.Read += ctx.readDelta 912 d.Write++ 913 } 914 if !l.IsLValue() { 915 //TODO panic(n.Position().String()) // report error 916 break 917 } 918 919 r := n.AssignmentExpression.check(ctx, isAsmArg) 920 //TODO check assignability 921 n.promote = n.UnaryExpression.Operand.Type() 922 if l.Type().IsArithmeticType() { 923 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 924 n.promote = op.Type() 925 } 926 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 927 case AssignmentExpressionSub: // UnaryExpression "-=" AssignmentExpression 928 l := n.UnaryExpression.check(ctx, isAsmArg) 929 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 930 d.SubjectOfAsgnOp = true 931 d.Read += ctx.readDelta 932 d.Write++ 933 } 934 if !l.IsLValue() { 935 //TODO panic(n.Position().String()) // report error 936 break 937 } 938 939 r := n.AssignmentExpression.check(ctx, isAsmArg) 940 //TODO check assignability 941 n.promote = n.UnaryExpression.Operand.Type() 942 if l.Type().IsArithmeticType() { 943 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 944 n.promote = op.Type() 945 } 946 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 947 case AssignmentExpressionLsh: // UnaryExpression "<<=" AssignmentExpression 948 l := n.UnaryExpression.check(ctx, isAsmArg) 949 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 950 d.SubjectOfAsgnOp = true 951 d.Read += ctx.readDelta 952 d.Write++ 953 } 954 if !l.IsLValue() { 955 //TODO panic(n.Position().String()) // report error 956 break 957 } 958 959 r := n.AssignmentExpression.check(ctx, isAsmArg) 960 //TODO check assignability 961 if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() { 962 //TODO report error 963 break 964 } 965 966 n.promote = r.integerPromotion(ctx, n).Type() 967 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: l.Type()}).integerPromotion(ctx, n) 968 case AssignmentExpressionRsh: // UnaryExpression ">>=" AssignmentExpression 969 l := n.UnaryExpression.check(ctx, isAsmArg) 970 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 971 d.SubjectOfAsgnOp = true 972 d.Read += ctx.readDelta 973 d.Write++ 974 } 975 if !l.IsLValue() { 976 //TODO panic(n.Position().String()) // report error 977 break 978 } 979 980 r := n.AssignmentExpression.check(ctx, isAsmArg) 981 //TODO check assignability 982 if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() { 983 //TODO report error 984 break 985 } 986 987 n.promote = r.integerPromotion(ctx, n).Type() 988 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: l.Type()}).integerPromotion(ctx, n) 989 case AssignmentExpressionAnd: // UnaryExpression "&=" AssignmentExpression 990 l := n.UnaryExpression.check(ctx, isAsmArg) 991 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 992 d.SubjectOfAsgnOp = true 993 d.Read += ctx.readDelta 994 d.Write++ 995 } 996 if !l.IsLValue() { 997 //TODO panic(n.Position().String()) // report error 998 break 999 } 1000 1001 r := n.AssignmentExpression.check(ctx, isAsmArg) 1002 //TODO check assignability 1003 if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() { 1004 //TODO report error 1005 break 1006 } 1007 1008 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 1009 n.promote = op.Type() 1010 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 1011 case AssignmentExpressionXor: // UnaryExpression "^=" AssignmentExpression 1012 l := n.UnaryExpression.check(ctx, isAsmArg) 1013 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 1014 d.SubjectOfAsgnOp = true 1015 d.Read += ctx.readDelta 1016 d.Write++ 1017 } 1018 if !l.IsLValue() { 1019 //TODO panic(n.Position().String()) // report error 1020 break 1021 } 1022 1023 r := n.AssignmentExpression.check(ctx, isAsmArg) 1024 //TODO check assignability 1025 if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() { 1026 //TODO report error 1027 break 1028 } 1029 1030 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 1031 n.promote = op.Type() 1032 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 1033 case AssignmentExpressionOr: // UnaryExpression "|=" AssignmentExpression 1034 l := n.UnaryExpression.check(ctx, isAsmArg) 1035 if d := n.UnaryExpression.Operand.Declarator(); d != nil { 1036 d.SubjectOfAsgnOp = true 1037 d.Read += ctx.readDelta 1038 d.Write++ 1039 } 1040 if !l.IsLValue() { 1041 //TODO panic(n.Position().String()) // report error 1042 break 1043 } 1044 1045 r := n.AssignmentExpression.check(ctx, isAsmArg) 1046 //TODO check assignability 1047 if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() { 1048 //TODO report error 1049 break 1050 } 1051 1052 op, _ := usualArithmeticConversions(ctx, n, l, r, true) 1053 n.promote = op.Type() 1054 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()} 1055 default: 1056 panic(todo("")) 1057 } 1058 return n.Operand 1059 } 1060 1061 func (n *UnaryExpression) check(ctx *context, isAsmArg bool) Operand { 1062 if n == nil { 1063 return noOperand 1064 } 1065 1066 n.Operand = noOperand //TODO- 1067 switch n.Case { 1068 case UnaryExpressionPostfix: // PostfixExpression 1069 n.Operand = n.PostfixExpression.check(ctx, false, isAsmArg) 1070 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 1071 case UnaryExpressionInc: // "++" UnaryExpression 1072 op := n.UnaryExpression.check(ctx, isAsmArg) 1073 if d := op.Declarator(); d != nil { 1074 d.SubjectOfIncDec = true 1075 d.Read += ctx.readDelta 1076 d.Write++ 1077 } 1078 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 1079 case UnaryExpressionDec: // "--" UnaryExpression 1080 op := n.UnaryExpression.check(ctx, isAsmArg) 1081 if d := op.Declarator(); d != nil { 1082 d.SubjectOfIncDec = true 1083 d.Read += ctx.readDelta 1084 d.Write++ 1085 } 1086 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 1087 case UnaryExpressionAddrof: // '&' CastExpression 1088 ctx.not(n, mIntConstExpr) 1089 op := n.CastExpression.addrOf(ctx) 1090 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1091 if op.Type().IsBitFieldType() { 1092 //TODO report error 1093 break 1094 } 1095 1096 d := n.CastExpression.Declarator() 1097 if d != nil { 1098 setAddressTaken(n, d, "'&' CastExpression") 1099 if d.td.register() { 1100 //TODO report error 1101 } 1102 } 1103 1104 // [0], 6.5.3.2 1105 // 1106 // The operand of the unary & operator shall be either a 1107 // function designator, the result of a [] or unary * operator, 1108 // or an lvalue that designates an object that is not a 1109 // bit-field and is not declared with the register 1110 // storage-class specifier. 1111 //TODO 1112 if x, ok := op.(*funcDesignator); ok { 1113 n.Operand = x 1114 break 1115 } 1116 1117 n.Operand = op 1118 case UnaryExpressionDeref: // '*' CastExpression 1119 ctx.not(n, mIntConstExpr) 1120 op := n.CastExpression.check(ctx, isAsmArg) 1121 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1122 if x, ok := op.(*funcDesignator); ok { 1123 n.Operand = x 1124 break 1125 } 1126 1127 if op.Type().Kind() == Function { 1128 n.Operand = op 1129 break 1130 } 1131 1132 if op.Type().Decay().Kind() != Ptr { 1133 //TODO report error 1134 break 1135 } 1136 1137 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: op.Type().Elem()}} 1138 case UnaryExpressionPlus: // '+' CastExpression 1139 op := n.CastExpression.check(ctx, isAsmArg) 1140 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1141 if op == nil { 1142 //TODO report error 1143 break 1144 } 1145 if !op.Type().IsArithmeticType() { 1146 //TODO report error 1147 break 1148 } 1149 1150 if op.Type().IsIntegerType() { 1151 op = op.integerPromotion(ctx, n) 1152 } 1153 n.Operand = op 1154 case UnaryExpressionMinus: // '-' CastExpression 1155 op := n.CastExpression.check(ctx, isAsmArg) 1156 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1157 if op == nil { 1158 //TODO report error 1159 break 1160 } 1161 if op.Type().Kind() == Vector { 1162 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 1163 break 1164 } 1165 1166 if !op.Type().IsArithmeticType() { 1167 //TODO report error 1168 break 1169 } 1170 1171 if op.Type().IsIntegerType() { 1172 op = op.integerPromotion(ctx, n) 1173 } 1174 if v := op.Value(); v != nil { 1175 op = (&operand{abi: &ctx.cfg.ABI, typ: op.Type(), value: v.neg()}).normalize(ctx, n) 1176 } 1177 n.Operand = op 1178 case UnaryExpressionCpl: // '~' CastExpression 1179 op := n.CastExpression.check(ctx, isAsmArg) 1180 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1181 if op.Type().Kind() == Vector { 1182 if !op.Type().Elem().IsIntegerType() { 1183 ctx.errNode(n, "operand must be integer") 1184 } 1185 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 1186 break 1187 } 1188 1189 if op.Type().IsComplexType() { 1190 n.Operand = op 1191 break 1192 } 1193 1194 if !op.Type().IsIntegerType() { 1195 ctx.errNode(n, "operand must be integer") 1196 break 1197 } 1198 1199 op = op.integerPromotion(ctx, n) 1200 if v := op.Value(); v != nil { 1201 op = (&operand{abi: &ctx.cfg.ABI, typ: op.Type(), value: v.cpl()}).normalize(ctx, n) 1202 } 1203 n.Operand = op 1204 case UnaryExpressionNot: // '!' CastExpression 1205 op := n.CastExpression.check(ctx, isAsmArg) 1206 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1207 op2 := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)} 1208 switch { 1209 case op.IsZero(): 1210 op2.value = Int64Value(1) 1211 case op.IsNonZero(): 1212 op2.value = Int64Value(0) 1213 } 1214 n.Operand = op2 1215 case UnaryExpressionSizeofExpr: // "sizeof" UnaryExpression 1216 n.IsSideEffectsFree = true 1217 rd := ctx.readDelta 1218 // [0]6.5.3.4, 2: If the type of the operand is a variable length array type, 1219 // the operand is evaluated; otherwise, the operand is not evaluated and the 1220 // result is an integer constant. 1221 switch op := n.UnaryExpression.Operand; { 1222 case op != nil && op.Type() != nil && op.Type().IsVLA(): 1223 ctx.readDelta = 1 1224 default: 1225 ctx.readDelta = 0 1226 } 1227 ctx.push(ctx.mode &^ mIntConstExpr) 1228 op := n.UnaryExpression.check(ctx, isAsmArg) 1229 ctx.pop() 1230 ctx.readDelta = rd 1231 if op.Type().IsIncomplete() { 1232 break 1233 } 1234 1235 sz := op.Type().Size() 1236 if d := n.UnaryExpression.Declarator(); d != nil && d.IsParameter { 1237 sz = op.Type().Decay().Size() 1238 } 1239 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(sz)}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token)) 1240 case UnaryExpressionSizeofType: // "sizeof" '(' TypeName ')' 1241 n.IsSideEffectsFree = true 1242 rd := ctx.readDelta 1243 ctx.readDelta = 0 1244 ctx.push(ctx.mode) 1245 if ctx.mode&mIntConstExpr != 0 { 1246 ctx.mode |= mIntConstExprAnyCast 1247 } 1248 t := n.TypeName.check(ctx, false, false, nil) 1249 ctx.pop() 1250 ctx.readDelta = rd 1251 if t.IsIncomplete() { 1252 break 1253 } 1254 1255 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(t.Size())}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token)) 1256 case UnaryExpressionLabelAddr: // "&&" IDENTIFIER 1257 abi := &ctx.cfg.ABI 1258 n.Operand = &operand{abi: abi, typ: abi.Ptr(n, abi.Type(Void))} 1259 n.IsSideEffectsFree = true 1260 ctx.not(n, mIntConstExpr) 1261 f := ctx.checkFn 1262 if f == nil { 1263 //TODO report error 1264 break 1265 } 1266 1267 if f.ComputedGotos == nil { 1268 f.ComputedGotos = map[StringID]*UnaryExpression{} 1269 } 1270 f.ComputedGotos[n.Token2.Value] = n 1271 case UnaryExpressionAlignofExpr: // "_Alignof" UnaryExpression 1272 n.IsSideEffectsFree = true 1273 ctx.push(ctx.mode &^ mIntConstExpr) 1274 op := n.UnaryExpression.check(ctx, isAsmArg) 1275 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(op.Type().Align())}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token)) 1276 ctx.pop() 1277 case UnaryExpressionAlignofType: // "_Alignof" '(' TypeName ')' 1278 n.IsSideEffectsFree = true 1279 ctx.push(ctx.mode) 1280 if ctx.mode&mIntConstExpr != 0 { 1281 ctx.mode |= mIntConstExprAnyCast 1282 } 1283 t := n.TypeName.check(ctx, false, false, nil) 1284 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(t.Align())}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token)) 1285 ctx.pop() 1286 case UnaryExpressionImag: // "__imag__" UnaryExpression 1287 ctx.not(n, mIntConstExpr) 1288 n.UnaryExpression.check(ctx, isAsmArg) 1289 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 1290 n.Operand = complexPart(ctx, n.UnaryExpression.Operand) 1291 case UnaryExpressionReal: // "__real__" UnaryExpression 1292 ctx.not(n, mIntConstExpr) 1293 n.UnaryExpression.check(ctx, isAsmArg) 1294 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 1295 n.Operand = complexPart(ctx, n.UnaryExpression.Operand) 1296 default: 1297 panic(todo("")) 1298 } 1299 return n.Operand 1300 } 1301 1302 func complexPart(ctx *context, op Operand) Operand { 1303 var k Kind 1304 switch op.Type().Kind() { 1305 case ComplexChar: 1306 k = Char 1307 case ComplexDouble: 1308 k = Double 1309 case ComplexFloat: 1310 k = Float 1311 case ComplexInt: 1312 k = Int 1313 case ComplexLong: 1314 k = Long 1315 case ComplexLongDouble: 1316 k = LongDouble 1317 case ComplexLongLong: 1318 k = LongLong 1319 case ComplexShort: 1320 k = Short 1321 case ComplexUInt: 1322 k = UInt 1323 case ComplexULong: 1324 k = ULong 1325 case ComplexULongLong: 1326 k = ULongLong 1327 case ComplexUShort: 1328 k = UShort 1329 default: 1330 //TODO report err 1331 return noOperand 1332 } 1333 1334 abi := &ctx.cfg.ABI 1335 typ := abi.Type(k) 1336 return &operand{abi: abi, typ: typ} 1337 } 1338 1339 func sizeT(ctx *context, s Scope, tok Token) Type { 1340 if t := ctx.sizeT; t != nil { 1341 return t 1342 } 1343 1344 t := ctx.stddef(idSizeT, s, tok) 1345 if t.Kind() != Invalid { 1346 ctx.sizeT = t 1347 } 1348 return t 1349 } 1350 1351 func (n *CastExpression) addrOf(ctx *context) Operand { 1352 if n == nil { 1353 return noOperand 1354 } 1355 1356 n.Operand = noOperand //TODO- 1357 switch n.Case { 1358 case CastExpressionUnary: // UnaryExpression 1359 n.Operand = n.UnaryExpression.addrOf(ctx) 1360 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 1361 case CastExpressionCast: // '(' TypeName ')' CastExpression 1362 panic(n.Position().String()) 1363 default: 1364 panic(todo("")) 1365 } 1366 return n.Operand 1367 } 1368 1369 func (n *UnaryExpression) addrOf(ctx *context) Operand { 1370 if n == nil { 1371 return noOperand 1372 } 1373 1374 n.Operand = noOperand //TODO- 1375 switch n.Case { 1376 case UnaryExpressionPostfix: // PostfixExpression 1377 n.Operand = n.PostfixExpression.addrOf(ctx) 1378 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 1379 case UnaryExpressionInc: // "++" UnaryExpression 1380 panic(n.Position().String()) 1381 case UnaryExpressionDec: // "--" UnaryExpression 1382 panic(n.Position().String()) 1383 case UnaryExpressionAddrof: // '&' CastExpression 1384 panic(n.Position().String()) 1385 case UnaryExpressionDeref: // '*' CastExpression 1386 n.Operand = n.CastExpression.check(ctx, false) 1387 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1388 case UnaryExpressionPlus: // '+' CastExpression 1389 panic(n.Position().String()) 1390 case UnaryExpressionMinus: // '-' CastExpression 1391 panic(n.Position().String()) 1392 case UnaryExpressionCpl: // '~' CastExpression 1393 panic(n.Position().String()) 1394 case UnaryExpressionNot: // '!' CastExpression 1395 panic(n.Position().String()) 1396 case UnaryExpressionSizeofExpr: // "sizeof" UnaryExpression 1397 panic(n.Position().String()) 1398 case UnaryExpressionSizeofType: // "sizeof" '(' TypeName ')' 1399 panic(n.Position().String()) 1400 case UnaryExpressionLabelAddr: // "&&" IDENTIFIER 1401 panic(n.Position().String()) 1402 case UnaryExpressionAlignofExpr: // "_Alignof" UnaryExpression 1403 panic(n.Position().String()) 1404 case UnaryExpressionAlignofType: // "_Alignof" '(' TypeName ')' 1405 panic(n.Position().String()) 1406 case UnaryExpressionImag: // "__imag__" UnaryExpression 1407 n.Operand = n.UnaryExpression.addrOf(ctx) 1408 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 1409 case UnaryExpressionReal: // "__real__" UnaryExpression 1410 n.Operand = n.UnaryExpression.addrOf(ctx) 1411 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 1412 default: 1413 panic(todo("")) 1414 } 1415 return n.Operand 1416 } 1417 1418 func (n *PostfixExpression) addrOf(ctx *context) Operand { 1419 if n == nil { 1420 return noOperand 1421 } 1422 1423 n.Operand = noOperand //TODO- 1424 switch n.Case { 1425 case PostfixExpressionPrimary: // PrimaryExpression 1426 n.Operand = n.PrimaryExpression.addrOf(ctx) 1427 n.IsSideEffectsFree = n.PrimaryExpression.IsSideEffectsFree 1428 case PostfixExpressionIndex: // PostfixExpression '[' Expression ']' 1429 pe := n.PostfixExpression.check(ctx, false, false) 1430 if d := n.PostfixExpression.Declarator(); d != nil && d.Type().Kind() != Ptr { 1431 setAddressTaken(n, d, "PostfixExpression '[' Expression ']'") 1432 d.Read += ctx.readDelta 1433 } 1434 e := n.Expression.check(ctx, false) 1435 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree && n.Expression.IsSideEffectsFree 1436 t := pe.Type().Decay() 1437 if t.Kind() == Invalid { 1438 break 1439 } 1440 1441 if t.Kind() == Ptr { 1442 if t := e.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 1443 ctx.errNode(n.Expression, "index must be integer type, have %v", e.Type()) 1444 break 1445 } 1446 1447 n.Operand = n.indexAddr(ctx, &n.Token, pe, e) 1448 break 1449 } 1450 1451 if pe.Type().Kind() == Vector { 1452 if t := e.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 1453 ctx.errNode(n.Expression, "index must be integer type, have %v", e.Type()) 1454 break 1455 } 1456 1457 n.Operand = n.index(ctx, pe, e) 1458 break 1459 } 1460 1461 t = e.Type().Decay() 1462 if t.Kind() == Invalid { 1463 break 1464 } 1465 1466 if t.Kind() == Ptr { 1467 if t := pe.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 1468 ctx.errNode(n.Expression, "index must be integer type, have %v", pe.Type()) 1469 break 1470 } 1471 1472 n.Operand = n.indexAddr(ctx, &n.Token, e, pe) 1473 break 1474 } 1475 1476 ctx.errNode(n, "invalid index expression %v[%v]", pe.Type(), e.Type()) 1477 case PostfixExpressionCall: // PostfixExpression '(' ArgumentExpressionList ')' 1478 panic(n.Position().String()) 1479 case PostfixExpressionSelect: // PostfixExpression '.' IDENTIFIER 1480 op := n.PostfixExpression.addrOf(ctx) 1481 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 1482 if d := n.PostfixExpression.Declarator(); d != nil { 1483 setAddressTaken(n, d, "PostfixExpression '.' IDENTIFIER") 1484 d.Read += ctx.readDelta 1485 } 1486 st := op.Type().Elem() 1487 if k := st.Kind(); k == Invalid || k != Struct && k != Union { 1488 //TODO report error 1489 break 1490 } 1491 1492 f, ok := st.FieldByName(n.Token2.Value) 1493 if !ok { 1494 ctx.errNode(&n.Token2, "unknown or ambiguous field: %s", n.Token2.Value) 1495 break 1496 } 1497 1498 n.Field = f 1499 ft := f.Type() 1500 if f.IsBitField() { 1501 //TODO report error 1502 break 1503 } 1504 1505 ot := ctx.cfg.ABI.Ptr(n, ft) 1506 switch { 1507 case op.IsConst(): 1508 switch x := op.Value().(type) { 1509 case Uint64Value: 1510 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ot, value: x + Uint64Value(f.Offset())} 1511 return n.Operand 1512 case nil: 1513 // nop 1514 default: 1515 //TODO panic(todo(" %v: %T", n.Position(), x)) 1516 } 1517 1518 fallthrough 1519 default: 1520 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ot, offset: op.Offset() + f.Offset()}, declarator: op.Declarator()} 1521 } 1522 case PostfixExpressionPSelect: // PostfixExpression "->" IDENTIFIER 1523 op := n.PostfixExpression.check(ctx, false, false) 1524 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 1525 if d := n.PostfixExpression.Declarator(); d != nil { 1526 d.Read += ctx.readDelta 1527 } 1528 t := op.Type() 1529 if k := t.Decay().Kind(); k == Invalid || k != Ptr { 1530 //TODO report error 1531 break 1532 } 1533 1534 st := t.Elem() 1535 if k := st.Kind(); k == Invalid || k != Struct && k != Union { 1536 //TODO report error 1537 break 1538 } 1539 1540 f, ok := st.FieldByName(n.Token2.Value) 1541 if !ok { 1542 //TODO report error 1543 break 1544 } 1545 1546 n.Field = f 1547 ft := f.Type() 1548 if f.IsBitField() { 1549 //TODO report error 1550 break 1551 } 1552 1553 ot := ctx.cfg.ABI.Ptr(n, ft) 1554 switch { 1555 case op.IsConst(): 1556 switch x := op.Value().(type) { 1557 case Uint64Value: 1558 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ot, value: x + Uint64Value(f.Offset())} 1559 return n.Operand 1560 case nil: 1561 // nop 1562 default: 1563 panic(todo(" %T", x)) 1564 } 1565 1566 fallthrough 1567 default: 1568 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ot, offset: op.Offset() + f.Offset()}, declarator: op.Declarator()} 1569 } 1570 case PostfixExpressionInc: // PostfixExpression "++" 1571 panic(n.Position().String()) 1572 case PostfixExpressionDec: // PostfixExpression "--" 1573 panic(n.Position().String()) 1574 case PostfixExpressionComplit: // '(' TypeName ')' '{' InitializerList ',' '}' 1575 //TODO IsSideEffectsFree 1576 if f := ctx.checkFn; f != nil { 1577 f.CompositeLiterals = append(f.CompositeLiterals, n) 1578 } 1579 t := n.TypeName.check(ctx, false, false, nil) 1580 var v *InitializerValue 1581 if n.InitializerList != nil { 1582 n.InitializerList.isConst = true 1583 n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil, false) 1584 n.InitializerList.setConstZero() 1585 v = &InitializerValue{typ: ctx.cfg.ABI.Ptr(n, t), initializer: n.InitializerList} 1586 } 1587 n.Operand = &lvalue{Operand: (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, t), value: v}).normalize(ctx, n)} 1588 case PostfixExpressionTypeCmp: // "__builtin_types_compatible_p" '(' TypeName ',' TypeName ')' 1589 panic(n.Position().String()) 1590 default: 1591 panic(todo("")) 1592 } 1593 return n.Operand 1594 } 1595 1596 func (n *PostfixExpression) indexAddr(ctx *context, nd Node, pe, e Operand) Operand { 1597 var x uintptr 1598 hasx := false 1599 switch v := e.Value().(type) { 1600 case Int64Value: 1601 x = uintptr(v) 1602 hasx = true 1603 case Uint64Value: 1604 x = uintptr(v) 1605 hasx = true 1606 } 1607 off := x * pe.Type().Elem().Size() 1608 switch y := pe.Value().(type) { 1609 case StringValue, WideStringValue: 1610 if hasx { 1611 return &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, pe.Type().Elem()), value: pe.Value(), offset: off}} 1612 } 1613 case Uint64Value: 1614 if hasx { 1615 return &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, pe.Type().Elem()), value: y + Uint64Value(off)}} 1616 } 1617 } 1618 1619 if d := pe.Declarator(); d != nil && hasx { 1620 r := &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, pe.Type().Elem()), offset: pe.Offset() + off}, declarator: d} 1621 return r 1622 } 1623 1624 return &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, pe.Type().Elem())}} 1625 } 1626 1627 func (n *PrimaryExpression) addrOf(ctx *context) Operand { 1628 if n == nil { 1629 return noOperand 1630 } 1631 1632 n.Operand = noOperand //TODO- 1633 switch n.Case { 1634 case PrimaryExpressionIdent: // IDENTIFIER 1635 n.IsSideEffectsFree = true 1636 n.check(ctx, false, false) 1637 if d := n.Operand.Declarator(); d != nil { 1638 switch d.Type().Kind() { 1639 case Function: 1640 // nop //TODO ? 1641 default: 1642 setAddressTaken(n, d, "&IDENTIFIER") 1643 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, d.Type())}, declarator: d} 1644 } 1645 return n.Operand 1646 } 1647 if ctx.cfg.RejectLateBinding && !ctx.cfg.ignoreUndefinedIdentifiers { 1648 ctx.errNode(n, "front-end: undefined: %s", n.Token.Value) 1649 return noOperand 1650 } 1651 1652 //TODO 1653 case PrimaryExpressionInt: // INTCONST 1654 panic(n.Position().String()) 1655 case PrimaryExpressionFloat: // FLOATCONST 1656 panic(n.Position().String()) 1657 case PrimaryExpressionEnum: // ENUMCONST 1658 panic(n.Position().String()) 1659 case PrimaryExpressionChar: // CHARCONST 1660 panic(n.Position().String()) 1661 case PrimaryExpressionLChar: // LONGCHARCONST 1662 panic(n.Position().String()) 1663 case PrimaryExpressionString: // STRINGLITERAL 1664 panic(n.Position().String()) 1665 case PrimaryExpressionLString: // LONGSTRINGLITERAL 1666 panic(n.Position().String()) 1667 case PrimaryExpressionExpr: // '(' Expression ')' 1668 n.Operand = n.Expression.addrOf(ctx) 1669 n.IsSideEffectsFree = n.Expression.IsSideEffectsFree 1670 case PrimaryExpressionStmt: // '(' CompoundStatement ')' 1671 panic(n.Position().String()) 1672 default: 1673 panic(todo("")) 1674 } 1675 return n.Operand 1676 } 1677 1678 func (n *Expression) addrOf(ctx *context) Operand { 1679 if n == nil { 1680 return noOperand 1681 } 1682 n.Operand = noOperand //TODO- 1683 switch n.Case { 1684 case ExpressionAssign: // AssignmentExpression 1685 n.Operand = n.AssignmentExpression.addrOf(ctx) 1686 n.IsSideEffectsFree = n.AssignmentExpression.IsSideEffectsFree 1687 case ExpressionComma: // Expression ',' AssignmentExpression 1688 panic(n.Position().String()) 1689 default: 1690 panic(todo("")) 1691 } 1692 return n.Operand 1693 } 1694 1695 func (n *AssignmentExpression) addrOf(ctx *context) Operand { 1696 if n == nil { 1697 return noOperand 1698 } 1699 n.Operand = noOperand //TODO- 1700 switch n.Case { 1701 case AssignmentExpressionCond: // ConditionalExpression 1702 n.Operand = n.ConditionalExpression.addrOf(ctx) 1703 n.IsSideEffectsFree = n.ConditionalExpression.IsSideEffectsFree 1704 case AssignmentExpressionAssign: // UnaryExpression '=' AssignmentExpression 1705 panic(n.Position().String()) 1706 case AssignmentExpressionMul: // UnaryExpression "*=" AssignmentExpression 1707 panic(n.Position().String()) 1708 case AssignmentExpressionDiv: // UnaryExpression "/=" AssignmentExpression 1709 panic(n.Position().String()) 1710 case AssignmentExpressionMod: // UnaryExpression "%=" AssignmentExpression 1711 panic(n.Position().String()) 1712 case AssignmentExpressionAdd: // UnaryExpression "+=" AssignmentExpression 1713 panic(n.Position().String()) 1714 case AssignmentExpressionSub: // UnaryExpression "-=" AssignmentExpression 1715 panic(n.Position().String()) 1716 case AssignmentExpressionLsh: // UnaryExpression "<<=" AssignmentExpression 1717 panic(n.Position().String()) 1718 case AssignmentExpressionRsh: // UnaryExpression ">>=" AssignmentExpression 1719 panic(n.Position().String()) 1720 case AssignmentExpressionAnd: // UnaryExpression "&=" AssignmentExpression 1721 panic(n.Position().String()) 1722 case AssignmentExpressionXor: // UnaryExpression "^=" AssignmentExpression 1723 panic(n.Position().String()) 1724 case AssignmentExpressionOr: // UnaryExpression "|=" AssignmentExpression 1725 panic(n.Position().String()) 1726 default: 1727 panic(todo("")) 1728 } 1729 return n.Operand 1730 } 1731 1732 func (n *ConditionalExpression) addrOf(ctx *context) Operand { 1733 if n == nil { 1734 return noOperand 1735 } 1736 n.Operand = noOperand //TODO- 1737 switch n.Case { 1738 case ConditionalExpressionLOr: // LogicalOrExpression 1739 n.Operand = n.LogicalOrExpression.addrOf(ctx) 1740 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree 1741 case ConditionalExpressionCond: // LogicalOrExpression '?' Expression ':' ConditionalExpression 1742 panic(n.Position().String()) 1743 default: 1744 panic(todo("")) 1745 } 1746 return n.Operand 1747 } 1748 1749 func (n *LogicalOrExpression) addrOf(ctx *context) Operand { 1750 if n == nil { 1751 return noOperand 1752 } 1753 1754 n.Operand = noOperand //TODO- 1755 switch n.Case { 1756 case LogicalOrExpressionLAnd: // LogicalAndExpression 1757 n.Operand = n.LogicalAndExpression.addrOf(ctx) 1758 n.IsSideEffectsFree = n.LogicalAndExpression.IsSideEffectsFree 1759 case LogicalOrExpressionLOr: // LogicalOrExpression "||" LogicalAndExpression 1760 panic(n.Position().String()) 1761 default: 1762 panic(todo("")) 1763 } 1764 return n.Operand 1765 } 1766 1767 func (n *LogicalAndExpression) addrOf(ctx *context) Operand { 1768 if n == nil { 1769 return noOperand 1770 } 1771 1772 n.Operand = noOperand //TODO- 1773 switch n.Case { 1774 case LogicalAndExpressionOr: // InclusiveOrExpression 1775 n.Operand = n.InclusiveOrExpression.addrOf(ctx) 1776 n.IsSideEffectsFree = n.InclusiveOrExpression.IsSideEffectsFree 1777 case LogicalAndExpressionLAnd: // LogicalAndExpression "&&" InclusiveOrExpression 1778 panic(n.Position().String()) 1779 default: 1780 panic(todo("")) 1781 } 1782 return n.Operand 1783 } 1784 1785 func (n *InclusiveOrExpression) addrOf(ctx *context) Operand { 1786 if n == nil { 1787 return noOperand 1788 } 1789 1790 n.Operand = noOperand //TODO- 1791 switch n.Case { 1792 case InclusiveOrExpressionXor: // ExclusiveOrExpression 1793 n.Operand = n.ExclusiveOrExpression.addrOf(ctx) 1794 n.IsSideEffectsFree = n.ExclusiveOrExpression.IsSideEffectsFree 1795 case InclusiveOrExpressionOr: // InclusiveOrExpression '|' ExclusiveOrExpression 1796 panic(n.Position().String()) 1797 default: 1798 panic(todo("")) 1799 } 1800 return n.Operand 1801 } 1802 1803 func (n *ExclusiveOrExpression) addrOf(ctx *context) Operand { 1804 if n == nil { 1805 return noOperand 1806 } 1807 1808 n.Operand = noOperand //TODO- 1809 switch n.Case { 1810 case ExclusiveOrExpressionAnd: // AndExpression 1811 n.Operand = n.AndExpression.addrOf(ctx) 1812 n.IsSideEffectsFree = n.AndExpression.IsSideEffectsFree 1813 case ExclusiveOrExpressionXor: // ExclusiveOrExpression '^' AndExpression 1814 panic(n.Position().String()) 1815 default: 1816 panic(todo("")) 1817 } 1818 return n.Operand 1819 } 1820 1821 func (n *AndExpression) addrOf(ctx *context) Operand { 1822 if n == nil { 1823 return noOperand 1824 } 1825 1826 n.Operand = noOperand //TODO- 1827 switch n.Case { 1828 case AndExpressionEq: // EqualityExpression 1829 n.Operand = n.EqualityExpression.addrOf(ctx) 1830 n.IsSideEffectsFree = n.EqualityExpression.IsSideEffectsFree 1831 case AndExpressionAnd: // AndExpression '&' EqualityExpression 1832 panic(n.Position().String()) 1833 default: 1834 panic(todo("")) 1835 } 1836 return n.Operand 1837 } 1838 1839 func (n *EqualityExpression) addrOf(ctx *context) Operand { 1840 if n == nil { 1841 return noOperand 1842 } 1843 1844 n.Operand = noOperand //TODO- 1845 switch n.Case { 1846 case EqualityExpressionRel: // RelationalExpression 1847 n.Operand = n.RelationalExpression.addrOf(ctx) 1848 n.IsSideEffectsFree = n.RelationalExpression.IsSideEffectsFree 1849 case EqualityExpressionEq: // EqualityExpression "==" RelationalExpression 1850 panic(n.Position().String()) 1851 case EqualityExpressionNeq: // EqualityExpression "!=" RelationalExpression 1852 panic(n.Position().String()) 1853 default: 1854 panic(todo("")) 1855 } 1856 return n.Operand 1857 } 1858 1859 func (n *RelationalExpression) addrOf(ctx *context) Operand { 1860 if n == nil { 1861 return noOperand 1862 } 1863 1864 n.Operand = noOperand //TODO- 1865 switch n.Case { 1866 case RelationalExpressionShift: // ShiftExpression 1867 n.Operand = n.ShiftExpression.addrOf(ctx) 1868 n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree 1869 case RelationalExpressionLt: // RelationalExpression '<' ShiftExpression 1870 panic(n.Position().String()) 1871 case RelationalExpressionGt: // RelationalExpression '>' ShiftExpression 1872 panic(n.Position().String()) 1873 case RelationalExpressionLeq: // RelationalExpression "<=" ShiftExpression 1874 panic(n.Position().String()) 1875 case RelationalExpressionGeq: // RelationalExpression ">=" ShiftExpression 1876 panic(n.Position().String()) 1877 default: 1878 panic(todo("")) 1879 } 1880 return n.Operand 1881 } 1882 1883 func (n *ShiftExpression) addrOf(ctx *context) Operand { 1884 if n == nil { 1885 return noOperand 1886 } 1887 1888 n.Operand = noOperand //TODO- 1889 switch n.Case { 1890 case ShiftExpressionAdd: // AdditiveExpression 1891 n.Operand = n.AdditiveExpression.addrOf(ctx) 1892 n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree 1893 case ShiftExpressionLsh: // ShiftExpression "<<" AdditiveExpression 1894 panic(n.Position().String()) 1895 case ShiftExpressionRsh: // ShiftExpression ">>" AdditiveExpression 1896 panic(n.Position().String()) 1897 default: 1898 panic(todo("")) 1899 } 1900 return n.Operand 1901 } 1902 1903 func (n *AdditiveExpression) addrOf(ctx *context) Operand { 1904 if n == nil { 1905 return noOperand 1906 } 1907 1908 n.Operand = noOperand //TODO- 1909 switch n.Case { 1910 case AdditiveExpressionMul: // MultiplicativeExpression 1911 n.Operand = n.MultiplicativeExpression.addrOf(ctx) 1912 n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree 1913 case AdditiveExpressionAdd: // AdditiveExpression '+' MultiplicativeExpression 1914 panic(n.Position().String()) 1915 case AdditiveExpressionSub: // AdditiveExpression '-' MultiplicativeExpression 1916 panic(n.Position().String()) 1917 default: 1918 panic(todo("")) 1919 } 1920 return n.Operand 1921 } 1922 1923 func (n *MultiplicativeExpression) addrOf(ctx *context) Operand { 1924 if n == nil { 1925 return noOperand 1926 } 1927 1928 n.Operand = noOperand //TODO- 1929 switch n.Case { 1930 case MultiplicativeExpressionCast: // CastExpression 1931 n.Operand = n.CastExpression.addrOf(ctx) 1932 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 1933 case MultiplicativeExpressionMul: // MultiplicativeExpression '*' CastExpression 1934 panic(n.Position().String()) 1935 case MultiplicativeExpressionDiv: // MultiplicativeExpression '/' CastExpression 1936 panic(n.Position().String()) 1937 case MultiplicativeExpressionMod: // MultiplicativeExpression '%' CastExpression 1938 panic(n.Position().String()) 1939 default: 1940 panic(todo("")) 1941 } 1942 return n.Operand 1943 } 1944 1945 func (n *TypeName) check(ctx *context, inUnion, isPacked bool, list *[]*TypeSpecifier) Type { 1946 if n == nil { 1947 return noType 1948 } 1949 1950 n.typ = n.SpecifierQualifierList.check(ctx, inUnion, isPacked, list) 1951 if n.AbstractDeclarator != nil { 1952 n.typ = n.AbstractDeclarator.check(ctx, n.typ) 1953 } 1954 for list := n.SpecifierQualifierList; list != nil; list = list.SpecifierQualifierList { 1955 if expr, ok := list.AttributeSpecifier.Has(idVectorSize, idVectorSize2); ok { 1956 n.vectorize(ctx, expr) 1957 break 1958 } 1959 } 1960 return n.typ 1961 } 1962 1963 func (n *TypeName) vectorize(ctx *context, expr *ExpressionList) { 1964 dst := &n.typ 1965 elem := n.typ 1966 switch n.typ.Kind() { 1967 case Function: 1968 dst = &n.typ.(*functionType).result 1969 elem = n.typ.Result() 1970 } 1971 1972 sz := expr.vectorSize(ctx) 1973 if sz == 0 { 1974 sz = elem.Size() 1975 } 1976 if sz%elem.Size() != 0 { 1977 ctx.errNode(expr, "vector size must be a multiple of the base size") 1978 } 1979 b := n.typ.base() 1980 b.size = sz 1981 b.kind = byte(Vector) 1982 *dst = &vectorType{ 1983 typeBase: b, 1984 elem: elem, 1985 length: sz / elem.Size(), 1986 } 1987 } 1988 1989 func (n *AbstractDeclarator) check(ctx *context, typ Type) Type { 1990 if n == nil { 1991 return typ 1992 } 1993 1994 n.typ = noType //TODO- 1995 switch n.Case { 1996 case AbstractDeclaratorPtr: // Pointer 1997 n.typ = n.Pointer.check(ctx, typ) 1998 case AbstractDeclaratorDecl: // Pointer DirectAbstractDeclarator 1999 typ = n.Pointer.check(ctx, typ) 2000 n.typ = n.DirectAbstractDeclarator.check(ctx, typ) 2001 default: 2002 panic(todo("")) 2003 } 2004 return n.typ 2005 } 2006 2007 func (n *DirectAbstractDeclarator) check(ctx *context, typ Type) Type { 2008 if n == nil { 2009 return typ 2010 } 2011 2012 switch n.Case { 2013 case DirectAbstractDeclaratorDecl: // '(' AbstractDeclarator ')' 2014 if n.AbstractDeclarator == nil { 2015 // [0], 6.7.6, 128) 2016 // 2017 // As indicated by the syntax, empty parentheses in a 2018 // type name are interpreted as ‘‘function with no 2019 // parameter specification’’, rather than redundant 2020 // parentheses around the omitted identifier. 2021 panic(todo("")) //TODO 2022 } 2023 2024 return n.AbstractDeclarator.check(ctx, typ) 2025 case DirectAbstractDeclaratorArr: // DirectAbstractDeclarator '[' TypeQualifiers AssignmentExpression ']' 2026 return n.DirectAbstractDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, true, false)) 2027 case DirectAbstractDeclaratorStaticArr: // DirectAbstractDeclarator '[' "static" TypeQualifiers AssignmentExpression ']' 2028 return n.DirectAbstractDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, false, false)) 2029 case DirectAbstractDeclaratorArrStatic: // DirectAbstractDeclarator '[' TypeQualifiers "static" AssignmentExpression ']' 2030 return n.DirectAbstractDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, false, false)) 2031 case DirectAbstractDeclaratorArrStar: // DirectAbstractDeclarator '[' '*' ']' 2032 return n.DirectAbstractDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, nil, true, true)) 2033 case DirectAbstractDeclaratorFunc: // DirectAbstractDeclarator '(' ParameterTypeList ')' 2034 ft := &functionType{typeBase: typeBase{kind: byte(Function)}, result: typ} 2035 n.ParameterTypeList.check(ctx, ft) 2036 return n.DirectAbstractDeclarator.check(ctx, ft) 2037 } 2038 2039 panic(internalErrorf("%v: %v", n.Position(), n.Case)) 2040 } 2041 2042 func (n *ParameterTypeList) check(ctx *context, ft *functionType) { 2043 if n == nil { 2044 return 2045 } 2046 2047 switch n.Case { 2048 case ParameterTypeListList: // ParameterList 2049 n.ParameterList.check(ctx, ft) 2050 case ParameterTypeListVar: // ParameterList ',' "..." 2051 ft.variadic = true 2052 n.ParameterList.check(ctx, ft) 2053 default: 2054 panic(todo("")) 2055 } 2056 } 2057 2058 func (n *ParameterList) check(ctx *context, ft *functionType) { 2059 for ; n != nil; n = n.ParameterList { 2060 p := n.ParameterDeclaration.check(ctx, ft) 2061 ft.params = append(ft.params, p) 2062 } 2063 } 2064 2065 func (n *ParameterDeclaration) check(ctx *context, ft *functionType) *Parameter { 2066 if n == nil { 2067 return nil 2068 } 2069 2070 switch n.Case { 2071 case ParameterDeclarationDecl: // DeclarationSpecifiers Declarator AttributeSpecifierList 2072 typ, _, _ := n.DeclarationSpecifiers.check(ctx, false) 2073 n.Declarator.IsParameter = true 2074 if n.typ = n.Declarator.check(ctx, n.DeclarationSpecifiers, typ, false); n.typ.Kind() == Void { 2075 panic(n.Position().String()) 2076 } 2077 if n.AttributeSpecifierList != nil { 2078 //TODO panic(n.Position().String()) 2079 } 2080 n.AttributeSpecifierList.check(ctx, n.typ.baseP()) 2081 return &Parameter{d: n.Declarator, typ: n.typ} 2082 case ParameterDeclarationAbstract: // DeclarationSpecifiers AbstractDeclarator 2083 n.typ, _, _ = n.DeclarationSpecifiers.check(ctx, false) 2084 if n.AbstractDeclarator != nil { 2085 n.typ = n.AbstractDeclarator.check(ctx, n.typ) 2086 } 2087 return &Parameter{typ: n.typ} 2088 default: 2089 panic(todo("")) 2090 } 2091 } 2092 2093 func (n *Pointer) check(ctx *context, typ Type) (t Type) { 2094 if n == nil || typ == nil { 2095 return typ 2096 } 2097 2098 switch n.Case { 2099 case PointerTypeQual: // '*' TypeQualifiers 2100 n.TypeQualifiers.check(ctx, &n.typeQualifiers) 2101 case PointerPtr: // '*' TypeQualifiers Pointer 2102 n.TypeQualifiers.check(ctx, &n.typeQualifiers) 2103 typ = n.Pointer.check(ctx, typ) 2104 case PointerBlock: // '^' TypeQualifiers 2105 n.TypeQualifiers.check(ctx, &n.typeQualifiers) 2106 default: 2107 panic(todo("")) 2108 } 2109 r := ctx.cfg.ABI.Ptr(n, typ).(*pointerType) 2110 if n.typeQualifiers != nil { 2111 r.typeQualifiers = n.typeQualifiers.check(ctx, (*DeclarationSpecifiers)(nil), false) 2112 } 2113 return r 2114 } 2115 2116 func (n *TypeQualifiers) check(ctx *context, typ **typeBase) { 2117 for ; n != nil; n = n.TypeQualifiers { 2118 switch n.Case { 2119 case TypeQualifiersTypeQual: // TypeQualifier 2120 if *typ == nil { 2121 *typ = &typeBase{} 2122 } 2123 n.TypeQualifier.check(ctx, *typ) 2124 case TypeQualifiersAttribute: // AttributeSpecifier 2125 if *typ == nil { 2126 *typ = &typeBase{} 2127 } 2128 n.AttributeSpecifier.check(ctx, *typ) 2129 default: 2130 panic(todo("")) 2131 } 2132 } 2133 } 2134 2135 func (n *TypeQualifier) check(ctx *context, typ *typeBase) { 2136 if n == nil { 2137 return 2138 } 2139 2140 switch n.Case { 2141 case TypeQualifierConst: // "const" 2142 typ.flags |= fConst 2143 case TypeQualifierRestrict: // "restrict" 2144 typ.flags |= fRestrict 2145 case TypeQualifierVolatile: // "volatile" 2146 typ.flags |= fVolatile 2147 case TypeQualifierAtomic: // "_Atomic" 2148 typ.flags |= fAtomic 2149 default: 2150 panic(todo("")) 2151 } 2152 } 2153 2154 func (n *SpecifierQualifierList) check(ctx *context, inUnion, isPacked bool, list *[]*TypeSpecifier) Type { 2155 n0 := n 2156 typ := &typeBase{} 2157 for ; n != nil; n = n.SpecifierQualifierList { 2158 switch n.Case { 2159 case SpecifierQualifierListTypeSpec: // TypeSpecifier SpecifierQualifierList 2160 n.TypeSpecifier.check(ctx, typ, inUnion) 2161 if list != nil && n.TypeSpecifier.Case != TypeSpecifierAtomic { 2162 *list = append(*list, n.TypeSpecifier) 2163 } 2164 case SpecifierQualifierListTypeQual: // TypeQualifier SpecifierQualifierList 2165 n.TypeQualifier.check(ctx, typ) 2166 case SpecifierQualifierListAlignSpec: // AlignmentSpecifier SpecifierQualifierList 2167 n.AlignmentSpecifier.check(ctx) 2168 case SpecifierQualifierListAttribute: // AttributeSpecifier SpecifierQualifierList 2169 n.AttributeSpecifier.check(ctx, typ) 2170 default: 2171 panic(todo("")) 2172 } 2173 } 2174 return typ.check(ctx, n0, true) 2175 } 2176 2177 func (n *TypeSpecifier) check(ctx *context, typ *typeBase, inUnion bool) { 2178 if n == nil { 2179 return 2180 } 2181 2182 switch n.Case { 2183 case 2184 TypeSpecifierVoid, // "void" 2185 TypeSpecifierChar, // "char" 2186 TypeSpecifierShort, // "short" 2187 TypeSpecifierInt, // "int" 2188 TypeSpecifierInt8, // "__int8" 2189 TypeSpecifierInt16, // "__int16" 2190 TypeSpecifierInt32, // "__int32" 2191 TypeSpecifierInt64, // "__int64" 2192 TypeSpecifierInt128, // "__int128" 2193 TypeSpecifierLong, // "long" 2194 TypeSpecifierFloat, // "float" 2195 TypeSpecifierFloat16, // "__fp16" 2196 TypeSpecifierDecimal32, // "_Decimal32" 2197 TypeSpecifierDecimal64, // "_Decimal64" 2198 TypeSpecifierDecimal128, // "_Decimal128" 2199 TypeSpecifierFloat32, // "_Float32" 2200 TypeSpecifierFloat32x, // "_Float32x" 2201 TypeSpecifierFloat64, // "_Float64" 2202 TypeSpecifierFloat64x, // "_Float64x" 2203 TypeSpecifierFloat128, // "_Float128" 2204 TypeSpecifierFloat80, // "__float80" 2205 TypeSpecifierDouble, // "double" 2206 TypeSpecifierSigned, // "signed" 2207 TypeSpecifierUnsigned, // "unsigned" 2208 TypeSpecifierBool, // "_Bool" 2209 TypeSpecifierComplex: // "_Complex" 2210 // nop 2211 case TypeSpecifierStructOrUnion: // StructOrUnionSpecifier 2212 n.StructOrUnionSpecifier.check(ctx, typ, inUnion) 2213 case TypeSpecifierEnum: // EnumSpecifier 2214 n.EnumSpecifier.check(ctx) 2215 case TypeSpecifierTypedefName: // TYPEDEFNAME 2216 // nop 2217 case TypeSpecifierTypeofExpr: // "typeof" '(' Expression ')' 2218 op := n.Expression.check(ctx, false) 2219 n.typ = op.Type() 2220 case TypeSpecifierTypeofType: // "typeof" '(' TypeName ')' 2221 n.typ = n.TypeName.check(ctx, false, false, nil) 2222 case TypeSpecifierAtomic: // AtomicTypeSpecifier 2223 t := n.AtomicTypeSpecifier.check(ctx) 2224 typ.kind = t.base().kind 2225 typ.flags |= fAtomic 2226 n.typ = typ 2227 case 2228 TypeSpecifierFract, // "_Fract" 2229 TypeSpecifierSat, // "_Sat" 2230 TypeSpecifierAccum: // "_Accum" 2231 // nop 2232 default: 2233 panic(todo("")) 2234 } 2235 } 2236 2237 func (n *AtomicTypeSpecifier) check(ctx *context) Type { 2238 if n == nil { 2239 return nil 2240 } 2241 2242 return n.TypeName.check(ctx, false, false, &n.list) 2243 } 2244 2245 func (n *EnumSpecifier) check(ctx *context) { 2246 if n == nil { 2247 return 2248 } 2249 2250 switch n.Case { 2251 case EnumSpecifierDef: // "enum" AttributeSpecifierList IDENTIFIER '{' EnumeratorList ',' '}' 2252 n.AttributeSpecifierList.check(ctx, nil) 2253 min, max := n.EnumeratorList.check(ctx) 2254 var tmin, tmax Type 2255 switch min := min.(type) { 2256 case Int64Value: 2257 switch { 2258 case min >= 0 && ctx.cfg.UnsignedEnums: 2259 tmin = n.requireUint(ctx, uint64(min)) 2260 switch max := max.(type) { 2261 case Int64Value: 2262 tmax = n.requireUint(ctx, uint64(max)) 2263 case Uint64Value: 2264 tmax = n.requireUint(ctx, uint64(max)) 2265 case nil: 2266 panic(todo("%v:", n.Position())) 2267 } 2268 default: 2269 tmin = n.requireInt(ctx, int64(min)) 2270 switch max := max.(type) { 2271 case Int64Value: 2272 tmax = n.requireInt(ctx, int64(max)) 2273 case Uint64Value: 2274 tmax = n.requireInt(ctx, int64(max)) 2275 case nil: 2276 panic(todo("%v:", n.Position())) 2277 } 2278 } 2279 case Uint64Value: 2280 tmin = n.requireUint(ctx, uint64(min)) 2281 switch max := max.(type) { 2282 case Int64Value: 2283 if max < 0 { 2284 panic(todo("%v: min %v max %v", n.Position(), min, max)) 2285 } 2286 2287 tmax = n.requireUint(ctx, uint64(max)) 2288 case Uint64Value: 2289 tmax = n.requireUint(ctx, uint64(max)) 2290 case nil: 2291 _ = max 2292 panic(todo("%v:", n.Position())) 2293 } 2294 case nil: 2295 panic(todo("%v: %v %T", n.Position(), n.Case, min)) 2296 } 2297 switch { 2298 case tmin.Size() > tmax.Size(): 2299 n.typ = tmin 2300 default: 2301 n.typ = tmax 2302 } 2303 if !n.typ.IsIntegerType() || n.typ.Size() == 0 { //TODO- 2304 panic(todo("")) 2305 } 2306 2307 reg := n.lexicalScope.Parent() == nil 2308 for list := n.EnumeratorList; list != nil; list = list.EnumeratorList { 2309 en := list.Enumerator 2310 en.Operand = en.Operand.convertTo(ctx, en, n.typ) 2311 if reg { 2312 ctx.enums[en.Token.Value] = en.Operand 2313 } 2314 } 2315 case EnumSpecifierTag: // "enum" AttributeSpecifierList IDENTIFIER 2316 n.typ = &taggedType{ 2317 resolutionScope: n.lexicalScope, 2318 tag: n.Token2.Value, 2319 typeBase: &typeBase{kind: byte(Enum)}, 2320 } 2321 default: 2322 panic(todo("")) 2323 } 2324 } 2325 2326 func (n *EnumSpecifier) requireInt(ctx *context, m int64) (r Type) { 2327 var w int 2328 switch { 2329 case m < 0: 2330 w = mathutil.BitLenUint64(uint64(-m)) 2331 default: 2332 w = mathutil.BitLenUint64(uint64(m)) + 1 2333 } 2334 w = mathutil.Max(w, 32) 2335 abi := ctx.cfg.ABI 2336 for k0, v := range intConvRank { 2337 k := Kind(k0) 2338 if k == Bool || k == Enum || v == 0 || !abi.isSignedInteger(k) { 2339 continue 2340 } 2341 2342 t := abi.Types[k] 2343 if int(t.Size)*8 < w { 2344 continue 2345 } 2346 2347 if r == nil || t.Size < r.Size() { 2348 r = abi.Type(k) 2349 } 2350 } 2351 if r == nil || r.Size() == 0 { //TODO- 2352 panic(todo("")) 2353 } 2354 return r 2355 } 2356 2357 func (n *EnumSpecifier) requireUint(ctx *context, m uint64) (r Type) { 2358 w := mathutil.BitLenUint64(m) 2359 w = mathutil.Max(w, 32) 2360 abi := ctx.cfg.ABI 2361 for k0, v := range intConvRank { 2362 k := Kind(k0) 2363 if k == Bool || k == Enum || v == 0 || abi.isSignedInteger(k) { 2364 continue 2365 } 2366 2367 t := abi.Types[k] 2368 if int(t.Size)*8 < w { 2369 continue 2370 } 2371 2372 if r == nil || t.Size < r.Size() { 2373 r = abi.Type(k) 2374 } 2375 } 2376 if r == nil || r.Size() == 0 { //TODO- 2377 panic(todo("")) 2378 } 2379 return r 2380 } 2381 2382 func (n *EnumeratorList) check(ctx *context) (min, max Value) { 2383 var iota Value 2384 for ; n != nil; n = n.EnumeratorList { 2385 iota, min, max = n.Enumerator.check(ctx, iota, min, max) 2386 } 2387 return min, max 2388 } 2389 2390 func (n *Enumerator) check(ctx *context, iota, min, max Value) (Value, Value, Value) { 2391 if n == nil { 2392 return nil, nil, nil 2393 } 2394 2395 if iota == nil { 2396 iota = Int64Value(0) 2397 } 2398 switch n.Case { 2399 case EnumeratorIdent: // IDENTIFIER AttributeSpecifierList 2400 n.AttributeSpecifierList.check(ctx, nil) 2401 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: iota}).normalize(ctx, n) 2402 case EnumeratorExpr: // IDENTIFIER AttributeSpecifierList '=' ConstantExpression 2403 n.AttributeSpecifierList.check(ctx, nil) 2404 n.Operand = n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false) 2405 iota = n.Operand.Value() 2406 default: 2407 panic(todo("")) 2408 } 2409 switch x := iota.(type) { 2410 case Int64Value: 2411 switch m := min.(type) { 2412 case Int64Value: 2413 if x < m { 2414 min = x 2415 } 2416 case Uint64Value: 2417 if x < 0 || Uint64Value(x) < m { 2418 min = x 2419 } 2420 case nil: 2421 min = x 2422 } 2423 switch m := max.(type) { 2424 case Int64Value: 2425 if x > m { 2426 max = x 2427 } 2428 case Uint64Value: 2429 if x >= 0 && Uint64Value(x) > m { 2430 max = x 2431 } 2432 case nil: 2433 max = x 2434 } 2435 x++ 2436 iota = x 2437 case Uint64Value: 2438 switch m := min.(type) { 2439 case Int64Value: 2440 if m < 0 { 2441 break 2442 } 2443 2444 if x < Uint64Value(m) { 2445 min = x 2446 } 2447 case Uint64Value: 2448 if x < m { 2449 min = x 2450 } 2451 case nil: 2452 min = x 2453 } 2454 switch m := max.(type) { 2455 case Int64Value: 2456 if m < 0 { 2457 max = x 2458 break 2459 } 2460 2461 if x > Uint64Value(m) { 2462 max = x 2463 } 2464 2465 case Uint64Value: 2466 if x > m { 2467 max = x 2468 } 2469 case nil: 2470 max = x 2471 } 2472 x++ 2473 iota = x 2474 case nil: 2475 //TODO report type 2476 } 2477 2478 return iota, min, max 2479 } 2480 2481 func (n *ConstantExpression) check(ctx *context, mode mode, isAsmArg bool) Operand { 2482 if n == nil { 2483 return noOperand 2484 } 2485 2486 ctx.push(mode) 2487 n.Operand = n.ConditionalExpression.check(ctx, isAsmArg) 2488 ctx.pop() 2489 return n.Operand 2490 } 2491 2492 func (n *StructOrUnionSpecifier) check(ctx *context, typ *typeBase, inUnion bool) Type { 2493 if n == nil { 2494 return noType 2495 } 2496 2497 switch n.Case { 2498 case StructOrUnionSpecifierDef: // StructOrUnion AttributeSpecifierList IDENTIFIER '{' StructDeclarationList '}' 2499 typ.kind = byte(n.StructOrUnion.check(ctx)) 2500 attr := n.AttributeSpecifierList.check(ctx, typ) 2501 fields := n.StructDeclarationList.check(ctx, inUnion || typ.Kind() == Union, typ.IsPacked()) 2502 m := make(map[StringID]*field, len(fields)) 2503 x := 0 2504 for _, v := range fields { 2505 if v.name != 0 { 2506 v.x = x 2507 v.xs = []int{x} 2508 x++ 2509 m[v.name] = v 2510 } 2511 } 2512 t := (&structType{ 2513 attr: attr, 2514 fields: fields, 2515 m: m, 2516 tag: n.Token.Value, 2517 typeBase: typ, 2518 }).check(ctx, n) 2519 if typ.Kind() == Union { 2520 var k Kind 2521 for _, v := range fields { 2522 if k == Invalid { 2523 k = v.typ.Kind() 2524 continue 2525 } 2526 2527 if v.typ.Kind() != k { 2528 k = Invalid 2529 break 2530 } 2531 } 2532 t.common = k 2533 } 2534 n.typ = t 2535 if nm := n.Token.Value; nm != 0 && n.lexicalScope.Parent() == nil { 2536 ctx.structTypes[nm] = t 2537 } 2538 case StructOrUnionSpecifierTag: // StructOrUnion AttributeSpecifierList IDENTIFIER 2539 typ.kind = byte(n.StructOrUnion.check(ctx)) 2540 attr := n.AttributeSpecifierList.check(ctx, typ.baseP()) 2541 n.typ = &taggedType{ 2542 resolutionScope: n.lexicalScope, 2543 tag: n.Token.Value, 2544 typeBase: typ, 2545 } 2546 if attr != nil { 2547 n.typ = &attributedType{n.typ, attr} 2548 } 2549 default: 2550 panic(todo("")) 2551 } 2552 return n.typ 2553 } 2554 2555 func (n *StructDeclarationList) check(ctx *context, inUnion, isPacked bool) (s []*field) { 2556 for ; n != nil; n = n.StructDeclarationList { 2557 s = append(s, n.StructDeclaration.check(ctx, inUnion, isPacked)...) 2558 } 2559 return s 2560 } 2561 2562 func (n *StructDeclaration) check(ctx *context, inUnion, isPacked bool) (s []*field) { 2563 if n == nil || n.Empty { 2564 return nil 2565 } 2566 2567 typ := n.SpecifierQualifierList.check(ctx, inUnion, isPacked, nil) 2568 if n.StructDeclaratorList != nil { 2569 return n.StructDeclaratorList.check(ctx, n.SpecifierQualifierList, typ, inUnion, isPacked) 2570 } 2571 2572 return []*field{{typ: typ, inUnion: inUnion}} 2573 } 2574 2575 func (n *StructDeclaratorList) check(ctx *context, td typeDescriptor, typ Type, inUnion, isPacked bool) (s []*field) { 2576 for ; n != nil; n = n.StructDeclaratorList { 2577 s = append(s, n.StructDeclarator.check(ctx, td, typ, inUnion, isPacked)) 2578 } 2579 return s 2580 } 2581 2582 func (n *StructDeclarator) check(ctx *context, td typeDescriptor, typ Type, inUnion, isPacked bool) *field { 2583 if n == nil { 2584 return nil 2585 } 2586 2587 if isPacked { 2588 typ.baseP().flags |= fPacked 2589 } 2590 if n.Declarator != nil { 2591 typ = n.Declarator.check(ctx, td, typ, false) 2592 } 2593 if attr := n.AttributeSpecifierList.check(ctx, typ.baseP()); len(attr) != 0 { 2594 typ = &attributedType{typ, attr} 2595 } 2596 sf := &field{ 2597 typ: typ, 2598 d: n, 2599 inUnion: inUnion, 2600 } 2601 switch n.Case { 2602 case StructDeclaratorDecl: // Declarator 2603 sf.name = n.Declarator.Name() 2604 case StructDeclaratorBitField: // Declarator ':' ConstantExpression AttributeSpecifierList 2605 sf.isBitField = true 2606 sf.typ = &bitFieldType{Type: typ, field: sf} 2607 sf.name = n.Declarator.Name() 2608 if op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false); op.Type().IsIntegerType() { 2609 switch x := op.Value().(type) { 2610 case Int64Value: 2611 if x < 0 || x > 64 { 2612 panic("TODO") 2613 } 2614 sf.bitFieldWidth = byte(x) 2615 case Uint64Value: 2616 if x > 64 { 2617 panic("TODO") 2618 } 2619 sf.bitFieldWidth = byte(x) 2620 default: 2621 //dbg("%T", x) 2622 panic(PrettyString(op)) 2623 } 2624 } else { 2625 //dbg("", n.ConstantExpression) 2626 panic(n.Declarator.Position()) 2627 } 2628 n.AttributeSpecifierList.check(ctx, sf.typ.baseP()) 2629 default: 2630 panic(todo("")) 2631 } 2632 return sf 2633 } 2634 2635 func (n *StructOrUnion) check(ctx *context) Kind { 2636 if n == nil { 2637 return Invalid 2638 } 2639 2640 switch n.Case { 2641 case StructOrUnionStruct: // "struct" 2642 return Struct 2643 case StructOrUnionUnion: // "union" 2644 return Union 2645 default: 2646 panic(todo("")) 2647 } 2648 } 2649 2650 func (n *CastExpression) check(ctx *context, isAsmArg bool) Operand { 2651 if n == nil { 2652 return noOperand 2653 } 2654 2655 n.Operand = noOperand //TODO- 2656 switch n.Case { 2657 case CastExpressionUnary: // UnaryExpression 2658 n.Operand = n.UnaryExpression.check(ctx, isAsmArg) 2659 n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree 2660 case CastExpressionCast: // '(' TypeName ')' CastExpression 2661 t := n.TypeName.check(ctx, false, false, nil) 2662 ctx.push(ctx.mode) 2663 if m := ctx.mode; m&mIntConstExpr != 0 && m&mIntConstExprAnyCast == 0 { 2664 if t := n.TypeName.Type(); t != nil && t.Kind() != Int { 2665 ctx.mode &^= mIntConstExpr 2666 } 2667 ctx.mode |= mIntConstExprFloat 2668 } 2669 op := n.CastExpression.check(ctx, isAsmArg) 2670 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 2671 ctx.pop() 2672 n.Operand = op.convertTo(ctx, n, t) 2673 default: 2674 panic(todo("")) 2675 } 2676 return n.Operand 2677 } 2678 2679 func (n *PostfixExpression) check(ctx *context, implicitFunc, isAsmArg bool) Operand { 2680 if n == nil { 2681 return noOperand 2682 } 2683 2684 n.Operand = noOperand //TODO- 2685 out: 2686 switch n.Case { 2687 case PostfixExpressionPrimary: // PrimaryExpression 2688 n.Operand = n.PrimaryExpression.check(ctx, implicitFunc, isAsmArg) 2689 n.IsSideEffectsFree = n.PrimaryExpression.IsSideEffectsFree 2690 case PostfixExpressionIndex: // PostfixExpression '[' Expression ']' 2691 pe := n.PostfixExpression.check(ctx, false, isAsmArg) 2692 if d := pe.Declarator(); d != nil { 2693 d.Read += ctx.readDelta 2694 } 2695 e := n.Expression.check(ctx, isAsmArg) 2696 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree && n.Expression.IsSideEffectsFree 2697 t := pe.Type().Decay() 2698 if t.Kind() == Invalid { 2699 break 2700 } 2701 2702 if t.Kind() == Ptr { 2703 if t := e.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 2704 ctx.errNode(n.Expression, "index must be integer type, have %v", e.Type()) 2705 break 2706 } 2707 2708 n.Operand = n.index(ctx, pe, e) 2709 break 2710 } 2711 2712 if pe.Type().Kind() == Vector { 2713 if t := e.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 2714 ctx.errNode(n.Expression, "index must be integer type, have %v", e.Type()) 2715 break 2716 } 2717 2718 n.Operand = n.index(ctx, pe, e) 2719 break 2720 } 2721 2722 t = e.Type().Decay() 2723 if t.Kind() == Invalid { 2724 break 2725 } 2726 2727 if t.Kind() == Ptr { 2728 if t := pe.Type(); t.Kind() != Invalid && !t.IsIntegerType() { 2729 ctx.errNode(n.Expression, "index must be integer type, have %v", pe.Type()) 2730 break 2731 } 2732 2733 n.Operand = n.index(ctx, e, pe) 2734 break 2735 } 2736 2737 ctx.errNode(n, "invalid index expression %v[%v]", pe.Type(), e.Type()) 2738 case PostfixExpressionCall: // PostfixExpression '(' ArgumentExpressionList ')' 2739 op := n.PostfixExpression.check(ctx, true, isAsmArg) 2740 Inspect(n.PostfixExpression, func(n Node, enter bool) bool { 2741 if !enter { 2742 return true 2743 } 2744 2745 if x, ok := n.(*PrimaryExpression); ok { 2746 if d := x.Declarator(); d != nil { 2747 d.called = true 2748 } 2749 } 2750 return true 2751 }) 2752 args := n.ArgumentExpressionList.check(ctx, n.PostfixExpression.Declarator(), isAsmArg) 2753 switch op.Declarator().Name() { 2754 case idBuiltinConstantPImpl: 2755 if len(args) < 2 { 2756 panic(todo("")) 2757 } 2758 2759 var v Int64Value 2760 if args[1].Value() != nil { 2761 v = 1 2762 } 2763 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: v} 2764 default: 2765 switch n.PostfixExpression.Operand.Value().(type) { 2766 case StringValue, WideStringValue: 2767 if isAsmArg { 2768 // asm("foo": "bar" (a)) 2769 // ^ 2770 break out 2771 } 2772 } 2773 2774 n.Operand = n.checkCall(ctx, n, op.Type(), args, n.ArgumentExpressionList) 2775 } 2776 case PostfixExpressionSelect: // PostfixExpression '.' IDENTIFIER 2777 op := n.PostfixExpression.check(ctx, false, isAsmArg) 2778 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 2779 if d := op.Declarator(); d != nil { 2780 d.Read += ctx.readDelta 2781 } 2782 st := op.Type() 2783 st0 := st.underlyingType() 2784 if k := st.Kind(); k == Invalid || k != Struct && k != Union { 2785 ctx.errNode(n.PostfixExpression, "select expression of wrong type: %s (%s)", st, st0) 2786 break 2787 } 2788 2789 f, ok := st.FieldByName(n.Token2.Value) 2790 if !ok { 2791 ctx.errNode(n.PostfixExpression, "unknown or ambiguous field %q of type %s (%s)", n.Token2.Value, st, st0) 2792 break 2793 } 2794 2795 n.Field = f 2796 ft := f.Type() 2797 if f.IsBitField() { 2798 ft = &bitFieldType{Type: ft, field: f.(*field)} 2799 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ft}} 2800 break 2801 } 2802 2803 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ft, offset: op.Offset() + f.Offset()}} 2804 case PostfixExpressionPSelect: // PostfixExpression "->" IDENTIFIER 2805 op := n.PostfixExpression.check(ctx, false, isAsmArg) 2806 n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree 2807 if d := op.Declarator(); d != nil { 2808 d.Read += ctx.readDelta 2809 } 2810 t := op.Type() 2811 if k := t.Decay().Kind(); k == Invalid || k != Ptr { 2812 //TODO report error 2813 break 2814 } 2815 2816 st := t.Elem() 2817 if k := st.Kind(); k == Invalid || k != Struct && k != Union { 2818 //TODO report error 2819 break 2820 } 2821 2822 f, ok := st.FieldByName(n.Token2.Value) 2823 if !ok { 2824 //TODO report error 2825 break 2826 } 2827 2828 n.Field = f 2829 ft := f.Type() 2830 if f.IsBitField() { 2831 ft = &bitFieldType{Type: ft, field: f.(*field)} 2832 } 2833 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ft}} 2834 case PostfixExpressionInc: // PostfixExpression "++" 2835 op := n.PostfixExpression.check(ctx, false, isAsmArg) 2836 if d := op.Declarator(); d != nil { 2837 d.SubjectOfIncDec = true 2838 d.Read += ctx.readDelta 2839 d.Write++ 2840 } 2841 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 2842 case PostfixExpressionDec: // PostfixExpression "--" 2843 op := n.PostfixExpression.check(ctx, false, isAsmArg) 2844 if d := op.Declarator(); d != nil { 2845 d.SubjectOfIncDec = true 2846 d.Read += ctx.readDelta 2847 d.Write++ 2848 } 2849 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()} 2850 case PostfixExpressionComplit: // '(' TypeName ')' '{' InitializerList ',' '}' 2851 //TODO IsSideEffectsFree 2852 if f := ctx.checkFn; f != nil { 2853 f.CompositeLiterals = append(f.CompositeLiterals, n) 2854 } 2855 t := n.TypeName.check(ctx, false, false, nil) 2856 var v *InitializerValue 2857 if n.InitializerList != nil { 2858 n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil, false) 2859 n.InitializerList.setConstZero() 2860 v = &InitializerValue{typ: t, initializer: n.InitializerList} 2861 } 2862 n.Operand = &lvalue{Operand: (&operand{abi: &ctx.cfg.ABI, typ: t, value: v}).normalize(ctx, n)} 2863 case PostfixExpressionTypeCmp: // "__builtin_types_compatible_p" '(' TypeName ',' TypeName ')' 2864 n.IsSideEffectsFree = true 2865 t1 := n.TypeName.check(ctx, false, false, nil) 2866 t2 := n.TypeName2.check(ctx, false, false, nil) 2867 v := 0 2868 switch { 2869 case t1.IsArithmeticType() && t2.IsArithmeticType(): 2870 if t1.Kind() == t2.Kind() { 2871 v = 1 2872 } 2873 default: 2874 ctx.errNode(n, "ICE: __builtin_types_compatible_p(%v, %v)", t1, t2) 2875 } 2876 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: Int64Value(v)} 2877 case PostfixExpressionChooseExpr: // "__builtin_choose_expr" '(' ConstantExpression ',' AssignmentExpression ',' AssignmentExpression ')' 2878 n.Operand = noOperand 2879 expr1 := n.AssignmentExpression.check(ctx, isAsmArg) 2880 if expr1 == nil { 2881 ctx.errNode(n, "first argument of __builtin_choose_expr must be a constant expression") 2882 break 2883 } 2884 2885 if !expr1.IsConst() { 2886 ctx.errNode(n, "first argument of __builtin_choose_expr must be a constant expression: %v %v", expr1.Value(), expr1.Type()) 2887 break 2888 } 2889 2890 switch { 2891 case expr1.IsNonZero(): 2892 n.Operand = n.AssignmentExpression2.check(ctx, isAsmArg) 2893 n.IsSideEffectsFree = n.AssignmentExpression2.IsSideEffectsFree 2894 default: 2895 n.Operand = n.AssignmentExpression3.check(ctx, isAsmArg) 2896 n.IsSideEffectsFree = n.AssignmentExpression3.IsSideEffectsFree 2897 } 2898 default: 2899 panic(todo("")) 2900 } 2901 return n.Operand 2902 } 2903 2904 func (n *PostfixExpression) index(ctx *context, pe, e Operand) Operand { 2905 var x uintptr 2906 hasx := false 2907 switch v := e.Value().(type) { 2908 case Int64Value: 2909 x = uintptr(v) 2910 hasx = true 2911 case Uint64Value: 2912 x = uintptr(v) 2913 hasx = true 2914 } 2915 off := x * pe.Type().Elem().Size() 2916 switch v := pe.Value().(type) { 2917 case StringValue: 2918 if hasx { 2919 s := StringID(v).String() 2920 var v byte 2921 switch { 2922 case x > uintptr(len(s)): 2923 //TODO report err 2924 return noOperand 2925 case x < uintptr(len(s)): 2926 v = s[x] 2927 } 2928 2929 return (&operand{abi: &ctx.cfg.ABI, typ: pe.Type().Elem(), value: Int64Value(v)}).normalize(ctx, n) 2930 } 2931 case WideStringValue: 2932 if hasx { 2933 s := []rune(StringID(v).String()) 2934 var v rune 2935 switch { 2936 case x > uintptr(len(s)): 2937 //TODO report err 2938 return noOperand 2939 case x < uintptr(len(s)): 2940 v = s[x] 2941 } 2942 2943 return (&operand{abi: &ctx.cfg.ABI, typ: pe.Type().Elem(), value: Int64Value(v)}).normalize(ctx, n) 2944 } 2945 } 2946 2947 if d := pe.Declarator(); d != nil && hasx { 2948 return &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: pe.Type().Elem(), offset: pe.Offset() + off}, declarator: d} 2949 } 2950 2951 return &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: pe.Type().Elem()}} 2952 } 2953 2954 func (n *PostfixExpression) checkCall(ctx *context, nd Node, f Type, args []Operand, argList *ArgumentExpressionList) (r Operand) { 2955 r = noOperand 2956 switch f.Kind() { 2957 case Invalid: 2958 return noOperand 2959 case Function: 2960 // ok 2961 case Ptr: 2962 if e := f.Elem(); e.Kind() == Function { 2963 f = e 2964 break 2965 } 2966 2967 ctx.errNode(nd, "expected function pointer type: %v, %v", f, f.Kind()) 2968 return r 2969 default: 2970 ctx.errNode(nd, "expected function type: %v, %v", f, f.Kind()) 2971 return r 2972 } 2973 2974 r = &operand{abi: &ctx.cfg.ABI, typ: f.Result()} 2975 params := f.Parameters() 2976 if len(params) == 1 && params[0].Type().Kind() == Void { 2977 params = nil 2978 if len(args) != 0 { 2979 //TODO report error 2980 return r 2981 } 2982 } 2983 2984 for i, arg := range args { 2985 var t Type 2986 switch { 2987 case i < len(params): 2988 //TODO check assignability 2989 t = params[i].Type().Decay() 2990 default: 2991 t = defaultArgumentPromotion(ctx, nd, arg).Type() 2992 } 2993 argList.AssignmentExpression.promote = t 2994 argList = argList.ArgumentExpressionList 2995 } 2996 return r 2997 } 2998 2999 func defaultArgumentPromotion(ctx *context, n Node, op Operand) Operand { 3000 t := op.Type().Decay() 3001 if arithmeticTypes[t.Kind()] { 3002 if t.IsIntegerType() { 3003 return op.integerPromotion(ctx, n) 3004 } 3005 3006 switch t.Kind() { 3007 case Float: 3008 return op.convertTo(ctx, n, ctx.cfg.ABI.Type(Double)) 3009 } 3010 } 3011 return op 3012 } 3013 3014 func (n *ArgumentExpressionList) check(ctx *context, f *Declarator, isAsmArg bool) (r []Operand) { 3015 for ; n != nil; n = n.ArgumentExpressionList { 3016 op := n.AssignmentExpression.check(ctx, isAsmArg) 3017 if op.Type() == nil { 3018 ctx.errNode(n, "operand has usupported, invalid or incomplete type") 3019 op = noOperand 3020 } else if op.Type().IsComplexType() { 3021 ctx.checkFn.CallSiteComplexExpr = append(ctx.checkFn.CallSiteComplexExpr, n.AssignmentExpression) 3022 } 3023 r = append(r, op) 3024 if !ctx.cfg.TrackAssignments { 3025 continue 3026 } 3027 3028 Inspect(n.AssignmentExpression, func(n Node, enter bool) bool { 3029 if !enter { 3030 return true 3031 } 3032 3033 if x, ok := n.(*PrimaryExpression); ok { 3034 x.Declarator().setLHS(f) 3035 } 3036 return true 3037 }) 3038 } 3039 return r 3040 } 3041 3042 func (n *Expression) check(ctx *context, isAsmArg bool) Operand { 3043 if n == nil { 3044 return noOperand 3045 } 3046 3047 n.Operand = noOperand //TODO- 3048 switch n.Case { 3049 case ExpressionAssign: // AssignmentExpression 3050 n.Operand = n.AssignmentExpression.check(ctx, isAsmArg) 3051 n.IsSideEffectsFree = n.AssignmentExpression.IsSideEffectsFree 3052 case ExpressionComma: // Expression ',' AssignmentExpression 3053 op := n.Expression.check(ctx, isAsmArg) 3054 n.Operand = n.AssignmentExpression.check(ctx, isAsmArg) 3055 if !op.IsConst() && n.Operand.IsConst() { 3056 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: n.Operand.Type()} 3057 } 3058 n.IsSideEffectsFree = n.Expression.IsSideEffectsFree && n.AssignmentExpression.IsSideEffectsFree 3059 default: 3060 panic(todo("")) 3061 } 3062 return n.Operand 3063 } 3064 3065 func (n *PrimaryExpression) check(ctx *context, implicitFunc, isAsmArg bool) Operand { 3066 if n == nil { 3067 return noOperand 3068 } 3069 3070 n.Operand = noOperand //TODO- 3071 switch n.Case { 3072 case PrimaryExpressionIdent: // IDENTIFIER 3073 n.IsSideEffectsFree = true 3074 return n.checkIdentifier(ctx, implicitFunc) 3075 case PrimaryExpressionInt: // INTCONST 3076 n.IsSideEffectsFree = true 3077 n.Operand = n.intConst(ctx) 3078 case PrimaryExpressionFloat: // FLOATCONST 3079 n.IsSideEffectsFree = true 3080 if ctx.mode&mIntConstExpr != 0 && ctx.mode&mIntConstExprFloat == 0 { 3081 ctx.errNode(n, "invalid integer constant expression") 3082 break 3083 } 3084 3085 n.Operand = n.floatConst(ctx) 3086 case PrimaryExpressionEnum: // ENUMCONST 3087 n.IsSideEffectsFree = true 3088 if e := n.resolvedIn.enumerator(n.Token.Value, n.Token); e != nil { 3089 op := e.Operand.(*operand) 3090 op.typ = ctx.cfg.ABI.Type(Int) // [0] 6.4.4.3/2 3091 n.Operand = op 3092 break 3093 } 3094 3095 //TODO report err 3096 case PrimaryExpressionChar: // CHARCONST 3097 n.IsSideEffectsFree = true 3098 s := []rune(n.Token.Value.String()) 3099 var v Value 3100 switch { 3101 case s[0] <= 255: 3102 // If an integer character constant contains a single character or escape 3103 // sequence, its value is the one that results when an object with type char 3104 // whose value is that of the single character or escape sequence is converted 3105 // to type int. 3106 switch { 3107 case ctx.cfg.ABI.SignedChar: 3108 v = Int64Value(int8(s[0])) 3109 default: 3110 v = Int64Value(s[0]) 3111 } 3112 default: 3113 v = Int64Value(s[0]) 3114 } 3115 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: v}).normalize(ctx, n) 3116 case PrimaryExpressionLChar: // LONGCHARCONST 3117 n.IsSideEffectsFree = true 3118 s := []rune(n.Token.Value.String()) 3119 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: wcharT(ctx, n.lexicalScope, n.Token), value: Int64Value(s[0])}).normalize(ctx, n) 3120 case PrimaryExpressionString: // STRINGLITERAL 3121 n.IsSideEffectsFree = true 3122 ctx.not(n, mIntConstExpr) 3123 typ := ctx.cfg.ABI.Type(Char) 3124 b := typ.base() 3125 b.align = byte(typ.Align()) 3126 b.fieldAlign = byte(typ.FieldAlign()) 3127 b.kind = byte(Array) 3128 sz := uintptr(len(n.Token.Value.String())) + 1 //TODO set sz in cpp 3129 arr := &arrayType{typeBase: b, decay: ctx.cfg.ABI.Ptr(n, typ), elem: typ, length: sz} 3130 arr.setLen(sz) 3131 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: arr, value: StringValue(n.Token.Value)}).normalize(ctx, n) 3132 case PrimaryExpressionLString: // LONGSTRINGLITERAL 3133 n.IsSideEffectsFree = true 3134 ctx.not(n, mIntConstExpr) 3135 typ := wcharT(ctx, n.lexicalScope, n.Token) 3136 b := typ.base() 3137 b.align = byte(typ.Align()) 3138 b.fieldAlign = byte(typ.FieldAlign()) 3139 b.kind = byte(Array) 3140 sz := uintptr(len([]rune(n.Token.Value.String()))) + 1 //TODO set sz in cpp 3141 arr := &arrayType{typeBase: b, decay: ctx.cfg.ABI.Ptr(n, typ), elem: typ, length: sz} 3142 arr.setLen(sz) 3143 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: arr, value: WideStringValue(n.Token.Value)}).normalize(ctx, n) 3144 case PrimaryExpressionExpr: // '(' Expression ')' 3145 n.Operand = n.Expression.check(ctx, isAsmArg) 3146 n.IsSideEffectsFree = n.Expression.IsSideEffectsFree 3147 case PrimaryExpressionStmt: // '(' CompoundStatement ')' 3148 //TODO IsSideEffectsFree 3149 ctx.not(n, mIntConstExpr) 3150 n.Operand = n.CompoundStatement.check(ctx) 3151 if n.Operand == noOperand { 3152 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Void)} 3153 } 3154 default: 3155 panic(todo("")) 3156 } 3157 return n.Operand 3158 } 3159 3160 func wcharT(ctx *context, s Scope, tok Token) Type { 3161 if t := ctx.wcharT; t != nil { 3162 return t 3163 } 3164 3165 t := ctx.stddef(idWCharT, s, tok) 3166 if t.Kind() != Invalid { 3167 ctx.wcharT = t 3168 } 3169 return t 3170 } 3171 3172 func (n *PrimaryExpression) checkIdentifier(ctx *context, implicitFunc bool) Operand { 3173 ctx.not(n, mIntConstExpr) 3174 var d *Declarator 3175 nm := n.Token.Value 3176 if n.resolvedIn == nil { 3177 if ctx.cfg.RejectLateBinding && !ctx.cfg.ignoreUndefinedIdentifiers { 3178 ctx.errNode(n, "front-end: undefined: %s", n.Token.Value) 3179 return noOperand 3180 } 3181 3182 out: 3183 for s := n.lexicalScope; s != nil; s = s.Parent() { 3184 for _, v := range s[nm] { 3185 switch x := v.(type) { 3186 case *Enumerator: 3187 break out 3188 case *Declarator: 3189 if x.IsTypedefName { 3190 d = nil 3191 break out 3192 } 3193 3194 n.resolvedIn = s 3195 n.resolvedTo = x 3196 d = x 3197 t := d.Type() 3198 if t != nil && t.Kind() == Function { 3199 if d.fnDef { 3200 break out 3201 } 3202 3203 continue 3204 } 3205 3206 if t != nil && !t.IsIncomplete() { 3207 break out 3208 } 3209 case *EnumSpecifier, *StructOrUnionSpecifier, *StructDeclarator, *LabeledStatement: 3210 // nop 3211 default: 3212 panic(todo("")) 3213 } 3214 } 3215 } 3216 } 3217 if d == nil && n.resolvedIn != nil { 3218 d = n.resolvedIn.declarator(n.Token.Value, n.Token) 3219 } 3220 if d == nil && !ctx.cfg.DisableBuiltinResolution { 3221 d = builtin(ctx, nm) 3222 } 3223 if d == nil { 3224 _, ok := gccKeywords[nm] 3225 if !ok && implicitFunc { 3226 d := &Declarator{ 3227 DirectDeclarator: &DirectDeclarator{ 3228 lexicalScope: ctx.ast.Scope, 3229 Case: DirectDeclaratorFuncIdent, 3230 DirectDeclarator: &DirectDeclarator{ 3231 lexicalScope: ctx.ast.Scope, 3232 Case: DirectDeclaratorIdent, 3233 Token: Token{Value: nm}, 3234 }, 3235 }, 3236 implicit: true, 3237 } 3238 ed := &ExternalDeclaration{ 3239 Case: ExternalDeclarationDecl, 3240 Declaration: &Declaration{ 3241 DeclarationSpecifiers: &DeclarationSpecifiers{ 3242 Case: DeclarationSpecifiersTypeSpec, 3243 TypeSpecifier: &TypeSpecifier{ 3244 Case: TypeSpecifierInt, 3245 }, 3246 }, 3247 InitDeclaratorList: &InitDeclaratorList{ 3248 InitDeclarator: &InitDeclarator{ 3249 Case: InitDeclaratorDecl, 3250 Declarator: d, 3251 }, 3252 }, 3253 }, 3254 } 3255 ed.check(ctx) 3256 n.Operand = &funcDesignator{Operand: &operand{abi: &ctx.cfg.ABI, typ: d.Type()}, declarator: d} 3257 return n.Operand 3258 } 3259 3260 if !ctx.cfg.ignoreUndefinedIdentifiers { 3261 ctx.errNode(n, "front-end: undefined: %s", n.Token.Value) 3262 } 3263 return noOperand 3264 } 3265 if d == nil { 3266 if !ctx.cfg.ignoreUndefinedIdentifiers { 3267 ctx.errNode(n, "front-end: undefined: %s", n.Token.Value) 3268 } 3269 return noOperand 3270 } 3271 3272 switch d.Linkage { 3273 case Internal: 3274 if d.IsStatic() { 3275 break 3276 } 3277 3278 fallthrough 3279 case External: 3280 s := n.resolvedIn 3281 if s.Parent() == nil { 3282 break 3283 } 3284 3285 for s.Parent() != nil { 3286 s = s.Parent() 3287 } 3288 3289 if d2 := s.declarator(n.Token.Value, Token{}); d2 != nil { 3290 d = d2 3291 } 3292 } 3293 3294 if d.Type() == nil { 3295 ctx.errNode(d, "unresolved type of: %s", n.Token.Value) 3296 return noOperand 3297 } 3298 3299 d.Read += ctx.readDelta 3300 switch t := d.Type(); t.Kind() { 3301 case Function: 3302 n.Operand = &funcDesignator{Operand: &operand{abi: &ctx.cfg.ABI, typ: t}, declarator: d} 3303 default: 3304 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: t}, declarator: d} 3305 } 3306 if !ctx.capture { 3307 return n.Operand 3308 } 3309 3310 for s := n.lexicalScope; s != nil; s = s.Parent() { 3311 if _, ok := s[nm]; ok { 3312 return n.Operand // d in fn scope 3313 } 3314 3315 if _, ok := s[idClosure]; ok { // d in outer scope 3316 if ctx.closure == nil { 3317 ctx.closure = map[StringID]struct{}{} //TODO capture the PrimaryExpression, not the declarator name 3318 } 3319 ctx.closure[nm] = struct{}{} 3320 return n.Operand 3321 } 3322 } 3323 panic(todo("")) 3324 } 3325 3326 func builtin(ctx *context, nm StringID) *Declarator { 3327 id := dict.sid("__builtin_" + nm.String()) 3328 a := ctx.ast.Scope[id] 3329 if len(a) == 0 { 3330 return nil 3331 } 3332 3333 switch x := a[0].(type) { 3334 case *Declarator: 3335 if x.fnDef || x.IsFunctionPrototype() { 3336 return x 3337 } 3338 } 3339 return nil 3340 } 3341 3342 func (n *PrimaryExpression) floatConst(ctx *context) Operand { 3343 s0 := n.Token.String() 3344 s := s0 3345 var cplx, suff string 3346 loop2: 3347 for i := len(s) - 1; i > 0; i-- { 3348 switch s0[i] { 3349 case 'l', 'L': 3350 s = s[:i] 3351 if ctx.cfg.LongDoubleIsDouble { 3352 break 3353 } 3354 3355 suff += "l" 3356 case 'f', 'F': 3357 s = s[:i] 3358 suff += "f" 3359 case 'i', 'I', 'j', 'J': 3360 s = s[:i] 3361 cplx += "i" 3362 default: 3363 break loop2 3364 } 3365 } 3366 3367 if len(suff) > 1 || len(cplx) > 1 { 3368 ctx.errNode(n, "invalid number format") 3369 return noOperand 3370 } 3371 3372 var v float64 3373 var err error 3374 prec := uint(64) 3375 if suff == "l" { 3376 prec = longDoublePrec 3377 } 3378 var bf *big.Float 3379 switch { 3380 case suff == "l" || strings.Contains(s, "p") || strings.Contains(s, "P"): 3381 bf, _, err = big.ParseFloat(strings.ToLower(s), 0, prec, big.ToNearestEven) 3382 if err == nil { 3383 v, _ = bf.Float64() 3384 } 3385 default: 3386 v, err = strconv.ParseFloat(s, 64) 3387 } 3388 if err != nil { 3389 switch { 3390 case !strings.HasPrefix(s, "-") && strings.Contains(err.Error(), "value out of range"): 3391 // linux_386/usr/include/math.h 3392 // 3393 // /* Value returned on overflow. With IEEE 754 floating point, this is 3394 // +Infinity, otherwise the largest representable positive value. */ 3395 // #if __GNUC_PREREQ (3, 3) 3396 // # define HUGE_VAL (__builtin_huge_val ()) 3397 // #else 3398 // /* This may provoke compiler warnings, and may not be rounded to 3399 // +Infinity in all IEEE 754 rounding modes, but is the best that can 3400 // be done in ISO C while remaining a constant expression. 10,000 is 3401 // greater than the maximum (decimal) exponent for all supported 3402 // floating-point formats and widths. */ 3403 // # define HUGE_VAL 1e10000 3404 // #endif 3405 v = math.Inf(1) 3406 default: 3407 ctx.errNode(n, "%v", err) 3408 return noOperand 3409 } 3410 } 3411 3412 // [0]6.4.4.2 3413 switch suff { 3414 case "": 3415 switch { 3416 case cplx != "": 3417 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ComplexDouble), value: Complex128Value(complex(0, v))}).normalize(ctx, n) 3418 default: 3419 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Double), value: Float64Value(v)}).normalize(ctx, n) 3420 } 3421 case "f": 3422 switch { 3423 case cplx != "": 3424 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ComplexFloat), value: Complex64Value(complex(0, float32(v)))}).normalize(ctx, n) 3425 default: 3426 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Float), value: Float32Value(float32(v))}).normalize(ctx, n) 3427 } 3428 case "l": 3429 switch { 3430 case cplx != "": 3431 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ComplexLongDouble), value: Complex256Value{&Float128Value{N: big.NewFloat(0)}, &Float128Value{N: bf}}}).normalize(ctx, n) 3432 default: 3433 return (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(LongDouble), value: &Float128Value{N: bf}}).normalize(ctx, n) 3434 } 3435 default: 3436 //dbg("%q %q %q %q %v", s0, s, suff, cplx, err) 3437 panic("TODO") 3438 } 3439 } 3440 3441 func (n *PrimaryExpression) intConst(ctx *context) Operand { 3442 var val uint64 3443 s0 := n.Token.String() 3444 s := strings.TrimRight(s0, "uUlL") 3445 var decadic bool 3446 switch { 3447 case strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X"): 3448 var err error 3449 if val, err = strconv.ParseUint(s[2:], 16, 64); err != nil { 3450 ctx.errNode(n, "%v", err) 3451 return nil 3452 } 3453 case strings.HasPrefix(s, "0b") || strings.HasPrefix(s, "0B"): 3454 var err error 3455 if val, err = strconv.ParseUint(s[2:], 2, 64); err != nil { 3456 ctx.errNode(n, "%v", err) 3457 return nil 3458 } 3459 case strings.HasPrefix(s, "0"): 3460 var err error 3461 if val, err = strconv.ParseUint(s, 8, 64); err != nil { 3462 ctx.errNode(n, "%v", err) 3463 return nil 3464 } 3465 default: 3466 decadic = true 3467 var err error 3468 if val, err = strconv.ParseUint(s, 10, 64); err != nil { 3469 ctx.errNode(n, "%v", err) 3470 return nil 3471 } 3472 } 3473 3474 suffix := s0[len(s):] 3475 switch suffix = strings.ToLower(suffix); suffix { 3476 case "": 3477 if decadic { 3478 return intConst(ctx, n, s0, val, Int, Long, LongLong) 3479 } 3480 3481 return intConst(ctx, n, s0, val, Int, UInt, Long, ULong, LongLong, ULongLong) 3482 case "u": 3483 return intConst(ctx, n, s0, val, UInt, ULong, ULongLong) 3484 case "l": 3485 if decadic { 3486 return intConst(ctx, n, s0, val, Long, LongLong) 3487 } 3488 3489 return intConst(ctx, n, s0, val, Long, ULong, LongLong, ULongLong) 3490 case "lu", "ul": 3491 return intConst(ctx, n, s0, val, ULong, ULongLong) 3492 case "ll": 3493 if decadic { 3494 return intConst(ctx, n, s0, val, LongLong) 3495 } 3496 3497 return intConst(ctx, n, s0, val, LongLong, ULongLong) 3498 case "llu", "ull": 3499 return intConst(ctx, n, s0, val, ULongLong) 3500 default: 3501 ctx.errNode(n, "invalid suffix: %v", s0) 3502 return nil 3503 } 3504 } 3505 3506 func intConst(ctx *context, n Node, s string, val uint64, list ...Kind) Operand { 3507 abi := ctx.cfg.ABI 3508 b := bits.Len64(val) 3509 for _, k := range list { 3510 sign := 0 3511 if abi.isSignedInteger(k) { 3512 sign = 1 3513 } 3514 if abi.size(k)*8 >= b+sign { 3515 switch { 3516 case sign == 0: 3517 return (&operand{abi: &ctx.cfg.ABI, typ: abi.Type(k), value: Uint64Value(val)}).normalize(ctx, n) 3518 default: 3519 return (&operand{abi: &ctx.cfg.ABI, typ: abi.Type(k), value: Int64Value(val)}).normalize(ctx, n) 3520 } 3521 } 3522 } 3523 3524 ctx.errNode(n, "invalid integer constant %v", s) 3525 return nil 3526 } 3527 3528 func (n *ConditionalExpression) check(ctx *context, isAsmArg bool) Operand { 3529 if n == nil { 3530 return noOperand 3531 } 3532 3533 n.Operand = noOperand //TODO- 3534 switch n.Case { 3535 case ConditionalExpressionLOr: // LogicalOrExpression 3536 n.Operand = n.LogicalOrExpression.check(ctx, isAsmArg) 3537 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree 3538 case ConditionalExpressionCond: // LogicalOrExpression '?' Expression ':' ConditionalExpression 3539 op := n.LogicalOrExpression.check(ctx, isAsmArg) 3540 // The first operand shall have scalar type. 3541 if !op.Type().Decay().IsScalarType() { 3542 //TODO report error 3543 break 3544 } 3545 3546 a := n.Expression.check(ctx, isAsmArg) 3547 b := n.ConditionalExpression.check(ctx, isAsmArg) 3548 at := a.Type().Decay() 3549 bt := b.Type().Decay() 3550 3551 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree && (n.Expression == nil || n.Expression.IsSideEffectsFree) && n.ConditionalExpression.IsSideEffectsFree 3552 var val Value 3553 if op.Value() != nil { 3554 switch { 3555 case op.IsZero(): 3556 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree && n.ConditionalExpression.IsSideEffectsFree 3557 default: 3558 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree && n.Expression.IsSideEffectsFree 3559 } 3560 if a.Value() != nil && b.Value() != nil { //TODO not needed both non nil 3561 switch { 3562 case op.IsZero(): 3563 val = b.Value() 3564 default: 3565 val = a.Value() 3566 } 3567 } 3568 } 3569 3570 if a.Type().Kind() == Invalid && b.Type().Kind() == Invalid { 3571 return noOperand 3572 } 3573 3574 // One of the following shall hold for the second and third 3575 // operands: 3576 //TODO — both operands have the same structure or union type; 3577 //TODO — one operand is a pointer to an object or incomplete type and the other is a pointer to a 3578 //TODO qualified or unqualified version of void. 3579 switch { 3580 // — both operands have arithmetic type; 3581 case a.Type().IsArithmeticType() && b.Type().IsArithmeticType(): 3582 // If both the second and third operands have 3583 // arithmetic type, the result type that would be 3584 // determined by the usual arithmetic conversions, were 3585 // they applied to those two operands, 3586 // is the type of the result. 3587 op, _ := usualArithmeticConversions(ctx, n, a, b, true) 3588 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: op.Type(), value: val}).normalize(ctx, n) 3589 // — both operands have void type; 3590 case a.Type().Kind() == Void && b.Type().Kind() == Void: 3591 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n) 3592 // — one operand is a pointer and the other is a null pointer constant; 3593 case (a.Type().Kind() == Ptr || a.Type().Kind() == Function) && b.IsZero(): 3594 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n) 3595 case (b.Type().Kind() == Ptr || b.Type().Kind() == Function) && a.IsZero(): 3596 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: b.Type(), value: val}).normalize(ctx, n) 3597 // — both operands are pointers to qualified or unqualified versions of compatible types; 3598 case at.Kind() == Ptr && bt.Kind() == Ptr: 3599 //TODO check compatible 3600 //TODO if !at.isCompatibleIgnoreQualifiers(bt) { 3601 //TODO trc("%v: XXXX %v ? %v", n.Token2.Position(), at, bt) 3602 //TODO ctx.assignmentCompatibilityErrorCond(&n.Token2, at, bt) 3603 //TODO } 3604 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: n.Expression.Operand.Type(), value: val}).normalize(ctx, n) 3605 case a.Type().Kind() == Ptr && a.Type().Elem().Kind() == Function && b.Type().Kind() == Function: 3606 //TODO check compatible 3607 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n) 3608 case b.Type().Kind() == Ptr && b.Type().Elem().Kind() == Function && a.Type().Kind() == Function: 3609 //TODO check compatible 3610 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: b.Type(), value: val}).normalize(ctx, n) 3611 case a.Type().Kind() != Invalid: 3612 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n) 3613 case b.Type().Kind() != Invalid: 3614 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: b.Type(), value: val}).normalize(ctx, n) 3615 default: 3616 panic(todo("")) 3617 } 3618 default: 3619 panic(todo("")) 3620 } 3621 return n.Operand 3622 } 3623 3624 func (n *LogicalOrExpression) check(ctx *context, isAsmArg bool) Operand { 3625 if n == nil { 3626 return noOperand 3627 } 3628 3629 n.Operand = noOperand //TODO- 3630 switch n.Case { 3631 case LogicalOrExpressionLAnd: // LogicalAndExpression 3632 n.Operand = n.LogicalAndExpression.check(ctx, isAsmArg) 3633 n.IsSideEffectsFree = n.LogicalAndExpression.IsSideEffectsFree 3634 case LogicalOrExpressionLOr: // LogicalOrExpression "||" LogicalAndExpression 3635 lop := n.LogicalOrExpression.check(ctx, isAsmArg) 3636 rop := n.LogicalAndExpression.check(ctx, isAsmArg) 3637 n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree && n.LogicalAndExpression.IsSideEffectsFree || 3638 lop.Value() != nil && lop.IsNonZero() && n.LogicalOrExpression.IsSideEffectsFree 3639 var v Value 3640 if lop.Value() != nil && rop.Value() != nil { //TODO lop.IsNonZero shortcut 3641 switch { 3642 case n.LogicalOrExpression.Operand.IsNonZero() || n.LogicalAndExpression.Operand.IsNonZero(): 3643 v = Int64Value(1) 3644 default: 3645 v = Int64Value(0) 3646 } 3647 } 3648 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: v}).normalize(ctx, n) 3649 default: 3650 panic(todo("")) 3651 } 3652 return n.Operand 3653 } 3654 3655 func (n *LogicalAndExpression) check(ctx *context, isAsmArg bool) Operand { 3656 if n == nil { 3657 return noOperand 3658 } 3659 3660 n.Operand = noOperand //TODO- 3661 switch n.Case { 3662 case LogicalAndExpressionOr: // InclusiveOrExpression 3663 n.Operand = n.InclusiveOrExpression.check(ctx, isAsmArg) 3664 n.IsSideEffectsFree = n.InclusiveOrExpression.IsSideEffectsFree 3665 case LogicalAndExpressionLAnd: // LogicalAndExpression "&&" InclusiveOrExpression 3666 lop := n.LogicalAndExpression.check(ctx, isAsmArg) 3667 rop := n.InclusiveOrExpression.check(ctx, isAsmArg) 3668 n.IsSideEffectsFree = n.LogicalAndExpression.IsSideEffectsFree && n.InclusiveOrExpression.IsSideEffectsFree || 3669 lop.Value() != nil && lop.IsZero() && n.LogicalAndExpression.IsSideEffectsFree 3670 var v Value 3671 if lop.Value() != nil && rop.Value() != nil { //TODO lop.IsZero shortcut 3672 switch { 3673 case n.LogicalAndExpression.Operand.IsNonZero() && n.InclusiveOrExpression.Operand.IsNonZero(): 3674 v = Int64Value(1) 3675 default: 3676 v = Int64Value(0) 3677 } 3678 } 3679 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: v}).normalize(ctx, n) 3680 default: 3681 panic(todo("")) 3682 } 3683 return n.Operand 3684 } 3685 3686 func (n *InclusiveOrExpression) check(ctx *context, isAsmArg bool) Operand { 3687 if n == nil { 3688 return noOperand 3689 } 3690 3691 n.Operand = noOperand //TODO- 3692 switch n.Case { 3693 case InclusiveOrExpressionXor: // ExclusiveOrExpression 3694 n.Operand = n.ExclusiveOrExpression.check(ctx, isAsmArg) 3695 n.IsSideEffectsFree = n.ExclusiveOrExpression.IsSideEffectsFree 3696 case InclusiveOrExpressionOr: // InclusiveOrExpression '|' ExclusiveOrExpression 3697 a := n.InclusiveOrExpression.check(ctx, isAsmArg) 3698 b := n.ExclusiveOrExpression.check(ctx, isAsmArg) 3699 n.IsSideEffectsFree = n.InclusiveOrExpression.IsSideEffectsFree && n.ExclusiveOrExpression.IsSideEffectsFree 3700 n.promote = noType 3701 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 3702 n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b) 3703 break 3704 } 3705 3706 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 3707 ctx.errNode(n, "operands must be integers") 3708 break 3709 } 3710 3711 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 3712 n.promote = a.Type() 3713 if a.Value() == nil || b.Value() == nil { 3714 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 3715 break 3716 } 3717 3718 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().or(b.Value())}).normalize(ctx, n) 3719 default: 3720 panic(todo("")) 3721 } 3722 return n.Operand 3723 } 3724 3725 func checkBinaryVectorIntegerArtithmetic(ctx *context, n Node, a, b Operand) Operand { 3726 var rt Type 3727 if a.Type().Kind() == Vector { 3728 rt = a.Type() 3729 a = &operand{abi: &ctx.cfg.ABI, typ: a.Type().Elem()} 3730 } 3731 if b.Type().Kind() == Vector { 3732 if rt == nil { 3733 rt = b.Type() 3734 } 3735 b = &operand{abi: &ctx.cfg.ABI, typ: b.Type().Elem()} 3736 } 3737 a, b = usualArithmeticConversions(ctx, n, a, b, true) 3738 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 3739 ctx.errNode(n, "operands must be integers") 3740 } 3741 return &operand{abi: &ctx.cfg.ABI, typ: rt} 3742 } 3743 3744 func (n *ExclusiveOrExpression) check(ctx *context, isAsmArg bool) Operand { 3745 if n == nil { 3746 return noOperand 3747 } 3748 3749 n.Operand = noOperand //TODO- 3750 switch n.Case { 3751 case ExclusiveOrExpressionAnd: // AndExpression 3752 n.Operand = n.AndExpression.check(ctx, isAsmArg) 3753 n.IsSideEffectsFree = n.AndExpression.IsSideEffectsFree 3754 case ExclusiveOrExpressionXor: // ExclusiveOrExpression '^' AndExpression 3755 a := n.ExclusiveOrExpression.check(ctx, isAsmArg) 3756 b := n.AndExpression.check(ctx, isAsmArg) 3757 n.IsSideEffectsFree = n.ExclusiveOrExpression.IsSideEffectsFree && n.AndExpression.IsSideEffectsFree 3758 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 3759 n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b) 3760 break 3761 } 3762 3763 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 3764 ctx.errNode(n, "operands must be integers") 3765 break 3766 } 3767 3768 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 3769 n.promote = a.Type() 3770 if a.Value() == nil || b.Value() == nil { 3771 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 3772 break 3773 } 3774 3775 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().xor(b.Value())}).normalize(ctx, n) 3776 default: 3777 panic(todo("")) 3778 } 3779 return n.Operand 3780 } 3781 3782 func (n *AndExpression) check(ctx *context, isAsmArg bool) Operand { 3783 if n == nil { 3784 return noOperand 3785 } 3786 3787 n.Operand = noOperand //TODO- 3788 switch n.Case { 3789 case AndExpressionEq: // EqualityExpression 3790 n.Operand = n.EqualityExpression.check(ctx, isAsmArg) 3791 n.IsSideEffectsFree = n.EqualityExpression.IsSideEffectsFree 3792 case AndExpressionAnd: // AndExpression '&' EqualityExpression 3793 a := n.AndExpression.check(ctx, isAsmArg) 3794 b := n.EqualityExpression.check(ctx, isAsmArg) 3795 n.IsSideEffectsFree = n.AndExpression.IsSideEffectsFree && n.EqualityExpression.IsSideEffectsFree 3796 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 3797 n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b) 3798 break 3799 } 3800 3801 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 3802 ctx.errNode(n, "operands must be integers") 3803 break 3804 } 3805 3806 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 3807 n.promote = a.Type() 3808 if a.Value() == nil || b.Value() == nil { 3809 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 3810 break 3811 } 3812 3813 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().and(b.Value())}).normalize(ctx, n) 3814 default: 3815 panic(todo("")) 3816 } 3817 return n.Operand 3818 } 3819 3820 func (n *EqualityExpression) check(ctx *context, isAsmArg bool) Operand { 3821 if n == nil { 3822 return noOperand 3823 } 3824 3825 switch n.Case { 3826 case EqualityExpressionRel: // RelationalExpression 3827 n.Operand = n.RelationalExpression.check(ctx, isAsmArg) 3828 n.IsSideEffectsFree = n.RelationalExpression.IsSideEffectsFree 3829 case 3830 EqualityExpressionEq, // EqualityExpression "==" RelationalExpression 3831 EqualityExpressionNeq: // EqualityExpression "!=" RelationalExpression 3832 3833 op := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)} 3834 n.Operand = op 3835 lo := n.EqualityExpression.check(ctx, isAsmArg) 3836 ro := n.RelationalExpression.check(ctx, isAsmArg) 3837 n.IsSideEffectsFree = n.EqualityExpression.IsSideEffectsFree && n.RelationalExpression.IsSideEffectsFree 3838 lt := lo.Type().Decay() 3839 rt := ro.Type().Decay() 3840 n.promote = noType 3841 ok := false 3842 switch { 3843 case lo.Type().Kind() == Vector && ro.Type().Kind() == Vector: 3844 n.Operand = checkVectorComparison(ctx, n, lo.Type(), ro.Type()) 3845 return n.Operand 3846 case lt.IsArithmeticType() && rt.IsArithmeticType(): 3847 op, _ := usualArithmeticConversions(ctx, n, lo, ro, true) 3848 n.promote = op.Type() 3849 ok = true 3850 case lt.Kind() == Ptr && (rt.Kind() == Ptr || rt.IsIntegerType()): 3851 n.promote = lt 3852 //TODO 3853 case (lt.Kind() == Ptr || lt.IsIntegerType()) && rt.Kind() == Ptr: 3854 n.promote = rt 3855 //TODO 3856 case lt.Kind() == Function: 3857 n.promote = ctx.cfg.ABI.Ptr(n, lt) 3858 case rt.Kind() == Function: 3859 n.promote = ctx.cfg.ABI.Ptr(n, rt) 3860 default: 3861 //TODO report error 3862 } 3863 if n.promote.Kind() == Invalid || !ok { 3864 break 3865 } 3866 3867 lo = lo.convertTo(ctx, n, n.promote) 3868 ro = ro.convertTo(ctx, n, n.promote) 3869 if a, b := lo.Value(), ro.Value(); a != nil && b != nil { 3870 switch n.Case { 3871 case EqualityExpressionEq: // EqualityExpression "==" RelationalExpression 3872 op.value = a.eq(b) 3873 case EqualityExpressionNeq: // EqualityExpression "!=" RelationalExpression 3874 op.value = a.neq(b) 3875 } 3876 } 3877 default: 3878 panic(todo("")) 3879 } 3880 return n.Operand 3881 } 3882 3883 func checkVectorComparison(ctx *context, n Node, a, b Type) (r Operand) { 3884 a = a.underlyingType() 3885 b = b.underlyingType() 3886 rt := *a.(*vectorType) 3887 rt.elem = ctx.cfg.ABI.Type(Int) 3888 r = &operand{abi: &ctx.cfg.ABI, typ: &rt} 3889 x := a.Elem() 3890 y := b.Elem() 3891 if x.Kind() != y.Kind() { 3892 ctx.errNode(n, "cannot compare vectors of different element types: %s and %s", x, y) 3893 } 3894 return r 3895 } 3896 3897 func (n *RelationalExpression) check(ctx *context, isAsmArg bool) Operand { 3898 if n == nil { 3899 return noOperand 3900 } 3901 3902 n.Operand = noOperand //TODO- 3903 switch n.Case { 3904 case RelationalExpressionShift: // ShiftExpression 3905 n.Operand = n.ShiftExpression.check(ctx, isAsmArg) 3906 n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree 3907 case 3908 RelationalExpressionLt, // RelationalExpression '<' ShiftExpression 3909 RelationalExpressionGt, // RelationalExpression '>' ShiftExpression 3910 RelationalExpressionLeq, // RelationalExpression "<=" ShiftExpression 3911 RelationalExpressionGeq: // RelationalExpression ">=" ShiftExpression 3912 3913 n.promote = noType 3914 op := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)} 3915 n.Operand = op 3916 lo := n.RelationalExpression.check(ctx, isAsmArg) 3917 ro := n.ShiftExpression.check(ctx, isAsmArg) 3918 n.IsSideEffectsFree = n.RelationalExpression.IsSideEffectsFree && n.ShiftExpression.IsSideEffectsFree 3919 if lo.Type().Kind() == Vector && ro.Type().Kind() == Vector { 3920 n.Operand = checkVectorComparison(ctx, n, lo.Type(), ro.Type()) 3921 break 3922 } 3923 3924 if lo.Type().IsComplexType() || ro.Type().IsComplexType() { 3925 ctx.errNode(&n.Token, "complex numbers are not ordered") 3926 break 3927 } 3928 3929 lt := lo.Type().Decay() 3930 rt := ro.Type().Decay() 3931 n.promote = noType 3932 ok := true 3933 switch { 3934 case lt.IsRealType() && rt.IsRealType(): 3935 op, _ := usualArithmeticConversions(ctx, n, lo, ro, true) 3936 n.promote = op.Type() 3937 case lt.Kind() == Ptr && (rt.Kind() == Ptr || rt.IsIntegerType()): 3938 n.promote = lt 3939 //TODO 3940 case (lt.Kind() == Ptr || lt.IsIntegerType()) && rt.Kind() == Ptr: 3941 n.promote = rt 3942 //TODO 3943 default: 3944 //TODO report error 3945 ok = false 3946 } 3947 if n.promote.Kind() == Invalid || !ok { 3948 break 3949 } 3950 3951 lo = lo.convertTo(ctx, n, n.promote) 3952 ro = ro.convertTo(ctx, n, n.promote) 3953 if a, b := lo.Value(), ro.Value(); a != nil && b != nil { 3954 switch n.Case { 3955 case RelationalExpressionLt: // RelationalExpression '<' ShiftExpression 3956 op.value = a.lt(b) 3957 case RelationalExpressionGt: // RelationalExpression '>' ShiftExpression 3958 op.value = a.gt(b) 3959 case RelationalExpressionLeq: // RelationalExpression "<=" ShiftExpression 3960 op.value = a.le(b) 3961 case RelationalExpressionGeq: // RelationalExpression ">=" ShiftExpression 3962 op.value = a.ge(b) 3963 } 3964 } 3965 default: 3966 panic(todo("")) 3967 } 3968 return n.Operand 3969 } 3970 3971 func (n *ShiftExpression) check(ctx *context, isAsmArg bool) Operand { 3972 if n == nil { 3973 return noOperand 3974 } 3975 3976 n.Operand = noOperand //TODO- 3977 switch n.Case { 3978 case ShiftExpressionAdd: // AdditiveExpression 3979 n.Operand = n.AdditiveExpression.check(ctx, isAsmArg) 3980 n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree 3981 case ShiftExpressionLsh: // ShiftExpression "<<" AdditiveExpression 3982 a := n.ShiftExpression.check(ctx, isAsmArg) 3983 b := n.AdditiveExpression.check(ctx, isAsmArg) 3984 n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree && n.AdditiveExpression.IsSideEffectsFree 3985 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 3986 n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b) 3987 break 3988 } 3989 3990 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 3991 //TODO report err 3992 break 3993 } 3994 3995 a = a.integerPromotion(ctx, n) 3996 b = b.integerPromotion(ctx, n) 3997 n.promote = b.Type() 3998 if a.Value() == nil || b.Value() == nil { 3999 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4000 break 4001 } 4002 4003 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().lsh(b.Value())}).normalize(ctx, n) 4004 case ShiftExpressionRsh: // ShiftExpression ">>" AdditiveExpression 4005 a := n.ShiftExpression.check(ctx, isAsmArg) 4006 b := n.AdditiveExpression.check(ctx, isAsmArg) 4007 n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree && n.AdditiveExpression.IsSideEffectsFree 4008 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4009 n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b) 4010 break 4011 } 4012 4013 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 4014 //TODO report err 4015 break 4016 } 4017 4018 a = a.integerPromotion(ctx, n) 4019 b = b.integerPromotion(ctx, n) 4020 n.promote = b.Type() 4021 if a.Value() == nil || b.Value() == nil { 4022 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4023 break 4024 } 4025 4026 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().rsh(b.Value())}).normalize(ctx, n) 4027 default: 4028 panic(todo("")) 4029 } 4030 return n.Operand 4031 } 4032 4033 func (n *AdditiveExpression) check(ctx *context, isAsmArg bool) Operand { 4034 if n == nil { 4035 return noOperand 4036 } 4037 4038 n.Operand = noOperand //TODO- 4039 switch n.Case { 4040 case AdditiveExpressionMul: // MultiplicativeExpression 4041 n.Operand = n.MultiplicativeExpression.check(ctx, isAsmArg) 4042 n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree 4043 case AdditiveExpressionAdd: // AdditiveExpression '+' MultiplicativeExpression 4044 n.promote = noType 4045 a := n.AdditiveExpression.check(ctx, isAsmArg) 4046 b := n.MultiplicativeExpression.check(ctx, isAsmArg) 4047 n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree && n.MultiplicativeExpression.IsSideEffectsFree 4048 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4049 n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b) 4050 break 4051 } 4052 4053 if t := a.Type().Decay(); t.Kind() == Ptr && b.Type().IsScalarType() { 4054 var x uintptr 4055 hasx := false 4056 switch v := b.Value().(type) { 4057 case Int64Value: 4058 x = uintptr(v) 4059 hasx = true 4060 case Uint64Value: 4061 x = uintptr(v) 4062 hasx = true 4063 } 4064 off := x * a.Type().Elem().Size() 4065 switch y := a.Value().(type) { 4066 case StringValue: 4067 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, a.Type().Elem()), value: y, offset: a.Offset() + off} 4068 default: 4069 switch { 4070 case a.Value() == nil && a.Declarator() != nil && hasx: 4071 n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Ptr(n, a.Type().Elem()), offset: a.Offset() + off}, declarator: a.Declarator()} 4072 default: 4073 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: t} 4074 } 4075 } 4076 break 4077 } 4078 4079 if t := b.Type().Decay(); t.Kind() == Ptr && a.Type().IsScalarType() { 4080 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: t} 4081 break 4082 } 4083 4084 if !a.Type().IsArithmeticType() || !b.Type().IsArithmeticType() { 4085 //TODO report error 4086 break 4087 } 4088 4089 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 4090 n.promote = a.Type() 4091 if a.Value() == nil || b.Value() == nil { 4092 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4093 break 4094 } 4095 4096 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().add(b.Value())}).normalize(ctx, n) 4097 case AdditiveExpressionSub: // AdditiveExpression '-' MultiplicativeExpression 4098 n.promote = noType 4099 a := n.AdditiveExpression.check(ctx, isAsmArg) 4100 b := n.MultiplicativeExpression.check(ctx, isAsmArg) 4101 n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree && n.MultiplicativeExpression.IsSideEffectsFree 4102 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4103 n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b) 4104 break 4105 } 4106 4107 if a.Type().Decay().Kind() == Ptr && b.Type().Decay().Kind() == Ptr { 4108 var val Value 4109 if a.Value() != nil && b.Value() != nil { 4110 ae := a.Type().Decay().Elem() 4111 be := b.Type().Decay().Elem() 4112 switch { 4113 case ae.Size() == be.Size(): 4114 var d int64 4115 switch x := a.Value().(type) { 4116 case Int64Value: 4117 d = int64(x) 4118 case Uint64Value: 4119 d = int64(x) 4120 } 4121 switch x := b.Value().(type) { 4122 case Int64Value: 4123 val = Int64Value(d - int64(x)) 4124 case Uint64Value: 4125 val = Int64Value(d - int64(x)) 4126 } 4127 default: 4128 ctx.errNode(n, "difference of pointers of differently sized elements") 4129 } 4130 } 4131 pt := ptrdiffT(ctx, n.lexicalScope, n.Token) 4132 n.promote = pt 4133 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: pt, value: val} 4134 if val != nil { 4135 n.Operand = n.Operand.convertTo(ctx, n, a.Type()) 4136 } 4137 break 4138 } 4139 4140 if t := a.Type().Decay(); t.Kind() == Ptr && b.Type().IsScalarType() { 4141 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: t} 4142 break 4143 } 4144 4145 if !a.Type().IsArithmeticType() || !b.Type().IsArithmeticType() { 4146 //TODO report error 4147 break 4148 } 4149 4150 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 4151 n.promote = a.Type() 4152 if a.Value() == nil || b.Value() == nil { 4153 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4154 break 4155 } 4156 4157 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().sub(b.Value())}).normalize(ctx, n) 4158 default: 4159 panic(todo("")) 4160 } 4161 return n.Operand 4162 } 4163 4164 func checkBinaryVectorArtithmetic(ctx *context, n Node, a, b Operand) Operand { 4165 var rt Type 4166 if a.Type().Kind() == Vector { 4167 rt = a.Type() 4168 a = &operand{abi: &ctx.cfg.ABI, typ: a.Type().Elem()} 4169 } 4170 if b.Type().Kind() == Vector { 4171 if rt == nil { 4172 rt = b.Type() 4173 } 4174 b = &operand{abi: &ctx.cfg.ABI, typ: b.Type().Elem()} 4175 } 4176 usualArithmeticConversions(ctx, n, a, b, true) 4177 return &operand{abi: &ctx.cfg.ABI, typ: rt} 4178 } 4179 4180 func ptrdiffT(ctx *context, s Scope, tok Token) Type { 4181 if t := ctx.ptrdiffT; t != nil { 4182 return t 4183 } 4184 4185 t := ctx.stddef(idPtrdiffT, s, tok) 4186 if t.Kind() != Invalid { 4187 ctx.ptrdiffT = t 4188 } 4189 return t 4190 } 4191 4192 func (n *MultiplicativeExpression) check(ctx *context, isAsmArg bool) Operand { 4193 if n == nil { 4194 return noOperand 4195 } 4196 4197 n.Operand = noOperand //TODO- 4198 switch n.Case { 4199 case MultiplicativeExpressionCast: // CastExpression 4200 n.Operand = n.CastExpression.check(ctx, isAsmArg) 4201 n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree 4202 case MultiplicativeExpressionMul: // MultiplicativeExpression '*' CastExpression 4203 a := n.MultiplicativeExpression.check(ctx, isAsmArg) 4204 b := n.CastExpression.check(ctx, isAsmArg) 4205 n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree 4206 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4207 n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b) 4208 break 4209 } 4210 4211 if !a.Type().IsArithmeticType() || !b.Type().IsArithmeticType() { 4212 break 4213 } 4214 4215 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 4216 n.promote = a.Type() 4217 if a.Value() == nil || b.Value() == nil { 4218 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4219 break 4220 } 4221 4222 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().mul(b.Value())}).normalize(ctx, n) 4223 case MultiplicativeExpressionDiv: // MultiplicativeExpression '/' CastExpression 4224 a := n.MultiplicativeExpression.check(ctx, isAsmArg) 4225 b := n.CastExpression.check(ctx, isAsmArg) 4226 n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree 4227 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4228 n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b) 4229 break 4230 } 4231 4232 if !a.Type().IsArithmeticType() || !b.Type().IsArithmeticType() { 4233 break 4234 } 4235 4236 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 4237 n.promote = a.Type() 4238 if a.Value() == nil || b.Value() == nil { 4239 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4240 break 4241 } 4242 4243 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().div(b.Value())}).normalize(ctx, n) 4244 case MultiplicativeExpressionMod: // MultiplicativeExpression '%' CastExpression 4245 a := n.MultiplicativeExpression.check(ctx, isAsmArg) 4246 b := n.CastExpression.check(ctx, isAsmArg) 4247 n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree 4248 if a.Type().Kind() == Vector || b.Type().Kind() == Vector { 4249 n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b) 4250 break 4251 } 4252 4253 if !a.Type().IsArithmeticType() || !b.Type().IsArithmeticType() { 4254 break 4255 } 4256 4257 if !a.Type().IsIntegerType() || !b.Type().IsIntegerType() { 4258 ctx.errNode(&n.Token, "the operands of the %% operator shall have integer type.") // [0] 6.5.5, 2 4259 break 4260 } 4261 4262 a, b = usualArithmeticConversions(ctx, &n.Token, a, b, true) 4263 n.promote = a.Type() 4264 if a.Value() == nil || b.Value() == nil { 4265 n.Operand = &operand{abi: &ctx.cfg.ABI, typ: a.Type()} 4266 break 4267 } 4268 4269 n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().mod(b.Value())}).normalize(ctx, n) 4270 default: 4271 panic(todo("")) 4272 } 4273 return n.Operand 4274 } 4275 4276 func (n *Declarator) check(ctx *context, td typeDescriptor, typ Type, tld bool) Type { 4277 if n == nil { 4278 n.typ = ctx.cfg.ABI.Type(Int) 4279 return noType 4280 } 4281 4282 typ = n.Pointer.check(ctx, typ) 4283 n.td = td 4284 if attr := n.AttributeSpecifierList.check(ctx, typ.baseP()); len(attr) != 0 { 4285 typ = &attributedType{typ, attr} 4286 } 4287 n.typ = n.DirectDeclarator.check(ctx, typ) 4288 4289 hasStorageSpecifiers := td.typedef() || td.extern() || td.static() || 4290 td.auto() || td.register() || td.threadLocal() 4291 4292 typ = n.typ 4293 if typ == nil { 4294 n.typ = ctx.cfg.ABI.Type(Int) 4295 ctx.errNode(n, "declarator has unsupported, invalid or incomplete type") 4296 return noType 4297 } 4298 4299 if typ.Kind() == Array && typ.IsVLA() { 4300 if f := ctx.checkFn; f != nil { 4301 f.VLAs = append(f.VLAs, n) 4302 } 4303 } 4304 4305 // 6.2.2 Linkages of identifiers 4306 n.Linkage = None 4307 switch { 4308 case tld && td.static(): 4309 // 3: If the declaration of a file scope identifier for an object or a function 4310 // contains the storage-class specifier static, the identifier has internal 4311 // linkage. 4312 n.Linkage = Internal 4313 case td.extern(): 4314 //TODO 4315 // 4316 // 4: For an identifier declared with the storage-class specifier extern in a 4317 // scope in which a prior declaration of that identifier is visible, 23) if the 4318 // prior declaration specifies internal or external linkage, the linkage of the 4319 // identifier at the later declaration is the same as the linkage specified at 4320 // the prior declaration. If no prior declaration is visible, or if the prior 4321 // declaration specifies no linkage, then the identifier has external linkage. 4322 n.Linkage = External 4323 case 4324 !n.IsParameter && typ.Kind() == Function && !hasStorageSpecifiers, 4325 tld && !hasStorageSpecifiers: 4326 4327 // 5: If the declaration of an identifier for a function has no storage-class 4328 // specifier, its linkage is determined exactly as if it were declared with the 4329 // storage-class specifier extern. 4330 n.Linkage = External 4331 } 4332 4333 // 6.2.4 Storage durations of objects 4334 switch { 4335 case n.Linkage == External, n.Linkage == Internal, td.static(): 4336 // 2: An object whose identifier is declared with external or internal linkage, 4337 // or with the storage-class specifier static has static storage duration. Its 4338 // lifetime is the entire execution of the program and its stored value is 4339 // initialized only once, prior to 4340 // program startup. 4341 n.StorageClass = Static 4342 case n.Linkage == None && !td.static(): 4343 // 4: An object whose identifier is declared with no linkage and without the 4344 // storage-class specifier static has automatic storage duration. 4345 n.StorageClass = Automatic 4346 } 4347 switch { 4348 case n.typ.Kind() == Invalid: 4349 ctx.errNode(n, "declarator has incomplete type") 4350 } 4351 if n.IsTypedefName { 4352 if k, ok := complexTypedefs[n.Name()]; ok { 4353 abi := ctx.cfg.ABI 4354 t := n.typ.Alias() 4355 t.setKind(k) 4356 abi.types[k] = t 4357 abi.Types[k] = ABIType{Size: t.Size(), Align: t.Align(), FieldAlign: t.FieldAlign()} 4358 } 4359 } 4360 switch expr, ok := n.AttributeSpecifierList.Has(idVectorSize, idVectorSize2); { 4361 case ok: 4362 n.vectorize(ctx, expr) 4363 default: 4364 switch x := td.(type) { 4365 case *DeclarationSpecifiers: 4366 for ; x != nil; x = x.DeclarationSpecifiers { 4367 if expr, ok := x.AttributeSpecifier.Has(idVectorSize, idVectorSize2); ok { 4368 n.vectorize(ctx, expr) 4369 break 4370 } 4371 } 4372 } 4373 } 4374 return n.typ 4375 } 4376 4377 func (n *Declarator) vectorize(ctx *context, expr *ExpressionList) { 4378 dst := &n.typ 4379 elem := n.typ 4380 switch n.typ.Kind() { 4381 case Function: 4382 dst = &n.typ.(*functionType).result 4383 elem = n.typ.Result() 4384 } 4385 4386 sz := expr.vectorSize(ctx) 4387 if sz == 0 { 4388 sz = elem.Size() 4389 } 4390 if elem.Size() == 0 { 4391 ctx.errNode(expr, "vector element has zero size") 4392 return 4393 } 4394 4395 if sz%elem.Size() != 0 { 4396 ctx.errNode(expr, "vector size must be a multiple of the base size") 4397 } 4398 b := n.typ.base() 4399 b.size = sz 4400 b.kind = byte(Vector) 4401 *dst = &vectorType{ 4402 typeBase: b, 4403 elem: elem, 4404 length: sz / elem.Size(), 4405 } 4406 } 4407 4408 func (n *ExpressionList) vectorSize(ctx *context) (r uintptr) { 4409 if n.ExpressionList != nil { 4410 ctx.errNode(n, "expected single expression") 4411 return 0 4412 } 4413 4414 switch x := n.AssignmentExpression.Operand.Value().(type) { 4415 case Int64Value: 4416 if x <= 0 { 4417 ctx.errNode(n, "expected integer greater than zero") 4418 return 0 4419 } 4420 4421 r = uintptr(x) 4422 case Uint64Value: 4423 r = uintptr(x) 4424 case nil: 4425 ctx.errNode(n, "expected constant expression") 4426 r = 0 4427 default: 4428 panic(todo("%T", x)) 4429 } 4430 if bits.OnesCount64(uint64(r)) != 1 { 4431 ctx.errNode(n, "expected a power of two") 4432 r = 0 4433 } 4434 return r 4435 } 4436 4437 func (n *DirectDeclarator) check(ctx *context, typ Type) Type { 4438 if n == nil { 4439 return noType 4440 } 4441 4442 switch n.Case { 4443 case DirectDeclaratorIdent: // IDENTIFIER Asm 4444 n.Asm.check(ctx) 4445 return typ 4446 case DirectDeclaratorDecl: // '(' AttributeSpecifierList Declarator ')' 4447 n.AttributeSpecifierList.check(ctx, typ.baseP()) 4448 return n.Declarator.check(ctx, noTypeDescriptor, typ, false) 4449 case DirectDeclaratorArr: // DirectDeclarator '[' TypeQualifiers AssignmentExpression ']' 4450 return n.DirectDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, true, false)) 4451 case DirectDeclaratorStaticArr: // DirectDeclarator '[' "static" TypeQualifiers AssignmentExpression ']' 4452 return n.DirectDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, false, false)) 4453 case DirectDeclaratorArrStatic: // DirectDeclarator '[' TypeQualifiers "static" AssignmentExpression ']' 4454 return n.DirectDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, n.AssignmentExpression, false, false)) 4455 case DirectDeclaratorStar: // DirectDeclarator '[' TypeQualifiers '*' ']' 4456 return n.DirectDeclarator.check(ctx, checkArray(ctx, &n.Token, typ, nil, true, true)) 4457 case DirectDeclaratorFuncParam: // DirectDeclarator '(' ParameterTypeList ')' 4458 ft := &functionType{typeBase: typeBase{kind: byte(Function)}, result: typ} 4459 if typ != nil && typ.Inline() { 4460 ft.typeBase.flags = fInline 4461 } 4462 n.ParameterTypeList.check(ctx, ft) 4463 return n.DirectDeclarator.check(ctx, ft) 4464 case DirectDeclaratorFuncIdent: // DirectDeclarator '(' IdentifierList ')' 4465 ft := &functionType{typeBase: typeBase{kind: byte(Function)}, result: typ, paramList: n.IdentifierList.check(ctx)} 4466 if typ != nil && typ.Inline() { 4467 ft.typeBase.flags = fInline 4468 } 4469 if n.idListNoDeclList { 4470 n.checkIdentList(ctx, ft) 4471 } 4472 return n.DirectDeclarator.check(ctx, ft) 4473 } 4474 4475 panic(internalErrorf("%v: %v", n.Position(), n.Case)) 4476 } 4477 4478 func (n *DirectDeclarator) checkIdentList(ctx *context, ft *functionType) { 4479 s := n.paramScope 4480 for _, nm := range ft.paramList { 4481 d := s[nm][0].(*Declarator) 4482 d.check(ctx, noTypeDescriptor, ctx.cfg.ABI.Type(Int), false) 4483 ft.params = append(ft.params, &Parameter{d, d.Type()}) 4484 } 4485 } 4486 4487 func checkArray(ctx *context, n Node, typ Type, expr *AssignmentExpression, exprIsOptional, noExpr bool) Type { //TODO pass and use typeQualifiers 4488 if typ == nil { 4489 ctx.errNode(n, "array of invalid or incomplete type") 4490 return noType 4491 } 4492 4493 b := typ.base() 4494 b.align = byte(typ.Align()) 4495 b.fieldAlign = byte(typ.FieldAlign()) 4496 b.kind = byte(Array) 4497 switch { 4498 case expr != nil && noExpr: 4499 panic(todo("")) 4500 case expr != nil: 4501 op := expr.check(ctx, false) 4502 if op.Type().Kind() == Invalid { 4503 return noType 4504 } 4505 4506 if !op.Type().IsIntegerType() { 4507 //TODO report err 4508 return noType 4509 } 4510 4511 var length uintptr 4512 var vla bool 4513 var vlaExpr *AssignmentExpression 4514 switch x := op.Value().(type) { 4515 case nil: 4516 vla = true 4517 vlaExpr = expr 4518 case Int64Value: 4519 length = uintptr(x) 4520 case Uint64Value: 4521 length = uintptr(x) 4522 } 4523 switch { 4524 case vla: 4525 b.size = ctx.cfg.ABI.Types[Ptr].Size 4526 default: 4527 if typ.IsIncomplete() { 4528 //TODO report error 4529 return noType 4530 } 4531 4532 b.size = length * typ.Size() 4533 } 4534 return &arrayType{typeBase: b, decay: ctx.cfg.ABI.Ptr(n, typ), elem: typ, length: length, vla: vla, expr: vlaExpr} 4535 case noExpr: 4536 // nop 4537 case !exprIsOptional: 4538 panic(todo("")) 4539 } 4540 b.flags |= fIncomplete 4541 return &arrayType{typeBase: b, decay: ctx.cfg.ABI.Ptr(n, typ), elem: typ} 4542 } 4543 4544 func (n *IdentifierList) check(ctx *context) (r []StringID) { 4545 for ; n != nil; n = n.IdentifierList { 4546 tok := n.Token2.Value 4547 if tok == 0 { 4548 tok = n.Token.Value 4549 } 4550 r = append(r, tok) 4551 } 4552 return r 4553 } 4554 4555 func (n *Asm) check(ctx *context) { 4556 if n == nil { 4557 return 4558 } 4559 4560 n.AsmQualifierList.check(ctx) 4561 n.AsmArgList.check(ctx) 4562 } 4563 4564 func (n *AsmArgList) check(ctx *context) { 4565 for ; n != nil; n = n.AsmArgList { 4566 n.AsmExpressionList.check(ctx) 4567 } 4568 } 4569 4570 func (n *AsmExpressionList) check(ctx *context) { 4571 if ctx.cfg.DoNotTypecheckAsm { 4572 return 4573 } 4574 4575 for ; n != nil; n = n.AsmExpressionList { 4576 n.AsmIndex.check(ctx) 4577 n.AssignmentExpression.check(ctx, true) 4578 } 4579 } 4580 4581 func (n *AsmIndex) check(ctx *context) { 4582 if n == nil { 4583 return 4584 } 4585 4586 n.Expression.check(ctx, true) 4587 } 4588 4589 func (n *AsmQualifierList) check(ctx *context) { 4590 for ; n != nil; n = n.AsmQualifierList { 4591 n.AsmQualifier.check(ctx) 4592 } 4593 } 4594 4595 func (n *AsmQualifier) check(ctx *context) { 4596 if n == nil { 4597 return 4598 } 4599 4600 switch n.Case { 4601 case AsmQualifierVolatile: // "volatile" 4602 //TODO 4603 case AsmQualifierInline: // "inline" 4604 //TODO 4605 case AsmQualifierGoto: // "goto" 4606 //TODO 4607 default: 4608 panic(todo("")) 4609 } 4610 } 4611 4612 func (n *AttributeSpecifierList) check(ctx *context, t *typeBase) (a []*AttributeSpecifier) { 4613 for ; n != nil; n = n.AttributeSpecifierList { 4614 a = append(a, n.AttributeSpecifier.check(ctx, t)) 4615 } 4616 return a 4617 } 4618 4619 func (n *AttributeSpecifier) check(ctx *context, t *typeBase) *AttributeSpecifier { 4620 if n == nil { 4621 return nil 4622 } 4623 4624 n.AttributeValueList.check(ctx, t) 4625 return n 4626 } 4627 4628 func (n *AttributeValueList) check(ctx *context, t *typeBase) { 4629 for ; n != nil; n = n.AttributeValueList { 4630 n.AttributeValue.check(ctx, t) 4631 } 4632 } 4633 4634 func (n *AttributeValue) check(ctx *context, t *typeBase) { 4635 if n == nil { 4636 return 4637 } 4638 4639 switch n.Case { 4640 case AttributeValueIdent: // IDENTIFIER 4641 if n.Token.Value == idPacked && t != nil { 4642 t.flags |= fPacked 4643 } 4644 case AttributeValueExpr: // IDENTIFIER '(' ExpressionList ')' 4645 v := ctx.cfg.ignoreErrors 4646 ctx.cfg.ignoreErrors = true 4647 defer func() { ctx.cfg.ignoreErrors = v }() 4648 n.ExpressionList.check(ctx, false) 4649 if n.Token.Value == idAligned && n.ExpressionList != nil && t != nil { 4650 switch x := n.ExpressionList.AssignmentExpression.Operand.Value().(type) { 4651 case Int64Value: 4652 t.setAligned(int(x)) 4653 switch t.Kind() { 4654 case Struct, Union: 4655 ctx.structs[StructInfo{Size: t.Size(), Align: t.Align()}] = struct{}{} 4656 } 4657 } 4658 } 4659 default: 4660 panic(todo("")) 4661 } 4662 } 4663 4664 func (n *ExpressionList) check(ctx *context, isAsmArg bool) { 4665 for ; n != nil; n = n.ExpressionList { 4666 n.AssignmentExpression.check(ctx, isAsmArg) 4667 } 4668 } 4669 4670 func (n *DeclarationSpecifiers) check(ctx *context, inUnion bool) (r Type, inline, noret bool) { 4671 n0 := n 4672 typ := &typeBase{} 4673 for ; n != nil; n = n.DeclarationSpecifiers { 4674 switch n.Case { 4675 case DeclarationSpecifiersStorage: // StorageClassSpecifier DeclarationSpecifiers 4676 n.StorageClassSpecifier.check(ctx, n) 4677 case DeclarationSpecifiersTypeSpec: // TypeSpecifier DeclarationSpecifiers 4678 n.TypeSpecifier.check(ctx, typ, inUnion) 4679 case DeclarationSpecifiersTypeQual: // TypeQualifier DeclarationSpecifiers 4680 n.TypeQualifier.check(ctx, typ) 4681 case DeclarationSpecifiersFunc: // FunctionSpecifier DeclarationSpecifiers 4682 if n.FunctionSpecifier == nil { 4683 break 4684 } 4685 4686 switch n.FunctionSpecifier.Case { 4687 case FunctionSpecifierInline: // "inline" 4688 inline = true 4689 case FunctionSpecifierNoreturn: // "_Noreturn" 4690 noret = true 4691 default: 4692 panic(todo("")) 4693 } 4694 case DeclarationSpecifiersAlignSpec: // AlignmentSpecifier DeclarationSpecifiers 4695 n.AlignmentSpecifier.check(ctx) 4696 case DeclarationSpecifiersAttribute: // AttributeSpecifier DeclarationSpecifiers 4697 n.AttributeSpecifier.check(ctx, typ) 4698 default: 4699 panic(todo("")) 4700 } 4701 } 4702 r = typ.check(ctx, n0, true) 4703 return r, inline, noret 4704 } 4705 4706 func (n *AlignmentSpecifier) check(ctx *context) { 4707 if n == nil { 4708 return 4709 } 4710 4711 switch n.Case { 4712 case AlignmentSpecifierAlignasType: // "_Alignas" '(' TypeName ')' 4713 n.TypeName.check(ctx, false, false, nil) 4714 //TODO actually set the alignment 4715 case AlignmentSpecifierAlignasExpr: // "_Alignas" '(' ConstantExpression ')' 4716 n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false) 4717 //TODO actually set the alignment 4718 default: 4719 panic(todo("")) 4720 } 4721 } 4722 4723 func (n *StorageClassSpecifier) check(ctx *context, ds *DeclarationSpecifiers) { 4724 if n == nil { 4725 return 4726 } 4727 4728 switch n.Case { 4729 case StorageClassSpecifierTypedef: // "typedef" 4730 ds.class |= fTypedef 4731 case StorageClassSpecifierExtern: // "extern" 4732 ds.class |= fExtern 4733 case StorageClassSpecifierStatic: // "static" 4734 ds.class |= fStatic 4735 case StorageClassSpecifierAuto: // "auto" 4736 ds.class |= fAuto 4737 case StorageClassSpecifierRegister: // "register" 4738 ds.class |= fRegister 4739 case StorageClassSpecifierThreadLocal: // "_Thread_local" 4740 ds.class |= fThreadLocal 4741 default: 4742 panic(todo("")) 4743 } 4744 c := bits.OnesCount(uint(ds.class & (fTypedef | fExtern | fStatic | fAuto | fRegister | fThreadLocal))) 4745 if c == 1 { 4746 return 4747 } 4748 4749 // [2], 6.7.1, 2 4750 if c == 2 && ds.class&fThreadLocal != 0 { 4751 if ds.class&(fStatic|fExtern) != 0 { 4752 return 4753 } 4754 } 4755 4756 ctx.errNode(n, "at most, one storage-class specifier may be given in the declaration specifiers in a declaration") 4757 } 4758 4759 // DeclarationSpecifiers Declarator DeclarationList CompoundStatement 4760 func (n *FunctionDefinition) checkDeclarator(ctx *context) { 4761 if n == nil { 4762 return 4763 } 4764 4765 n.Declarator.fnDef = true 4766 n.Declarator.funcDefinition = n 4767 ctx.checkFn = n 4768 typ, inline, noret := n.DeclarationSpecifiers.check(ctx, false) 4769 typ = n.Declarator.check(ctx, n.DeclarationSpecifiers, typ, true) 4770 typ.setFnSpecs(inline, noret) 4771 ctx.checkFn = nil 4772 n.DeclarationList.checkFn(ctx, typ, n.Declarator.ParamScope()) 4773 } 4774 4775 func (n *DeclarationList) checkFn(ctx *context, typ Type, s Scope) { 4776 if n == nil { 4777 return 4778 } 4779 4780 n.check(ctx) 4781 ft, ok := typ.(*functionType) 4782 if !ok { 4783 return 4784 } 4785 4786 if ft.params != nil { 4787 //TODO report error 4788 return 4789 } 4790 4791 if len(ft.paramList) == 0 { 4792 //TODO report error 4793 return 4794 } 4795 4796 m := make(map[StringID]int, len(ft.paramList)) 4797 for i, v := range ft.paramList { 4798 if _, ok := m[v]; ok { 4799 ctx.errNode(n, "duplicate parameter: %s", v) 4800 continue 4801 } 4802 4803 m[v] = i 4804 } 4805 params := make([]*Parameter, len(m)) 4806 i := 0 4807 for ; n != nil; n = n.DeclarationList { 4808 for n := n.Declaration.InitDeclaratorList; n != nil; n = n.InitDeclaratorList { 4809 n := n.InitDeclarator 4810 switch n.Case { 4811 case InitDeclaratorDecl: // Declarator AttributeSpecifierList 4812 nm := n.Declarator.Name() 4813 n.Declarator.IsParameter = true 4814 switch x, ok := m[nm]; { 4815 case ok: 4816 params[x] = &Parameter{d: n.Declarator, typ: n.Declarator.Type()} 4817 i++ 4818 default: 4819 //TODO report error 4820 } 4821 case InitDeclaratorInit: // Declarator AttributeSpecifierList '=' Initializer 4822 //TODO report error 4823 return 4824 default: 4825 panic(todo("")) 4826 } 4827 } 4828 } 4829 for i, v := range params { 4830 if v != nil { 4831 continue 4832 } 4833 4834 nm := ft.paramList[i] 4835 d := &Declarator{ 4836 DirectDeclarator: &DirectDeclarator{ 4837 Case: DirectDeclaratorIdent, 4838 Token: Token{Rune: IDENTIFIER, Value: nm}, 4839 }, 4840 IsParameter: true, 4841 Linkage: None, 4842 StorageClass: Automatic, 4843 typ: ctx.cfg.ABI.Type(Int), 4844 } 4845 s.declare(nm, d) 4846 params[i] = &Parameter{d, d.typ} 4847 } 4848 ft.params = params 4849 } 4850 4851 func (n *CompoundStatement) check(ctx *context) Operand { 4852 n.Operand = n.BlockItemList.check(ctx) 4853 return n.Operand 4854 } 4855 4856 func (n *BlockItemList) check(ctx *context) (r Operand) { 4857 r = noOperand 4858 var last *BlockItem 4859 for ; n != nil; n = n.BlockItemList { 4860 last = n.BlockItem 4861 r = n.BlockItem.check(ctx) 4862 } 4863 if last != nil { 4864 last.Last = true 4865 } 4866 return r 4867 } 4868 4869 func (n *BlockItem) check(ctx *context) Operand { 4870 if n == nil { 4871 return noOperand 4872 } 4873 4874 switch n.Case { 4875 case BlockItemDecl: // Declaration 4876 n.Declaration.check(ctx, false) 4877 case BlockItemStmt: // Statement 4878 return n.Statement.check(ctx) 4879 case BlockItemLabel: // LabelDeclaration 4880 n.LabelDeclaration.check(ctx) 4881 case BlockItemFuncDef: // DeclarationSpecifiers Declarator CompoundStatement 4882 ctxClosure := ctx.closure 4883 ctx.closure = nil 4884 ctxCheckFn := ctx.checkFn 4885 fn := &FunctionDefinition{ 4886 DeclarationSpecifiers: n.DeclarationSpecifiers, 4887 Declarator: n.Declarator, 4888 CompoundStatement: n.CompoundStatement, 4889 } 4890 n.fn = fn 4891 ctx.checkFn = fn 4892 n.CompoundStatement.scope.declare(idClosure, n) 4893 fn.checkDeclarator(ctx) 4894 ctxCapture := ctx.capture 4895 ctx.capture = true 4896 fn.checkBody(ctx) 4897 n.closure = ctx.closure 4898 ctx.capture = ctxCapture 4899 delete(n.CompoundStatement.scope, idClosure) 4900 ctx.checkFn = ctxCheckFn 4901 ctx.closure = ctxClosure 4902 case BlockItemPragma: // PragmaSTDC 4903 n.PragmaSTDC.check(ctx) 4904 default: 4905 panic(todo("")) 4906 } 4907 return noOperand 4908 } 4909 4910 func (n *LabelDeclaration) check(ctx *context) { 4911 if n == nil { 4912 return 4913 } 4914 4915 n.IdentifierList.check(ctx) 4916 } 4917 4918 func (n *Statement) check(ctx *context) Operand { 4919 if n == nil { 4920 return noOperand 4921 } 4922 4923 n.Operand = noOperand 4924 switch n.Case { 4925 case StatementLabeled: // LabeledStatement 4926 n.LabeledStatement.check(ctx) 4927 case StatementCompound: // CompoundStatement 4928 n.Operand = n.CompoundStatement.check(ctx) 4929 case StatementExpr: // ExpressionStatement 4930 n.Operand = n.ExpressionStatement.check(ctx) 4931 case StatementSelection: // SelectionStatement 4932 n.SelectionStatement.check(ctx) 4933 case StatementIteration: // IterationStatement 4934 n.IterationStatement.check(ctx) 4935 case StatementJump: // JumpStatement 4936 n.JumpStatement.check(ctx) 4937 case StatementAsm: // AsmStatement 4938 n.AsmStatement.check(ctx) 4939 default: 4940 panic(todo("")) 4941 } 4942 return n.Operand 4943 } 4944 4945 func (n *JumpStatement) check(ctx *context) { 4946 if n == nil { 4947 return 4948 } 4949 4950 switch n.Case { 4951 case JumpStatementGoto: // "goto" IDENTIFIER ';' 4952 n.context = ctx.breakCtx 4953 if ctx.checkFn.Gotos == nil { 4954 ctx.checkFn.Gotos = map[StringID]*JumpStatement{} 4955 } 4956 ctx.checkFn.Gotos[n.Token2.Value] = n 4957 case JumpStatementGotoExpr: // "goto" '*' Expression ';' 4958 n.Expression.check(ctx, false) 4959 //TODO 4960 case JumpStatementContinue: // "continue" ';' 4961 n.context = ctx.breakCtx 4962 if ctx.continues <= 0 { 4963 panic(n.Position().String()) 4964 } 4965 //TODO 4966 case JumpStatementBreak: // "break" ';' 4967 n.context = ctx.breakCtx 4968 if ctx.breaks <= 0 { 4969 panic(n.Position().String()) 4970 } 4971 //TODO 4972 case JumpStatementReturn: // "return" Expression ';' 4973 n.context = ctx.breakCtx 4974 op := n.Expression.check(ctx, false) 4975 if op.Type().IsComplexType() { 4976 ctx.checkFn.ReturnComplexExpr = append(ctx.checkFn.ReturnComplexExpr, n.Expression) 4977 } 4978 default: 4979 panic(todo("")) 4980 } 4981 } 4982 4983 func (n *IterationStatement) check(ctx *context) { 4984 if n == nil { 4985 return 4986 } 4987 4988 sv := ctx.breakCtx 4989 ctx.breakCtx = n 4990 4991 defer func() { ctx.breakCtx = sv }() 4992 4993 switch n.Case { 4994 case IterationStatementWhile: // "while" '(' Expression ')' Statement 4995 n.Expression.check(ctx, false) 4996 ctx.breaks++ 4997 ctx.continues++ 4998 n.Statement.check(ctx) 4999 ctx.breaks-- 5000 ctx.continues-- 5001 case IterationStatementDo: // "do" Statement "while" '(' Expression ')' ';' 5002 ctx.breaks++ 5003 ctx.continues++ 5004 n.Statement.check(ctx) 5005 ctx.breaks-- 5006 ctx.continues-- 5007 n.Expression.check(ctx, false) 5008 case IterationStatementFor: // "for" '(' Expression ';' Expression ';' Expression ')' Statement 5009 n.Expression.check(ctx, false) 5010 n.Expression2.check(ctx, false) 5011 n.Expression3.check(ctx, false) 5012 ctx.breaks++ 5013 ctx.continues++ 5014 n.Statement.check(ctx) 5015 ctx.breaks-- 5016 ctx.continues-- 5017 case IterationStatementForDecl: // "for" '(' Declaration Expression ';' Expression ')' Statement 5018 n.Declaration.check(ctx, false) 5019 n.Expression.check(ctx, false) 5020 n.Expression2.check(ctx, false) 5021 ctx.breaks++ 5022 ctx.continues++ 5023 n.Statement.check(ctx) 5024 ctx.breaks-- 5025 ctx.continues-- 5026 default: 5027 panic(todo("")) 5028 } 5029 } 5030 5031 func (n *SelectionStatement) check(ctx *context) { 5032 if n == nil { 5033 return 5034 } 5035 5036 switch n.Case { 5037 case SelectionStatementIf: // "if" '(' Expression ')' Statement 5038 n.Expression.check(ctx, false) 5039 n.Statement.check(ctx) 5040 case SelectionStatementIfElse: // "if" '(' Expression ')' Statement "else" Statement 5041 n.Expression.check(ctx, false) 5042 n.Statement.check(ctx) 5043 n.Statement2.check(ctx) 5044 if !n.Expression.Operand.Type().IsScalarType() { 5045 //TODO report err 5046 break 5047 } 5048 case SelectionStatementSwitch: // "switch" '(' Expression ')' Statement 5049 if n == nil { 5050 return 5051 } 5052 5053 sv := ctx.breakCtx 5054 ctx.breakCtx = n 5055 5056 defer func() { ctx.breakCtx = sv }() 5057 5058 op := n.Expression.check(ctx, false) 5059 n.promote = op.integerPromotion(ctx, n).Type() 5060 cp := ctx.casePromote 5061 ctx.casePromote = n.promote 5062 cs := ctx.cases 5063 ctx.cases = nil 5064 ctx.switches++ 5065 ctx.breaks++ 5066 n.Statement.check(ctx) 5067 ctx.breaks-- 5068 ctx.switches-- 5069 n.cases = ctx.cases 5070 ctx.cases = cs 5071 ctx.casePromote = cp 5072 default: 5073 panic(todo("")) 5074 } 5075 } 5076 5077 func (n *ExpressionStatement) check(ctx *context) Operand { 5078 if n == nil { 5079 return noOperand 5080 } 5081 5082 n.AttributeSpecifierList.check(ctx, nil) 5083 return n.Expression.check(ctx, false) 5084 } 5085 5086 func (n *LabeledStatement) check(ctx *context) { 5087 if n == nil { 5088 return 5089 } 5090 5091 switch n.Case { 5092 case LabeledStatementLabel: // IDENTIFIER ':' AttributeSpecifierList Statement 5093 if ctx.checkFn.Labels == nil { 5094 ctx.checkFn.Labels = map[StringID]*LabeledStatement{} 5095 } 5096 if _, ok := ctx.checkFn.Labels[n.Token.Value]; ok { 5097 //TODO report redeclared 5098 } 5099 ctx.checkFn.Labels[n.Token.Value] = n 5100 n.AttributeSpecifierList.check(ctx, nil) 5101 n.Statement.check(ctx) 5102 case LabeledStatementCaseLabel: // "case" ConstantExpression ':' Statement 5103 if ctx.switches <= 0 { 5104 //TODO report error 5105 break 5106 } 5107 5108 switch op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false); op.Value().(type) { 5109 case Int64Value, Uint64Value: 5110 if t := ctx.casePromote; t.Kind() != Invalid { 5111 n.ConstantExpression.Operand = op.convertTo(ctx, n, t) 5112 break 5113 } 5114 5115 //TODO report error 5116 default: 5117 //TODO report error 5118 } 5119 ctx.cases = append(ctx.cases, n) 5120 n.Statement.check(ctx) 5121 case LabeledStatementRange: // "case" ConstantExpression "..." ConstantExpression ':' Statement 5122 if ctx.switches <= 0 { 5123 //TODO report error 5124 break 5125 } 5126 5127 switch n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) { 5128 case Int64Value, Uint64Value: 5129 // ok 5130 default: 5131 //TODO report error 5132 } 5133 switch n.ConstantExpression2.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) { 5134 case Int64Value, Uint64Value: 5135 // ok 5136 default: 5137 //TODO report error 5138 } 5139 ctx.cases = append(ctx.cases, n) 5140 n.Statement.check(ctx) 5141 case LabeledStatementDefault: // "default" ':' Statement 5142 if ctx.switches <= 0 { 5143 //TODO report error 5144 break 5145 } 5146 5147 ctx.cases = append(ctx.cases, n) 5148 n.Statement.check(ctx) 5149 default: 5150 panic(todo("")) 5151 } 5152 } 5153 5154 func (n *DeclarationList) check(ctx *context) { 5155 for ; n != nil; n = n.DeclarationList { 5156 n.Declaration.check(ctx, false) 5157 } 5158 } 5159 5160 func setAddressTaken(n Node, d *Declarator, s string) { 5161 d.AddressTaken = true 5162 // fmt.Printf("%v: %s, type %v (%v, %v), declared at %v, AddressTaken = true: %v\n", 5163 // n.Position(), d.Name(), d.Type(), d.Type().Kind(), d.Type().Size(), d.Position(), s, 5164 // ) //TODO- 5165 } 5166 5167 // Dump returns a debug form of n. 5168 func (n *Initializer) Dump() string { 5169 var b strings.Builder 5170 f := strutil.IndentFormatter(&b, "\t") 5171 n.dump(f) 5172 return b.String() 5173 } 5174 5175 func pos(n Node) (r token.Position) { 5176 if n == nil { 5177 return r 5178 } 5179 5180 r = token.Position(n.Position()) 5181 if r.IsValid() { 5182 r.Filename = filepath.Base(r.Filename) 5183 } 5184 return r 5185 } 5186 5187 func (n *Initializer) dump(f strutil.Formatter) { 5188 list := n.List() 5189 if len(list) != 0 { 5190 for i, v := range list { 5191 f.Format("Initializer.List() #%d/%d: %v: off %v type %v", i, len(list), pos(v), v.Offset, v.Type()) 5192 if fld := v.FirstDesignatorField(); fld != nil { 5193 f.Format(" [FirstDesignatorField %q]", fld.Name()) 5194 } 5195 f.Format("\n") 5196 } 5197 } 5198 if f0 := n.FirstDesignatorField(); f0 != nil { 5199 f.Format("[FirstDesignatorField: %q, index %v, off %v, type %v] ", f0.Name(), f0.Index(), n.Offset, n.Type().Alias()) 5200 } 5201 switch n.Case { 5202 case InitializerExpr: // AssignmentExpression 5203 if op := n.AssignmentExpression.Operand; op != nil { 5204 n.isConst = op.IsConst() 5205 n.isZero = op.IsZero() 5206 } 5207 var t Type 5208 if n.AssignmentExpression != nil && n.AssignmentExpression.Operand != nil { 5209 t = n.AssignmentExpression.Operand.Type() 5210 } 5211 f.Format("%v: %T@%[2]p, .Case %v, off %v, type %v\n", pos(n), n, n.Case, n.Offset, t.Alias()) 5212 case InitializerInitList: // '{' InitializerList ',' '}' 5213 n.InitializerList.dump(f) 5214 default: 5215 panic(todo("%v:", n.Position())) 5216 } 5217 } 5218 5219 // Dump returns a debug form of n. 5220 func (n *InitializerList) Dump() string { 5221 var b strings.Builder 5222 f := strutil.IndentFormatter(&b, "\t") 5223 n.dump(f) 5224 return b.String() 5225 } 5226 5227 func (n *InitializerList) dump(f strutil.Formatter) { 5228 if n == nil { 5229 f.Format("<nil>") 5230 return 5231 } 5232 5233 f.Format("%v: %T@%[2]p, len(.List()) %v {%i\n", pos(n), n, len(n.List())) 5234 list := n.List() 5235 for ; n != nil; n = n.InitializerList { 5236 n.Designation.dump(f) 5237 n.Initializer.dump(f) 5238 } 5239 for i, v := range list { 5240 f.Format("InitializerList.List() #%d/%d:", i, len(list)) 5241 v.dump(f) 5242 } 5243 f.Format("%u}\n") 5244 } 5245 5246 func (n *Designation) dump(f strutil.Formatter) { 5247 if n == nil { 5248 return 5249 } 5250 5251 cnt := 0 5252 designatorField2 := false 5253 for n := n.DesignatorList; n != nil; n = n.DesignatorList { 5254 n.Designator.dump(f) 5255 if n.Designator.Case == DesignatorField2 { 5256 designatorField2 = true 5257 } 5258 cnt++ 5259 } 5260 if cnt > 1 || !designatorField2 { 5261 f.Format(" = ") 5262 } 5263 } 5264 5265 func (n *Designator) dump(f strutil.Formatter) { 5266 switch n.Case { 5267 case DesignatorIndex: // '[' ConstantExpression ']' 5268 f.Format("[%v]", n.ConstantExpression.Operand.Value()) 5269 case DesignatorField: // '.' IDENTIFIER 5270 f.Format(".%s", n.Token2.Value) 5271 case DesignatorField2: // IDENTIFIER ':' 5272 f.Format("%s:", n.Token.Value) 5273 default: 5274 panic(todo("")) 5275 } 5276 }