modernc.org/cc@v1.0.1/v2/type.go (about)

     1  // Copyright 2017 The CC Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cc // import "modernc.org/cc/v2"
     6  
     7  // [0]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"go/token"
    13  
    14  	"modernc.org/ir"
    15  )
    16  
    17  var (
    18  	_ Type = (*ArrayType)(nil)
    19  	_ Type = (*EnumType)(nil)
    20  	_ Type = (*FunctionType)(nil)
    21  	_ Type = (*NamedType)(nil)
    22  	_ Type = (*PointerType)(nil)
    23  	_ Type = (*StructType)(nil)
    24  	_ Type = (*TaggedStructType)(nil)
    25  	_ Type = (*TaggedUnionType)(nil)
    26  	_ Type = (*TaggedEnumType)(nil)
    27  	_ Type = (*UnionType)(nil)
    28  	_ Type = TypeKind(0)
    29  
    30  	_ fieldFinder = (*StructType)(nil)
    31  	_ fieldFinder = (*UnionType)(nil)
    32  )
    33  
    34  type fieldFinder interface {
    35  	findField(int) *FieldProperties
    36  }
    37  
    38  // Type represents a C type.
    39  type Type interface {
    40  	Node
    41  	Equal(Type) bool
    42  	IsArithmeticType() bool
    43  	IsCompatible(Type) bool // [0]6.2.7
    44  	IsIntegerType() bool
    45  	IsPointerType() bool
    46  	IsScalarType() bool
    47  	IsUnsigned() bool
    48  	IsVoidPointerType() bool
    49  	Kind() TypeKind
    50  	String() string
    51  	assign(ctx *context, n Node, op Operand) Operand
    52  }
    53  
    54  // TypeKind represents a particular type kind.
    55  type TypeKind int
    56  
    57  func (t TypeKind) Pos() token.Pos { return token.Pos(0) }
    58  
    59  // TypeKind values.
    60  const (
    61  	_ TypeKind = iota
    62  
    63  	Bool
    64  	Char
    65  	Int
    66  	Long
    67  	LongLong
    68  	SChar
    69  	Short
    70  	UChar
    71  	UInt
    72  	ULong
    73  	ULongLong
    74  	UShort
    75  
    76  	Float
    77  	Double
    78  	LongDouble
    79  
    80  	FloatComplex
    81  	DoubleComplex
    82  	LongDoubleComplex
    83  
    84  	FloatImaginary
    85  	DoubleImaginary
    86  	LongDoubleImaginary
    87  
    88  	Array
    89  	Enum
    90  	EnumTag
    91  	Function
    92  	Ptr
    93  	Struct
    94  	StructTag
    95  	TypedefName
    96  	Union
    97  	UnionTag
    98  	Void
    99  
   100  	maxTypeKind
   101  )
   102  
   103  // IsUnsigned implements Type.
   104  func (t TypeKind) IsUnsigned() bool { return t.IsIntegerType() && !isSigned[t] }
   105  
   106  // Kind implements Type.
   107  func (t TypeKind) Kind() TypeKind { return t }
   108  
   109  // assign implements Type.
   110  func (t TypeKind) assign(ctx *context, n Node, op Operand) Operand {
   111  	// [0]6.5.16.1
   112  	switch {
   113  	// One of the following shall hold:
   114  	case
   115  		// the left operand has qualified or unqualified arithmetic
   116  		// type and the right has arithmetic type;
   117  		t.IsArithmeticType() && op.Type.IsArithmeticType():
   118  		return op.ConvertTo(ctx.model, t)
   119  	default:
   120  		panic(fmt.Sprintf("%v: %v <- %v", ctx.position(n), t, op))
   121  	}
   122  }
   123  
   124  // IsPointerType implements Type.
   125  func (t TypeKind) IsPointerType() bool {
   126  	if t.IsArithmeticType() {
   127  		return false
   128  	}
   129  
   130  	switch t {
   131  	case Void:
   132  		return false
   133  	default:
   134  		panic(t)
   135  	}
   136  }
   137  
   138  // IsIntegerType implements Type.
   139  func (t TypeKind) IsIntegerType() bool {
   140  	switch t {
   141  	case
   142  		Bool,
   143  		Char,
   144  		DoubleImaginary,
   145  		FloatImaginary,
   146  		Int,
   147  		Long,
   148  		LongDoubleImaginary,
   149  		LongLong,
   150  		SChar,
   151  		Short,
   152  		UChar,
   153  		UInt,
   154  		ULong,
   155  		ULongLong,
   156  		UShort:
   157  
   158  		return true
   159  	case
   160  		Double,
   161  		DoubleComplex,
   162  		Float,
   163  		FloatComplex,
   164  		LongDouble,
   165  		LongDoubleComplex,
   166  		Void:
   167  
   168  		return false
   169  	default:
   170  		panic(t)
   171  	}
   172  }
   173  
   174  // IsScalarType implements Type.
   175  func (t TypeKind) IsScalarType() bool {
   176  	switch t {
   177  	case
   178  		Char,
   179  		Double,
   180  		DoubleComplex,
   181  		Float,
   182  		FloatComplex,
   183  		Int,
   184  		Long,
   185  		LongDouble,
   186  		LongDoubleComplex,
   187  		LongLong,
   188  		SChar,
   189  		Short,
   190  		UChar,
   191  		UInt,
   192  		ULong,
   193  		ULongLong,
   194  		UShort:
   195  
   196  		return true
   197  	case
   198  		Bool,
   199  		Void:
   200  
   201  		return false
   202  	default:
   203  		panic(t)
   204  	}
   205  }
   206  
   207  // IsVoidPointerType implements Type.
   208  func (t TypeKind) IsVoidPointerType() bool {
   209  	if t != Ptr {
   210  		return false
   211  	}
   212  
   213  	panic(t)
   214  }
   215  
   216  // IsArithmeticType implements Type.
   217  func (t TypeKind) IsArithmeticType() bool { return isArithmeticType[t] }
   218  
   219  // IsCompatible implements Type.
   220  func (t TypeKind) IsCompatible(u Type) bool {
   221  	for {
   222  		switch x := u.(type) {
   223  		case *PointerType:
   224  			switch t {
   225  			case
   226  				Char,
   227  				Int:
   228  
   229  				return false
   230  			default:
   231  				panic(fmt.Errorf("%v %v", t, x))
   232  			}
   233  		case *NamedType:
   234  			u = x.Type
   235  		case *EnumType:
   236  			u = x.Enums[0].Operand.Type
   237  		case TypeKind:
   238  			if t.IsIntegerType() && u.IsIntegerType() {
   239  				return intConvRank[t] == intConvRank[x] && isSigned[t] == isSigned[x]
   240  			}
   241  
   242  			switch x {
   243  			case
   244  				Double,
   245  				DoubleComplex,
   246  				Float,
   247  				FloatComplex,
   248  				LongDouble,
   249  				LongDoubleComplex:
   250  
   251  				return t == x
   252  			case Void:
   253  				return t == x
   254  			default:
   255  				panic(fmt.Errorf("%v", x))
   256  			}
   257  		default:
   258  			panic(fmt.Errorf("%v %T", t, x))
   259  		}
   260  	}
   261  }
   262  
   263  // Equal implements Type.
   264  func (t TypeKind) Equal(u Type) bool {
   265  	switch x := u.(type) {
   266  	case
   267  		*ArrayType,
   268  		*EnumType,
   269  		*FunctionType,
   270  		*PointerType,
   271  		*StructType,
   272  		*TaggedEnumType,
   273  		*TaggedStructType,
   274  		*TaggedUnionType,
   275  		*UnionType:
   276  
   277  		if t.IsScalarType() || t == Void {
   278  			return false
   279  		}
   280  
   281  		panic(t)
   282  	case *NamedType:
   283  		return t.Equal(x.Type)
   284  	case TypeKind:
   285  		switch x {
   286  		case
   287  			Bool,
   288  			Char,
   289  			Double,
   290  			DoubleComplex,
   291  			DoubleImaginary,
   292  			Float,
   293  			FloatComplex,
   294  			FloatImaginary,
   295  			Int,
   296  			Long,
   297  			LongDouble,
   298  			LongDoubleComplex,
   299  			LongDoubleImaginary,
   300  			LongLong,
   301  			SChar,
   302  			Short,
   303  			UChar,
   304  			UInt,
   305  			ULong,
   306  			ULongLong,
   307  			UShort,
   308  			Void:
   309  
   310  			return t == x
   311  		default:
   312  			panic(x)
   313  		}
   314  	default:
   315  		panic(fmt.Errorf("%T", x))
   316  	}
   317  }
   318  
   319  func (t TypeKind) String() string {
   320  	switch t {
   321  	case Bool:
   322  		return "bool"
   323  	case Char:
   324  		return "char"
   325  	case Int:
   326  		return "int"
   327  	case Long:
   328  		return "long"
   329  	case LongLong:
   330  		return "long long"
   331  	case SChar:
   332  		return "signed char"
   333  	case Short:
   334  		return "short"
   335  	case UChar:
   336  		return "unsigned char"
   337  	case UInt:
   338  		return "unsigned"
   339  	case ULong:
   340  		return "unsigned long"
   341  	case ULongLong:
   342  		return "unsigned long long"
   343  	case UShort:
   344  		return "unsigned short"
   345  	case Float:
   346  		return "float"
   347  	case Double:
   348  		return "double"
   349  	case LongDouble:
   350  		return "long double"
   351  	case FloatImaginary:
   352  		return "float imaginary"
   353  	case DoubleImaginary:
   354  		return "double imaginary"
   355  	case LongDoubleImaginary:
   356  		return "long double imaginary"
   357  	case FloatComplex:
   358  		return "float complex"
   359  	case DoubleComplex:
   360  		return "double complex"
   361  	case LongDoubleComplex:
   362  		return "long double complex"
   363  	case Array:
   364  		return "array"
   365  	case Enum:
   366  		return "enum"
   367  	case EnumTag:
   368  		return "enum tag"
   369  	case Function:
   370  		return "function"
   371  	case Ptr:
   372  		return "ptr"
   373  	case Struct:
   374  		return "struct"
   375  	case StructTag:
   376  		return "struct tag"
   377  	case TypedefName:
   378  		return "typedef name"
   379  	case Union:
   380  		return "union"
   381  	case Void:
   382  		return "void"
   383  	default:
   384  		return fmt.Sprintf("TypeKind(%v)", int(t))
   385  	}
   386  }
   387  
   388  // ArrayType type represents an array type.
   389  type ArrayType struct {
   390  	Item           Type
   391  	Length         *Expr
   392  	Size           Operand
   393  	TypeQualifiers []*TypeQualifier // Eg. double a[restrict 3][5], see 6.7.5.3-21.
   394  	pos            token.Pos
   395  }
   396  
   397  func (t *ArrayType) Pos() token.Pos { return t.pos }
   398  
   399  func (t *ArrayType) IsVLA() bool { return t.Length != nil && t.Length.Operand.Value == nil }
   400  
   401  // IsUnsigned implements Type.
   402  func (t *ArrayType) IsUnsigned() bool { panic("TODO") }
   403  
   404  // IsVoidPointerType implements Type.
   405  func (t *ArrayType) IsVoidPointerType() bool { panic("TODO") }
   406  
   407  // IsArithmeticType implements Type.
   408  func (t *ArrayType) IsArithmeticType() bool { return false }
   409  
   410  // IsCompatible implements Type.
   411  func (t *ArrayType) IsCompatible(u Type) bool {
   412  	// [0]6.7.5.2
   413  	//
   414  	// 6. For two array types to be compatible, both shall have compatible
   415  	// element types, and if both size specifiers are present, and are
   416  	// integer constant expressions, then both size specifiers shall have
   417  	// the same constant value. If the two array types are used in a
   418  	// context which requires them to be compatible, it is undefined
   419  	// behavior if the two size specifiers evaluate to unequal values.
   420  	switch x := u.(type) {
   421  	case *ArrayType:
   422  		if !t.Item.IsCompatible(x.Item) {
   423  			return false
   424  		}
   425  
   426  		if t.Size.Type != nil && x.Size.Type != nil {
   427  			return t.Size.Value.(*ir.Int64Value).Value == x.Size.Value.(*ir.Int64Value).Value
   428  		}
   429  
   430  		return true
   431  	case *NamedType:
   432  		return x.IsCompatible(t)
   433  	case *PointerType:
   434  		return t.Size.Type == nil && t.Item.IsCompatible(x.Item)
   435  	case TypeKind:
   436  		if x.IsArithmeticType() {
   437  			return false
   438  		}
   439  
   440  		panic(fmt.Errorf("%T\n%v\n%v", x, t, u))
   441  	default:
   442  		panic(fmt.Errorf("%T\n%v\n%v", x, t, u))
   443  	}
   444  }
   445  
   446  // Equal implements Type.
   447  func (t *ArrayType) Equal(u Type) bool {
   448  	if t == u {
   449  		return true
   450  	}
   451  
   452  	switch x := u.(type) {
   453  	case *ArrayType:
   454  		if !t.Item.Equal(x.Item) {
   455  			return false
   456  		}
   457  
   458  		switch {
   459  		case t.Size.Type != nil && x.Size.Type != nil:
   460  			return x.Size.Type != nil && t.Size.Value.(*ir.Int64Value).Value == x.Size.Value.(*ir.Int64Value).Value
   461  		case t.Size.Type == nil && x.Size.Type == nil:
   462  			return true
   463  		default:
   464  			panic(fmt.Errorf("%v, %v", t, u))
   465  		}
   466  	case *NamedType:
   467  		return x.Type.Equal(t)
   468  	case
   469  		*FunctionType,
   470  		*PointerType,
   471  		*StructType,
   472  		*TaggedStructType:
   473  
   474  		return false
   475  	case TypeKind:
   476  		if x.IsScalarType() || x == Void {
   477  			return false
   478  		}
   479  
   480  		panic(x)
   481  	default:
   482  		panic(fmt.Errorf("%T %v", x, x))
   483  	}
   484  }
   485  
   486  // Kind implements Type.
   487  func (t *ArrayType) Kind() TypeKind { return Array }
   488  
   489  // assign implements Type.
   490  func (t *ArrayType) assign(ctx *context, n Node, op Operand) Operand {
   491  	switch {
   492  	case t.Size.Value == nil:
   493  		return (&PointerType{Item: t.Item}).assign(ctx, n, op)
   494  	default:
   495  		panic("TODO")
   496  	}
   497  }
   498  
   499  // IsPointerType implements Type.
   500  func (t *ArrayType) IsPointerType() bool { return false }
   501  
   502  // IsIntegerType implements Type.
   503  func (t *ArrayType) IsIntegerType() bool { return false }
   504  
   505  // IsScalarType implements Type.
   506  func (t *ArrayType) IsScalarType() bool { return false }
   507  
   508  func (t *ArrayType) String() string {
   509  	switch {
   510  	case t.Size.Type != nil && t.Size.Value != nil:
   511  		return fmt.Sprintf("array of %v %v", t.Size.Value, t.Item)
   512  	default:
   513  		return fmt.Sprintf("array of %v", t.Item)
   514  	}
   515  }
   516  
   517  // EnumType represents an enum type.
   518  type EnumType struct {
   519  	Tag   int
   520  	Enums []*EnumerationConstant
   521  	Min   int64
   522  	Max   uint64
   523  	pos   token.Pos
   524  }
   525  
   526  func (t *EnumType) Pos() token.Pos { return t.pos }
   527  
   528  func (t *EnumType) find(nm int) *EnumerationConstant {
   529  	for _, v := range t.Enums {
   530  		if v.Token.Val == nm {
   531  			return v
   532  		}
   533  	}
   534  	return nil
   535  }
   536  
   537  // IsUnsigned implements Type.
   538  func (t *EnumType) IsUnsigned() bool { return t.Enums[0].Operand.Type.IsUnsigned() }
   539  
   540  // IsVoidPointerType implements Type.
   541  func (t *EnumType) IsVoidPointerType() bool { panic("TODO") }
   542  
   543  // IsArithmeticType implements Type.
   544  func (t *EnumType) IsArithmeticType() bool { return true }
   545  
   546  // IsCompatible implements Type.
   547  func (t *EnumType) IsCompatible(u Type) bool {
   548  	switch x := underlyingType(u, true).(type) {
   549  	case *EnumType:
   550  		if len(t.Enums) != len(x.Enums) {
   551  			return false
   552  		}
   553  
   554  		for i, v := range t.Enums {
   555  			if !v.equal(x.Enums[i]) {
   556  				return false
   557  			}
   558  		}
   559  
   560  		return true
   561  	default:
   562  		return false
   563  	}
   564  }
   565  
   566  // Equal implements Type.
   567  func (t *EnumType) Equal(u Type) bool {
   568  	if t == u {
   569  		return true
   570  	}
   571  
   572  	switch x := UnderlyingType(u).(type) {
   573  	case *EnumType:
   574  		if t.Tag != x.Tag || len(t.Enums) != len(x.Enums) {
   575  			return false
   576  		}
   577  
   578  		for i, v := range t.Enums {
   579  			w := x.Enums[i]
   580  			if !v.Operand.Type.Equal(w.Operand.Type) || v.Operand.Value.(*ir.Int64Value).Value != w.Operand.Value.(*ir.Int64Value).Value {
   581  				return false
   582  			}
   583  		}
   584  
   585  		return true
   586  	case TypeKind:
   587  		if x.IsScalarType() {
   588  			return false
   589  		}
   590  
   591  		panic(fmt.Errorf("%v %T %v", t, x, x))
   592  	default:
   593  		panic(fmt.Errorf("%v %T %v", t, x, x))
   594  	}
   595  }
   596  
   597  // Kind implements Type.
   598  func (t *EnumType) Kind() TypeKind { return Enum }
   599  
   600  // assign implements Type.
   601  func (t *EnumType) assign(ctx *context, n Node, op Operand) Operand {
   602  	return op.ConvertTo(ctx.model, t)
   603  }
   604  
   605  // IsPointerType implements Type.
   606  func (t *EnumType) IsPointerType() bool { return false }
   607  
   608  // IsIntegerType implements Type.
   609  func (t *EnumType) IsIntegerType() bool { return true }
   610  
   611  // IsScalarType implements Type.
   612  func (t *EnumType) IsScalarType() bool { return true }
   613  
   614  func (t *EnumType) String() string {
   615  	return fmt.Sprintf("%s enumeration %s", t.Enums[0].Operand.Type.String(), dict.S(t.Tag))
   616  }
   617  
   618  // Field represents a struct/union field.
   619  type Field struct {
   620  	Bits       int
   621  	Declarator *Declarator
   622  	Name       int
   623  	PackedType Type // Bits != 0: underlaying struct field type
   624  	Type       Type
   625  
   626  	Anonymous       bool
   627  	IsFlexibleArray bool
   628  }
   629  
   630  func (f Field) equal(g Field) bool {
   631  	return f.Name == g.Name && f.Type.Equal(g.Type) && f.Bits == g.Bits
   632  }
   633  
   634  func (f Field) isCompatiblel(g Field) bool {
   635  	return f.Name == g.Name && f.Type.IsCompatible(g.Type) && f.Bits == g.Bits
   636  }
   637  
   638  func (f Field) String() string { return fmt.Sprintf("%s %v", dict.S(f.Name), f.Type) }
   639  
   640  // FunctionType represents a function type.
   641  type FunctionType struct {
   642  	Params   []Type
   643  	Result   Type
   644  	Variadic bool
   645  	params   []int
   646  	pos      token.Pos
   647  }
   648  
   649  func (t *FunctionType) Pos() token.Pos { return t.pos }
   650  
   651  // IsUnsigned implements Type.
   652  func (t *FunctionType) IsUnsigned() bool { panic("TODO") }
   653  
   654  // IsVoidPointerType implements Type.
   655  func (t *FunctionType) IsVoidPointerType() bool { panic("TODO") }
   656  
   657  // IsArithmeticType implements Type.
   658  func (t *FunctionType) IsArithmeticType() bool { return false }
   659  
   660  // IsCompatible implements Type.
   661  func (t *FunctionType) IsCompatible(u Type) bool {
   662  	switch x := u.(type) {
   663  	case *FunctionType:
   664  		if t.Variadic != x.Variadic || !t.Result.IsCompatible(x.Result) {
   665  			return false
   666  		}
   667  
   668  		if len(t.Params) != len(x.Params) {
   669  			switch {
   670  			case len(t.Params) == 1 && len(x.Params) == 0 && t.Params[0].Kind() == Void:
   671  				return true
   672  			case len(t.Params) == 0 && len(x.Params) == 1 && x.Params[0].Kind() == Void:
   673  				return true
   674  			}
   675  			return false
   676  		}
   677  
   678  		for i, t := range t.Params {
   679  			if !t.IsCompatible(x.Params[i]) {
   680  				return false
   681  			}
   682  		}
   683  		return true
   684  	case *NamedType:
   685  		return x.Type.IsCompatible(t)
   686  	case *PointerType:
   687  		return x.Item.IsCompatible(t)
   688  	default:
   689  		panic(fmt.Errorf("%T", x))
   690  	}
   691  }
   692  
   693  // Equal implements Type.
   694  func (t *FunctionType) Equal(u Type) bool {
   695  	if t == u {
   696  		return true
   697  	}
   698  
   699  	switch x := u.(type) {
   700  	case *FunctionType:
   701  		if len(t.Params) != len(x.Params) || t.Variadic != x.Variadic || !t.Result.Equal(x.Result) {
   702  			return false
   703  		}
   704  
   705  		for i, t := range t.Params {
   706  			if !t.Equal(x.Params[i]) {
   707  				return false
   708  			}
   709  		}
   710  		return true
   711  	case
   712  		*NamedType,
   713  		*PointerType,
   714  		*StructType,
   715  		*TaggedStructType:
   716  
   717  		return false
   718  	case TypeKind:
   719  		switch x {
   720  		case
   721  			Char,
   722  			Int,
   723  			Void:
   724  
   725  			return false
   726  		default:
   727  			panic(x)
   728  		}
   729  	default:
   730  		panic(fmt.Errorf("%T", x))
   731  	}
   732  }
   733  
   734  // Kind implements Type.
   735  func (t *FunctionType) Kind() TypeKind { return Function }
   736  
   737  // assign implements Type.
   738  func (t *FunctionType) assign(ctx *context, n Node, op Operand) Operand {
   739  	switch x := UnderlyingType(op.Type).(type) {
   740  	case *PointerType:
   741  		switch y := UnderlyingType(x.Item).(type) {
   742  		case *FunctionType:
   743  			if !t.Equal(y) {
   744  				panic(fmt.Errorf("%v: %v != %v", ctx.position(n), t, y))
   745  			}
   746  
   747  			return op
   748  		default:
   749  			panic(fmt.Errorf("%v: %T", ctx.position(n), y))
   750  		}
   751  	default:
   752  		panic(fmt.Errorf("%v: %T", ctx.position(n), x))
   753  	}
   754  }
   755  
   756  // IsPointerType implements Type.
   757  func (t *FunctionType) IsPointerType() bool { return false }
   758  
   759  // IsIntegerType implements Type.
   760  func (t *FunctionType) IsIntegerType() bool { return false }
   761  
   762  // IsScalarType implements Type.
   763  func (t *FunctionType) IsScalarType() bool { return false }
   764  
   765  func (t *FunctionType) String() string {
   766  	var buf bytes.Buffer
   767  	buf.WriteString("function (")
   768  	switch {
   769  	case len(t.Params) == 1 && t.Params[0].Kind() == Void:
   770  		// nop
   771  	default:
   772  		for i, v := range t.Params {
   773  			if i != 0 {
   774  				buf.WriteString(", ")
   775  			}
   776  			buf.WriteString(v.String())
   777  		}
   778  	}
   779  	fmt.Fprintf(&buf, ") returning %v", t.Result)
   780  	return buf.String()
   781  }
   782  
   783  // NamedType represents a type described by a typedef name.
   784  type NamedType struct {
   785  	Name int
   786  	Type Type // The type Name refers to.
   787  	pos  token.Pos
   788  }
   789  
   790  func (t *NamedType) Pos() token.Pos { return t.pos }
   791  
   792  // IsUnsigned implements Type.
   793  func (t *NamedType) IsUnsigned() bool { return t.Type.IsUnsigned() }
   794  
   795  // IsVoidPointerType implements Type.
   796  func (t *NamedType) IsVoidPointerType() bool { panic("TODO") }
   797  
   798  // IsArithmeticType implements Type.
   799  func (t *NamedType) IsArithmeticType() bool { return t.Type.IsArithmeticType() }
   800  
   801  // IsCompatible implements Type.
   802  func (t *NamedType) IsCompatible(u Type) (r bool) {
   803  	return UnderlyingType(t.Type).IsCompatible(UnderlyingType(u))
   804  }
   805  
   806  // Equal implements Type.
   807  func (t *NamedType) Equal(u Type) bool {
   808  	if t == u {
   809  		return true
   810  	}
   811  
   812  	switch x := u.(type) {
   813  	case *ArrayType:
   814  		return x.Equal(t.Type)
   815  	case *EnumType:
   816  		return x.Equal(t.Type)
   817  	case *NamedType:
   818  		return t.Name == x.Name && t.Type.Equal(x.Type)
   819  	case
   820  		*FunctionType,
   821  		*PointerType:
   822  
   823  		return x.Equal(t.Type)
   824  	case *StructType:
   825  		return t.Type.Equal(x)
   826  	case *TaggedEnumType:
   827  		v := x.getType()
   828  		return v != x && t.Type.Equal(v)
   829  	case *TaggedStructType:
   830  		v := x.getType()
   831  		return v != x && t.Type.Equal(v)
   832  	case *TaggedUnionType:
   833  		v := x.getType()
   834  		return v != x && t.Type.Equal(v)
   835  	case TypeKind:
   836  		switch x {
   837  		case
   838  			Bool,
   839  			Char,
   840  			Double,
   841  			Float,
   842  			Int,
   843  			Long,
   844  			LongDouble,
   845  			LongLong,
   846  			SChar,
   847  			Short,
   848  			UChar,
   849  			UInt,
   850  			ULong,
   851  			ULongLong,
   852  			UShort,
   853  			Void:
   854  
   855  			return x.Equal(t.Type)
   856  		default:
   857  			panic(x)
   858  		}
   859  	case *UnionType:
   860  		return t.Type.Equal(x)
   861  	default:
   862  		panic(fmt.Errorf("%T: %v, %v", x, t.Type, u))
   863  	}
   864  }
   865  
   866  // Kind implements Type.
   867  func (t *NamedType) Kind() TypeKind { return t.Type.Kind() }
   868  
   869  // assign implements Type.
   870  func (t *NamedType) assign(ctx *context, n Node, op Operand) Operand { return t.Type.assign(ctx, n, op) }
   871  
   872  // IsPointerType implements Type.
   873  func (t *NamedType) IsPointerType() bool { return t.Type.IsPointerType() }
   874  
   875  // IsIntegerType implements Type.
   876  func (t *NamedType) IsIntegerType() bool { return t.Type.IsIntegerType() }
   877  
   878  // IsScalarType implements Type.
   879  func (t *NamedType) IsScalarType() bool { return t.Type.IsScalarType() }
   880  
   881  func (t *NamedType) String() string { return string(dict.S(t.Name)) }
   882  
   883  // PointerType represents a pointer type.
   884  type PointerType struct {
   885  	Item Type
   886  	pos  token.Pos
   887  }
   888  
   889  func (t *PointerType) Pos() token.Pos { return t.pos }
   890  
   891  // IsUnsigned implements Type.
   892  func (t *PointerType) IsUnsigned() bool { return true }
   893  
   894  // IsVoidPointerType implements Type.
   895  func (t *PointerType) IsVoidPointerType() bool { return UnderlyingType(t.Item) == Void }
   896  
   897  // IsArithmeticType implements Type.
   898  func (t *PointerType) IsArithmeticType() bool { return false }
   899  
   900  // IsCompatible implements Type.
   901  func (t *PointerType) IsCompatible(u Type) bool {
   902  	if t.Equal(u) {
   903  		return true
   904  	}
   905  
   906  	var ai Type
   907  	switch x := UnderlyingType(t.Item).(type) {
   908  	case *ArrayType:
   909  		ai = x.Item
   910  	}
   911  
   912  	switch x := UnderlyingType(u).(type) {
   913  	case *ArrayType:
   914  		return t.Item.IsCompatible(x.Item)
   915  	case *NamedType:
   916  		return t.IsCompatible(x.Type)
   917  	case *FunctionType:
   918  		return x.IsCompatible(t)
   919  	case *PointerType:
   920  		// [0]6.3.2.3
   921  		//
   922  		// 1. A pointer to void may be converted to or from a pointer to any
   923  		// incomplete or object type. A pointer to any incomplete or object
   924  		// type may be converted to a pointer to void and back again; the
   925  		// result shall compare equal to the original pointer.
   926  		return t.Item == Void || x.Item == Void ||
   927  			ai != nil && ai.IsCompatible(x.Item) ||
   928  			underlyingType(t.Item, true).IsCompatible(underlyingType(x.Item, true)) ||
   929  			Unsigned(t.Item) == Unsigned(x.Item)
   930  	case *StructType:
   931  		return false
   932  	case TypeKind:
   933  		if u.IsArithmeticType() {
   934  			return false
   935  		}
   936  
   937  		panic(fmt.Errorf("%T\n%v\n%v", x, t, u))
   938  	default:
   939  		panic(fmt.Errorf("%T\n%v\n%v", x, t, u))
   940  	}
   941  }
   942  
   943  func Unsigned(t Type) TypeKind {
   944  	switch k := underlyingType(t, false).Kind(); k {
   945  	case Char, SChar:
   946  		return UChar
   947  	case Short:
   948  		return UShort
   949  	case Int:
   950  		return UInt
   951  	case Long:
   952  		return ULong
   953  	case LongLong:
   954  		return ULongLong
   955  	default:
   956  		return k
   957  	}
   958  }
   959  
   960  // Equal implements Type.
   961  func (t *PointerType) Equal(u Type) bool {
   962  	if t == u {
   963  		return true
   964  	}
   965  
   966  	switch x := u.(type) {
   967  	case
   968  		*ArrayType,
   969  		*FunctionType,
   970  		*StructType,
   971  		*TaggedStructType,
   972  		*UnionType:
   973  
   974  		return false
   975  	case *NamedType:
   976  		return t.Equal(x.Type)
   977  	case *PointerType:
   978  		return t.Item.Equal(x.Item)
   979  	case TypeKind:
   980  		switch x {
   981  		case
   982  			Char,
   983  			Double,
   984  			Float,
   985  			Int,
   986  			Long,
   987  			LongLong,
   988  			Short,
   989  			UChar,
   990  			UInt,
   991  			ULong,
   992  			ULongLong,
   993  			UShort,
   994  			Void:
   995  
   996  			return false
   997  		default:
   998  			panic(x)
   999  		}
  1000  	default:
  1001  		panic(fmt.Errorf("%T", x))
  1002  	}
  1003  }
  1004  
  1005  // Kind implements Type.
  1006  func (t *PointerType) Kind() TypeKind { return Ptr }
  1007  
  1008  // assign implements Type.
  1009  func (t *PointerType) assign(ctx *context, n Node, op Operand) (r Operand) {
  1010  	u := UnderlyingType(t.Item)
  1011  	var v Type
  1012  	if op.Type.IsPointerType() {
  1013  		v = UnderlyingType(UnderlyingType(op.Type).(*PointerType).Item)
  1014  	}
  1015  	// [0]6.5.16.1
  1016  	switch {
  1017  	// One of the following shall hold:
  1018  	case ctx.tweaks.EnablePointerCompatibility && op.Type.IsPointerType():
  1019  		return op.ConvertTo(ctx.model, t)
  1020  	case
  1021  		// both operands are pointers to qualified or unqualified
  1022  		// versions of compatible types, and the type pointed to by the
  1023  		// left has all the qualifiers of the type pointed to by the
  1024  		// right;
  1025  		op.Type.IsPointerType() && t.IsCompatible(op.Type),
  1026  		u.IsIntegerType() && v != nil && v.IsIntegerType() && ctx.model.Sizeof(u) == ctx.model.Sizeof(v) && u.IsUnsigned() == v.IsUnsigned():
  1027  
  1028  		return op.ConvertTo(ctx.model, t)
  1029  	case
  1030  		// one operand is a pointer to an object or incomplete type and
  1031  		// the other is a pointer to a qualified or unqualified version
  1032  		// of void, and the type pointed to by the left has all the
  1033  		// qualifiers of the type pointed to by the right;
  1034  		t.IsPointerType() && op.Type.IsVoidPointerType():
  1035  
  1036  		panic("TODO")
  1037  	case
  1038  		// the left operand is a pointer and the right is a null
  1039  		// pointer constant;
  1040  		op.isNullPtrConst():
  1041  
  1042  		return Operand{Type: t, Value: Null}
  1043  	default:
  1044  		panic(fmt.Errorf("%v: lhs type %v <- operand %v, op.IsPointerType %v op.IsCompatible %v", ctx.position(n), t, op, op.Type.IsPointerType(), t.IsCompatible(op.Type)))
  1045  	}
  1046  }
  1047  
  1048  // IsPointerType implements Type.
  1049  func (t *PointerType) IsPointerType() bool { return true }
  1050  
  1051  // IsIntegerType implements Type.
  1052  func (t *PointerType) IsIntegerType() bool { return false }
  1053  
  1054  // IsScalarType implements Type.
  1055  func (t *PointerType) IsScalarType() bool { return true }
  1056  
  1057  func (t *PointerType) String() string { return fmt.Sprintf("pointer to %v", t.Item) }
  1058  
  1059  type structBase struct {
  1060  	Fields                 []Field
  1061  	HasFlexibleArrayMember bool
  1062  	Tag                    int
  1063  	scope                  *Scope
  1064  	layout                 []FieldProperties
  1065  }
  1066  
  1067  func (s *structBase) findField(nm int) *FieldProperties {
  1068  	fps := s.layout
  1069  	if x, ok := s.scope.Idents[nm].(*Declarator); ok {
  1070  		r := fps[x.Field]
  1071  		return &r
  1072  	}
  1073  
  1074  	for _, v := range fps {
  1075  		if v.Declarator != nil {
  1076  			continue
  1077  		}
  1078  
  1079  		x, ok := v.Type.(fieldFinder)
  1080  		if !ok {
  1081  			continue
  1082  		}
  1083  
  1084  		if fp := x.findField(nm); fp != nil {
  1085  			r := *fp
  1086  			r.Offset += v.Offset
  1087  			return &r
  1088  		}
  1089  	}
  1090  	return nil
  1091  }
  1092  
  1093  // StructType represents a struct type.
  1094  type StructType struct {
  1095  	structBase
  1096  	pos token.Pos
  1097  }
  1098  
  1099  func (t *StructType) Pos() token.Pos { return t.pos }
  1100  
  1101  // IsUnsigned implements Type.
  1102  func (t *StructType) IsUnsigned() bool { panic("TODO") }
  1103  
  1104  // Field returns the properties of field nm or nil if the field does not exist.
  1105  func (t *StructType) Field(nm int) *FieldProperties {
  1106  	return t.findField(nm)
  1107  }
  1108  
  1109  // IsVoidPointerType implements Type.
  1110  func (t *StructType) IsVoidPointerType() bool { panic("TODO") }
  1111  
  1112  // IsArithmeticType implements Type.
  1113  func (t *StructType) IsArithmeticType() bool { return false }
  1114  
  1115  // IsCompatible implements Type.
  1116  func (t *StructType) IsCompatible(u Type) bool {
  1117  	if t.Equal(u) {
  1118  		return true
  1119  	}
  1120  
  1121  	// [0]6.2.7.1
  1122  	//
  1123  	// Moreover, two structure, union, or enumerated types declared in
  1124  	// separate translation units are compatible if their tags and members
  1125  	// satisfy the following requirements: If one is declared with a tag,
  1126  	// the other shall be declared with the same tag. If both are complete
  1127  	// types, then the following additional requirements apply: there shall
  1128  	// be a one-to-one correspondence between their members such that each
  1129  	// pair of corresponding members are declared with compatible types,
  1130  	// and such that if one member of a corresponding pair is declared with
  1131  	// a name, the other member is declared with the same name. For two
  1132  	// structures, corresponding members shall be declared in the same
  1133  	// order. For two structures or unions, corresponding bit-fields shall
  1134  	// have the same widths.
  1135  	switch x := UnderlyingType(u).(type) {
  1136  	case *StructType:
  1137  		//TODO if len(t.Fields) != len(x.Fields) || t.Tag != x.Tag { // Fails in _sqlite/src/test_fs.c
  1138  		if len(t.Fields) != len(x.Fields) {
  1139  			return false
  1140  		}
  1141  
  1142  		for i, v := range t.Fields {
  1143  			if !v.isCompatiblel(x.Fields[i]) {
  1144  				return false
  1145  			}
  1146  		}
  1147  
  1148  		return true
  1149  	default:
  1150  		return false
  1151  	}
  1152  }
  1153  
  1154  // Equal implements Type.
  1155  func (t *StructType) Equal(u Type) bool {
  1156  	if t == u {
  1157  		return true
  1158  	}
  1159  
  1160  	switch x := u.(type) {
  1161  	case *NamedType:
  1162  		return t.Equal(x.Type)
  1163  	case
  1164  		*ArrayType,
  1165  		*FunctionType,
  1166  		*PointerType:
  1167  
  1168  		return false
  1169  	case *StructType:
  1170  		if len(t.Fields) != len(x.Fields) || t.Tag != x.Tag {
  1171  			return false
  1172  		}
  1173  
  1174  		for i, v := range t.Fields {
  1175  			if !v.equal(x.Fields[i]) {
  1176  				return false
  1177  			}
  1178  		}
  1179  		return true
  1180  	case *TaggedStructType:
  1181  		v := x.getType()
  1182  		if v == u {
  1183  			return false
  1184  		}
  1185  
  1186  		return t.Equal(v)
  1187  	case TypeKind:
  1188  		switch x {
  1189  		case
  1190  			Char,
  1191  			Int,
  1192  			Long,
  1193  			UChar,
  1194  			UInt,
  1195  			UShort,
  1196  			Void:
  1197  
  1198  			return false
  1199  		default:
  1200  			panic(x)
  1201  		}
  1202  	default:
  1203  		panic(fmt.Errorf("%T", x))
  1204  	}
  1205  }
  1206  
  1207  // Kind implements Type.
  1208  func (t *StructType) Kind() TypeKind { return Struct }
  1209  
  1210  // assign implements Type.
  1211  func (t *StructType) assign(ctx *context, n Node, op Operand) Operand {
  1212  	switch x := op.Type.(type) {
  1213  	case *StructType:
  1214  		if !t.IsCompatible(x) {
  1215  			panic("TODO")
  1216  		}
  1217  
  1218  		return Operand{Type: t}
  1219  	case *NamedType:
  1220  		if !t.IsCompatible(x.Type) {
  1221  			panic("TODO")
  1222  		}
  1223  
  1224  		return Operand{Type: t}
  1225  	default:
  1226  		panic(fmt.Errorf("%v: %T %v", ctx.position(n), x, x))
  1227  	}
  1228  }
  1229  
  1230  // IsPointerType implements Type.
  1231  func (t *StructType) IsPointerType() bool { return false }
  1232  
  1233  // IsIntegerType implements Type.
  1234  func (t *StructType) IsIntegerType() bool { return false }
  1235  
  1236  // IsScalarType implements Type.
  1237  func (t *StructType) IsScalarType() bool { return false }
  1238  
  1239  func (t *StructType) String() string {
  1240  	var buf bytes.Buffer
  1241  	buf.WriteString("struct{")
  1242  	for i, v := range t.Fields {
  1243  		if i != 0 {
  1244  			buf.WriteString("; ")
  1245  		}
  1246  		fmt.Fprintf(&buf, "%s %s", dict.S(v.Name), v.Type)
  1247  		if v.Bits != 0 {
  1248  			fmt.Fprintf(&buf, ".%d", v.Bits)
  1249  		}
  1250  	}
  1251  	buf.WriteByte('}')
  1252  	return buf.String()
  1253  }
  1254  
  1255  // TaggedEnumType represents an enum type described by a tag name.
  1256  type TaggedEnumType struct {
  1257  	Tag   int
  1258  	Type  Type
  1259  	scope *Scope
  1260  	pos   token.Pos
  1261  }
  1262  
  1263  func (t *TaggedEnumType) Pos() token.Pos { return t.pos }
  1264  
  1265  // IsUnsigned implements Type.
  1266  func (t *TaggedEnumType) IsUnsigned() bool { return t.Type.IsUnsigned() }
  1267  
  1268  // Equal implements Type.
  1269  func (t *TaggedEnumType) Equal(u Type) bool {
  1270  	switch x := UnderlyingType(u).(type) {
  1271  	case *EnumType:
  1272  		switch y := t.getType(); {
  1273  		case y == t:
  1274  			panic("TODO")
  1275  		default:
  1276  			return y.Equal(u)
  1277  		}
  1278  	case *TaggedEnumType:
  1279  		if t.Tag == x.Tag {
  1280  			return true
  1281  		}
  1282  
  1283  		panic("TODO")
  1284  	case TypeKind:
  1285  		if x.IsScalarType() {
  1286  			return false
  1287  		}
  1288  
  1289  		panic(fmt.Errorf("%v", x))
  1290  	case *PointerType:
  1291  		return false
  1292  	default:
  1293  		panic(fmt.Errorf("%T", x))
  1294  	}
  1295  }
  1296  
  1297  // IsArithmeticType implements Type.
  1298  func (t *TaggedEnumType) IsArithmeticType() bool { return true }
  1299  
  1300  // IsCompatible implements Type.
  1301  func (t *TaggedEnumType) IsCompatible(u Type) bool {
  1302  	switch x := t.getType(); {
  1303  	case x == t:
  1304  		panic("TODO")
  1305  	default:
  1306  		return underlyingType(x, true).IsCompatible(underlyingType(u, true))
  1307  	}
  1308  }
  1309  
  1310  // IsIntegerType implements Type.
  1311  func (t *TaggedEnumType) IsIntegerType() bool { return true }
  1312  
  1313  // IsPointerType implements Type.
  1314  func (t *TaggedEnumType) IsPointerType() bool { return false }
  1315  
  1316  // IsScalarType implements Type.
  1317  func (t *TaggedEnumType) IsScalarType() bool { return true }
  1318  
  1319  // IsVoidPointerType implements Type.
  1320  func (t *TaggedEnumType) IsVoidPointerType() bool { panic("TODO") }
  1321  
  1322  // Kind implements Type.
  1323  func (t *TaggedEnumType) Kind() TypeKind { return Int }
  1324  
  1325  func (t *TaggedEnumType) String() string { return fmt.Sprintf("enum %s", dict.S(t.Tag)) }
  1326  
  1327  // assign implements Type.
  1328  func (t *TaggedEnumType) assign(ctx *context, n Node, op Operand) Operand {
  1329  	switch x := UnderlyingType(op.Type).(type) {
  1330  	case *EnumType:
  1331  		//TODO use IsCompatible
  1332  		op.Type = t
  1333  		return op
  1334  	case TypeKind:
  1335  		if x.IsIntegerType() {
  1336  			op.Type = t
  1337  			return op
  1338  		}
  1339  
  1340  		panic(x)
  1341  	default:
  1342  		panic(fmt.Errorf("%T", x))
  1343  	}
  1344  }
  1345  
  1346  func (t *TaggedEnumType) getType() Type {
  1347  	if t.Type != nil {
  1348  		return t.Type
  1349  	}
  1350  
  1351  	s := t.scope.lookupEnumTag(t.Tag)
  1352  	if s == nil {
  1353  		return t
  1354  	}
  1355  
  1356  	t.Type = s.typ
  1357  	return t.Type
  1358  }
  1359  
  1360  // TaggedStructType represents a struct type described by a tag name.
  1361  type TaggedStructType struct {
  1362  	Tag   int
  1363  	Type  Type
  1364  	scope *Scope
  1365  	pos   token.Pos
  1366  }
  1367  
  1368  func (t *TaggedStructType) Pos() token.Pos { return t.pos }
  1369  
  1370  // IsUnsigned implements Type.
  1371  func (t *TaggedStructType) IsUnsigned() bool { panic("TODO") }
  1372  
  1373  // IsVoidPointerType implements Type.
  1374  func (t *TaggedStructType) IsVoidPointerType() bool { panic("TODO") }
  1375  
  1376  // IsArithmeticType implements Type.
  1377  func (t *TaggedStructType) IsArithmeticType() bool { return false }
  1378  
  1379  // IsCompatible implements Type.
  1380  func (t *TaggedStructType) IsCompatible(u Type) bool {
  1381  	if t == u {
  1382  		return true
  1383  	}
  1384  
  1385  	if x, ok := u.(*TaggedStructType); ok && t.Tag == x.Tag {
  1386  		return true
  1387  	}
  1388  
  1389  	return false
  1390  }
  1391  
  1392  // Equal implements Type.
  1393  func (t *TaggedStructType) Equal(u Type) bool {
  1394  	if t == u {
  1395  		return true
  1396  	}
  1397  
  1398  	if x, ok := u.(*TaggedStructType); ok && t.Tag == x.Tag {
  1399  		return true
  1400  	}
  1401  
  1402  	switch x := t.getType().(type) {
  1403  	case *StructType:
  1404  		return x.Equal(u)
  1405  	case *TaggedStructType:
  1406  		if x == t {
  1407  			switch y := u.(type) {
  1408  			case *NamedType:
  1409  				return t.Equal(y.Type)
  1410  			case *StructType:
  1411  				return false
  1412  			case *TaggedStructType:
  1413  				return t.Tag == y.Tag
  1414  			case TypeKind:
  1415  				switch y {
  1416  				case Void:
  1417  					return false
  1418  				default:
  1419  					panic(y)
  1420  				}
  1421  			default:
  1422  				panic(fmt.Errorf("%T", y))
  1423  			}
  1424  		}
  1425  
  1426  		panic("TODO")
  1427  	default:
  1428  		panic(fmt.Errorf("%T", x))
  1429  	}
  1430  }
  1431  
  1432  func (t *TaggedStructType) getType() Type {
  1433  	if t.Type != nil {
  1434  		return t.Type
  1435  	}
  1436  
  1437  	s := t.scope.lookupStructTag(t.Tag)
  1438  	if s == nil {
  1439  		return t
  1440  	}
  1441  
  1442  	t.Type = s.typ
  1443  	return t.Type
  1444  }
  1445  
  1446  // Kind implements Type.
  1447  func (t *TaggedStructType) Kind() TypeKind { return Struct }
  1448  
  1449  // assign implements Type.
  1450  func (t *TaggedStructType) assign(ctx *context, n Node, op Operand) Operand {
  1451  	switch x := op.Type.(type) {
  1452  	case *NamedType:
  1453  		op.Type = x.Type
  1454  		return t.assign(ctx, n, op)
  1455  	case *TaggedStructType:
  1456  		t2 := t.getType()
  1457  		u2 := x.getType()
  1458  		if t2 != t && u2 != x {
  1459  			// [0]6.5.16.1
  1460  			//
  1461  			// the left operand has a qualified or unqualified
  1462  			// version of a structure or union type compatible with
  1463  			// the type of the right;
  1464  			if t2.Equal(u2) {
  1465  				return op
  1466  			}
  1467  
  1468  			panic("TODO")
  1469  		}
  1470  		panic("TODO")
  1471  	case *StructType:
  1472  		t2 := t.getType()
  1473  		if t2.Equal(x) {
  1474  			return op
  1475  		}
  1476  		panic(fmt.Errorf("%v: %T %v, %T %v", ctx.position(n), t2, t2, x, x))
  1477  	default:
  1478  		panic(fmt.Errorf("%T", x))
  1479  	}
  1480  }
  1481  
  1482  // IsPointerType implements Type.
  1483  func (t *TaggedStructType) IsPointerType() bool { return false }
  1484  
  1485  // IsIntegerType implements Type.
  1486  func (t *TaggedStructType) IsIntegerType() bool { return false }
  1487  
  1488  // IsScalarType implements Type.
  1489  func (t *TaggedStructType) IsScalarType() bool { return false }
  1490  
  1491  func (t *TaggedStructType) String() string { return fmt.Sprintf("struct %s", dict.S(t.Tag)) }
  1492  
  1493  // UnionType represents a union type.
  1494  type UnionType struct {
  1495  	structBase
  1496  	pos token.Pos
  1497  }
  1498  
  1499  func (t *UnionType) Pos() token.Pos { return t.pos }
  1500  
  1501  // Field returns the properties of field nm or nil if the field does not exist.
  1502  func (t *UnionType) Field(nm int) *FieldProperties {
  1503  	return t.findField(nm)
  1504  }
  1505  
  1506  // IsUnsigned implements Type.
  1507  func (t *UnionType) IsUnsigned() bool { panic("TODO") }
  1508  
  1509  // TaggedUnionType represents a struct type described by a tag name.
  1510  type TaggedUnionType struct {
  1511  	Tag   int
  1512  	Type  Type
  1513  	scope *Scope
  1514  	pos   token.Pos
  1515  }
  1516  
  1517  func (t *TaggedUnionType) Pos() token.Pos { return t.pos }
  1518  
  1519  // IsUnsigned implements Type.
  1520  func (t *TaggedUnionType) IsUnsigned() bool { panic("TODO") }
  1521  
  1522  // IsVoidPointerType implements Type.
  1523  func (t *TaggedUnionType) IsVoidPointerType() bool { panic("TODO") }
  1524  
  1525  // IsArithmeticType implements Type.
  1526  func (t *TaggedUnionType) IsArithmeticType() bool { return false }
  1527  
  1528  // IsCompatible implements Type.
  1529  func (t *TaggedUnionType) IsCompatible(u Type) bool { return t.Equal(u) }
  1530  
  1531  // Equal implements Type.
  1532  func (t *TaggedUnionType) Equal(u Type) bool {
  1533  	if t == u {
  1534  		return true
  1535  	}
  1536  
  1537  	if x, ok := u.(*TaggedUnionType); ok && t.Tag == x.Tag {
  1538  		return true
  1539  	}
  1540  
  1541  	switch x := t.getType().(type) {
  1542  	case *UnionType:
  1543  		return x.Equal(u)
  1544  	default:
  1545  		panic(fmt.Errorf("%T", x))
  1546  	}
  1547  }
  1548  
  1549  func (t *TaggedUnionType) getType() Type {
  1550  	if t.Type != nil {
  1551  		return t.Type
  1552  	}
  1553  
  1554  	s := t.scope.lookupStructTag(t.Tag)
  1555  	if s == nil {
  1556  		return t
  1557  	}
  1558  
  1559  	t.Type = s.typ
  1560  	return t.Type
  1561  }
  1562  
  1563  // Kind implements Type.
  1564  func (t *TaggedUnionType) Kind() TypeKind { return Union }
  1565  
  1566  // assign implements Type.
  1567  func (t *TaggedUnionType) assign(ctx *context, n Node, op Operand) Operand {
  1568  	switch x := op.Type.(type) {
  1569  	case *TaggedUnionType:
  1570  		t2 := t.getType()
  1571  		u2 := x.getType()
  1572  		if t2 != t && u2 != x {
  1573  			// [0]6.5.16.1
  1574  			//
  1575  			// the left operand has a qualified or unqualified
  1576  			// version of a structure or union type compatible with
  1577  			// the type of the right;
  1578  			if t2.Equal(u2) {
  1579  				return op
  1580  			}
  1581  
  1582  			panic("TODO")
  1583  		}
  1584  		panic("TODO")
  1585  	default:
  1586  		panic(fmt.Errorf("%T", x))
  1587  	}
  1588  }
  1589  
  1590  // IsPointerType implements Type.
  1591  func (t *TaggedUnionType) IsPointerType() bool { return false }
  1592  
  1593  // IsIntegerType implements Type.
  1594  func (t *TaggedUnionType) IsIntegerType() bool { return false }
  1595  
  1596  // IsScalarType implements Type.
  1597  func (t *TaggedUnionType) IsScalarType() bool { return false }
  1598  
  1599  func (t *TaggedUnionType) String() string { return fmt.Sprintf("union %s", dict.S(t.Tag)) }
  1600  
  1601  // IsVoidPointerType implements Type.
  1602  func (t *UnionType) IsVoidPointerType() bool { panic("TODO") }
  1603  
  1604  // IsArithmeticType implements Type.
  1605  func (t *UnionType) IsArithmeticType() bool { return false }
  1606  
  1607  // IsCompatible implements Type.
  1608  func (t *UnionType) IsCompatible(u Type) bool {
  1609  	if t.Equal(u) {
  1610  		return true
  1611  	}
  1612  
  1613  	switch x := UnderlyingType(u).(type) {
  1614  	case *PointerType:
  1615  		return false
  1616  	case TypeKind:
  1617  		if x.IsScalarType() {
  1618  			return false
  1619  		}
  1620  		panic(fmt.Errorf("%v %T %v", t, x, x))
  1621  	default:
  1622  		panic(fmt.Errorf("%v %T %v", t, x, x))
  1623  	}
  1624  }
  1625  
  1626  // Equal implements Type.
  1627  func (t *UnionType) Equal(u Type) bool {
  1628  	if t == u {
  1629  		return true
  1630  	}
  1631  
  1632  	switch x := u.(type) {
  1633  	case *NamedType:
  1634  		return t.Equal(x.Type)
  1635  	case *PointerType:
  1636  		return false
  1637  	case *TaggedUnionType:
  1638  		v := x.Type
  1639  		if v == x {
  1640  			panic(x)
  1641  		}
  1642  
  1643  		return t.Equal(v)
  1644  	case TypeKind:
  1645  		switch x {
  1646  		case
  1647  			Char,
  1648  			Int,
  1649  			UInt,
  1650  			ULongLong,
  1651  			Void:
  1652  
  1653  			return false
  1654  		default:
  1655  			panic(x)
  1656  		}
  1657  	case *UnionType:
  1658  		if len(t.Fields) != len(x.Fields) || t.Tag != x.Tag {
  1659  			return false
  1660  		}
  1661  
  1662  		for i, v := range t.Fields {
  1663  			if !v.equal(x.Fields[i]) {
  1664  				return false
  1665  			}
  1666  		}
  1667  		return true
  1668  	default:
  1669  		panic(x)
  1670  	}
  1671  }
  1672  
  1673  // Kind implements Type.
  1674  func (t *UnionType) Kind() TypeKind { return Union }
  1675  
  1676  // assign implements Type.
  1677  func (t *UnionType) assign(ctx *context, n Node, op Operand) Operand {
  1678  	switch x := op.Type.(type) {
  1679  	case *NamedType:
  1680  		if !t.IsCompatible(x.Type) {
  1681  			panic("TODO")
  1682  		}
  1683  
  1684  		return Operand{Type: t}
  1685  	case *UnionType:
  1686  		if !t.IsCompatible(x) {
  1687  			panic("TODO")
  1688  		}
  1689  
  1690  		return Operand{Type: t}
  1691  	default:
  1692  		panic(fmt.Errorf("%v: %T %v", ctx.position(n), x, x))
  1693  	}
  1694  }
  1695  
  1696  // IsPointerType implements Type.
  1697  func (t *UnionType) IsPointerType() bool { return false }
  1698  
  1699  // IsIntegerType implements Type.
  1700  func (t *UnionType) IsIntegerType() bool { return false }
  1701  
  1702  // IsScalarType implements Type.
  1703  func (t *UnionType) IsScalarType() bool { return false }
  1704  
  1705  func (t *UnionType) String() string {
  1706  	var buf bytes.Buffer
  1707  	buf.WriteString("union{")
  1708  	for i, v := range t.Fields {
  1709  		if i != 0 {
  1710  			buf.WriteString("; ")
  1711  		}
  1712  		fmt.Fprintf(&buf, "%s %s", dict.S(v.Name), v.Type)
  1713  		if v.Bits != 0 {
  1714  			fmt.Fprintf(&buf, ".%d", v.Bits)
  1715  		}
  1716  
  1717  	}
  1718  	buf.WriteByte('}')
  1719  	return buf.String()
  1720  }
  1721  
  1722  // AdjustedParameterType returns the type of an expression when used as an
  1723  // argument of a function, see [0]6.9.1-10.
  1724  func AdjustedParameterType(t Type) Type {
  1725  	u := t
  1726  	for {
  1727  		switch x := u.(type) {
  1728  		case *ArrayType:
  1729  			return &PointerType{t, t.Pos()}
  1730  		case *NamedType:
  1731  			if isVaList(x) {
  1732  				return x
  1733  			}
  1734  
  1735  			u = x.Type
  1736  		case
  1737  			*EnumType,
  1738  			*PointerType,
  1739  			*StructType,
  1740  			*TaggedEnumType,
  1741  			*TaggedStructType,
  1742  			*TaggedUnionType,
  1743  			*UnionType:
  1744  
  1745  			return t
  1746  		case TypeKind:
  1747  			switch x {
  1748  			case
  1749  				Char,
  1750  				Double,
  1751  				DoubleComplex,
  1752  				LongDouble,
  1753  				Float,
  1754  				FloatComplex,
  1755  				Int,
  1756  				Long,
  1757  				LongDoubleComplex,
  1758  				LongLong,
  1759  				SChar,
  1760  				Short,
  1761  				UChar,
  1762  				UInt,
  1763  				ULong,
  1764  				ULongLong,
  1765  				UShort:
  1766  
  1767  				return t
  1768  			default:
  1769  				panic(x)
  1770  			}
  1771  		default:
  1772  			panic(fmt.Errorf("%T", x))
  1773  		}
  1774  	}
  1775  }
  1776  
  1777  // UnderlyingType returns the concrete type of t, if posible.
  1778  func UnderlyingType(t Type) Type { return underlyingType(t, false) }
  1779  
  1780  func underlyingType(t Type, enums bool) Type {
  1781  	for {
  1782  		switch x := t.(type) {
  1783  		case
  1784  			*ArrayType,
  1785  			*FunctionType,
  1786  			*PointerType,
  1787  			*StructType,
  1788  			*UnionType:
  1789  
  1790  			return x
  1791  		case *EnumType:
  1792  			if enums {
  1793  				return x
  1794  			}
  1795  
  1796  			return x.Enums[0].Operand.Type
  1797  		case *NamedType:
  1798  			if x.Type == nil {
  1799  				return x
  1800  			}
  1801  
  1802  			t = x.Type
  1803  		case *TaggedEnumType:
  1804  			if x.Type == nil {
  1805  				return x
  1806  			}
  1807  
  1808  			t = x.Type
  1809  		case *TaggedStructType:
  1810  			if x.Type == nil {
  1811  				return x
  1812  			}
  1813  
  1814  			t = x.Type
  1815  		case *TaggedUnionType:
  1816  			if x.Type == nil {
  1817  				return x
  1818  			}
  1819  
  1820  			t = x.Type
  1821  		case TypeKind:
  1822  			switch x {
  1823  			case
  1824  				Bool,
  1825  				Char,
  1826  				Double,
  1827  				DoubleComplex,
  1828  				DoubleImaginary,
  1829  				Float,
  1830  				FloatComplex,
  1831  				FloatImaginary,
  1832  				Int,
  1833  				Long,
  1834  				LongDouble,
  1835  				LongDoubleComplex,
  1836  				LongDoubleImaginary,
  1837  				LongLong,
  1838  				Ptr,
  1839  				SChar,
  1840  				Short,
  1841  				UChar,
  1842  				UInt,
  1843  				ULong,
  1844  				ULongLong,
  1845  				UShort,
  1846  				Void:
  1847  
  1848  				return x
  1849  			default:
  1850  				panic(fmt.Errorf("%v", x))
  1851  			}
  1852  		default:
  1853  			panic(fmt.Errorf("%T", x))
  1854  		}
  1855  	}
  1856  }