gitlab.com/cznic/ccir@v1.0.0/ccir.go (about)

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