gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }