summaryrefslogtreecommitdiff
path: root/vendor/modernc.org/cc
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/cc')
-rw-r--r--vendor/modernc.org/cc/v3/Makefile4
-rw-r--r--vendor/modernc.org/cc/v3/abi.go17
-rw-r--r--vendor/modernc.org/cc/v3/abi_platforms.go101
-rw-r--r--vendor/modernc.org/cc/v3/ast.go2
-rw-r--r--vendor/modernc.org/cc/v3/ast2.go39
-rw-r--r--vendor/modernc.org/cc/v3/cc.go16
-rw-r--r--vendor/modernc.org/cc/v3/check.go567
-rw-r--r--vendor/modernc.org/cc/v3/cpp.go30
-rw-r--r--vendor/modernc.org/cc/v3/lexer.go8
-rw-r--r--vendor/modernc.org/cc/v3/lexer.l2
-rw-r--r--vendor/modernc.org/cc/v3/parser.yy4
-rw-r--r--vendor/modernc.org/cc/v3/scanner.go4
-rw-r--r--vendor/modernc.org/cc/v3/type.go35
13 files changed, 544 insertions, 285 deletions
diff --git a/vendor/modernc.org/cc/v3/Makefile b/vendor/modernc.org/cc/v3/Makefile
index e63a28112..12f21d040 100644
--- a/vendor/modernc.org/cc/v3/Makefile
+++ b/vendor/modernc.org/cc/v3/Makefile
@@ -95,8 +95,8 @@ edit:
editor: lexer.go
gofmt -l -s -w *.go
- GO111MODULE=off go test -o /dev/null -c
- GO111MODULE=off go install 2>&1 | tee log
+ go test -o /dev/null -c
+ go install 2>&1 | tee log
ast.go lexer.go stringer.go: lexer.l parser.yy enum.go
go generate
diff --git a/vendor/modernc.org/cc/v3/abi.go b/vendor/modernc.org/cc/v3/abi.go
index 537c8278c..e03255843 100644
--- a/vendor/modernc.org/cc/v3/abi.go
+++ b/vendor/modernc.org/cc/v3/abi.go
@@ -50,10 +50,9 @@ func NewABI(os, arch string) (ABI, error) {
return ABI{}, fmt.Errorf("unsupported os/arch pair: %s-%s", os, arch)
}
abi := ABI{
- ByteOrder: order,
- Types: make(map[Kind]ABIType, len(types)),
- //TODO: depends on the OS?
- SignedChar: true,
+ ByteOrder: order,
+ Types: make(map[Kind]ABIType, len(types)),
+ SignedChar: abiSignedChar[[2]string{os, arch}],
os: os,
arch: arch,
}
@@ -276,10 +275,10 @@ func (a *ABI) layout(ctx *context, n Node, t *structType) *structType {
off := f.offset
m[off] = append(m[off], f)
}
- for _, a := range m {
+ for _, s := range m {
var first *field
var w byte
- for _, f := range a {
+ for _, f := range s {
if first == nil {
first = f
}
@@ -291,11 +290,15 @@ func (a *ABI) layout(ctx *context, n Node, t *structType) *structType {
}
}
w = normalizeBitFieldWidth(w)
- for _, f := range a {
+ for _, f := range s {
if f.isBitField {
f.blockStart = first
f.blockWidth = w
}
+ if a.ByteOrder == binary.BigEndian {
+ f.bitFieldOffset = w - f.bitFieldWidth - f.bitFieldOffset
+ f.bitFieldMask = (uint64(1)<<f.bitFieldWidth - 1) << f.bitFieldOffset
+ }
}
}
}()
diff --git a/vendor/modernc.org/cc/v3/abi_platforms.go b/vendor/modernc.org/cc/v3/abi_platforms.go
index ee95f15b6..5b1820c78 100644
--- a/vendor/modernc.org/cc/v3/abi_platforms.go
+++ b/vendor/modernc.org/cc/v3/abi_platforms.go
@@ -3,13 +3,31 @@ package cc
import "encoding/binary"
// abiByteOrders contains byte order information for known architectures.
-var abiByteOrders = map[string]binary.ByteOrder{
- "amd64": binary.LittleEndian,
- "386": binary.LittleEndian,
- "arm": binary.LittleEndian,
- "arm64": binary.LittleEndian,
- "s390x": binary.BigEndian,
-}
+var (
+ abiByteOrders = map[string]binary.ByteOrder{
+ "amd64": binary.LittleEndian,
+ "386": binary.LittleEndian,
+ "arm": binary.LittleEndian,
+ "arm64": binary.LittleEndian,
+ "s390x": binary.BigEndian,
+ }
+
+ abiSignedChar = map[[2]string]bool{
+ {"linux", "arm"}: false,
+ {"linux", "arm64"}: false,
+ {"linux", "s390x"}: false,
+
+ {"darwin", "amd64"}: true,
+ {"darwin", "arm64"}: true,
+ {"freebsd", "amd64"}: true,
+ {"linux", "386"}: true,
+ {"linux", "amd64"}: true,
+ {"netbsd", "amd64"}: true,
+ {"openbsd", "amd64"}: true,
+ {"windows", "386"}: true,
+ {"windows", "amd64"}: true,
+ }
+)
// abiTypes contains size and alignment information for known OS/arch pairs.
//
@@ -364,4 +382,73 @@ var abiTypes = map[[2]string]map[Kind]ABIType{
Int128: {16, 16, 16},
UInt128: {16, 16, 16},
},
+ // gcc (GCC) 8.4.0
+ {"openbsd", "amd64"}: {
+ Void: {1, 1, 1},
+ Bool: {1, 1, 1},
+ Char: {1, 1, 1},
+ SChar: {1, 1, 1},
+ UChar: {1, 1, 1},
+ Short: {2, 2, 2},
+ UShort: {2, 2, 2},
+ Enum: {4, 4, 4},
+ Int: {4, 4, 4},
+ UInt: {4, 4, 4},
+ Long: {8, 8, 8},
+ ULong: {8, 8, 8},
+ LongLong: {8, 8, 8},
+ ULongLong: {8, 8, 8},
+ Ptr: {8, 8, 8},
+ Function: {8, 8, 8},
+ Float: {4, 4, 4},
+ Double: {8, 8, 8},
+ LongDouble: {16, 16, 16},
+ Int8: {1, 1, 1},
+ UInt8: {1, 1, 1},
+ Int16: {2, 2, 2},
+ UInt16: {2, 2, 2},
+ Int32: {4, 4, 4},
+ UInt32: {4, 4, 4},
+ Int64: {8, 8, 8},
+ UInt64: {8, 8, 8},
+ Int128: {16, 16, 16},
+ UInt128: {16, 16, 16},
+ Float32: {4, 4, 4},
+ Float32x: {8, 8, 8},
+ Float64: {8, 8, 8},
+ Float64x: {16, 16, 16},
+ Float128: {16, 16, 16},
+ },
+ // gcc (GCC) 10.3.0
+ {"netbsd", "amd64"}: {
+ Void: {1, 1, 1},
+ Bool: {1, 1, 1},
+ Char: {1, 1, 1},
+ SChar: {1, 1, 1},
+ UChar: {1, 1, 1},
+ Short: {2, 2, 2},
+ UShort: {2, 2, 2},
+ Enum: {4, 4, 4},
+ Int: {4, 4, 4},
+ UInt: {4, 4, 4},
+ Long: {8, 8, 8},
+ ULong: {8, 8, 8},
+ LongLong: {8, 8, 8},
+ ULongLong: {8, 8, 8},
+ Ptr: {8, 8, 8},
+ Function: {8, 8, 8},
+ Float: {4, 4, 4},
+ Double: {8, 8, 8},
+ LongDouble: {16, 16, 16},
+ Int8: {1, 1, 1},
+ UInt8: {1, 1, 1},
+ Int16: {2, 2, 2},
+ UInt16: {2, 2, 2},
+ Int32: {4, 4, 4},
+ UInt32: {4, 4, 4},
+ Int64: {8, 8, 8},
+ UInt64: {8, 8, 8},
+ Int128: {16, 16, 16},
+ UInt128: {16, 16, 16},
+ },
}
diff --git a/vendor/modernc.org/cc/v3/ast.go b/vendor/modernc.org/cc/v3/ast.go
index c34d3c0fa..28a1569bb 100644
--- a/vendor/modernc.org/cc/v3/ast.go
+++ b/vendor/modernc.org/cc/v3/ast.go
@@ -670,6 +670,7 @@ func (n *AssignmentExpression) Position() (r token.Position) {
// AtomicTypeSpecifier:
// "_Atomic" '(' TypeName ')'
type AtomicTypeSpecifier struct {
+ list []*TypeSpecifier
Token Token
Token2 Token
Token3 Token
@@ -1339,6 +1340,7 @@ type Declarator struct {
called bool
fnDef bool
hasInitializer bool
+ implicit bool
AttributeSpecifierList *AttributeSpecifierList
DirectDeclarator *DirectDeclarator
Pointer *Pointer
diff --git a/vendor/modernc.org/cc/v3/ast2.go b/vendor/modernc.org/cc/v3/ast2.go
index b4edb9928..13ed61306 100644
--- a/vendor/modernc.org/cc/v3/ast2.go
+++ b/vendor/modernc.org/cc/v3/ast2.go
@@ -414,16 +414,16 @@ func Preprocess(cfg *Config, includePaths, sysIncludePaths []string, sources []S
func wTok(w io.Writer, tok Token) (err error) {
switch tok.Rune {
case STRINGLITERAL, LONGSTRINGLITERAL:
- _, err = fmt.Fprintf(w, `%s"%s"`, tok.Sep, cQuotedString(tok.String()))
+ _, err = fmt.Fprintf(w, `%s"%s"`, tok.Sep, cQuotedString(tok.String(), true))
case CHARCONST, LONGCHARCONST:
- _, err = fmt.Fprintf(w, `%s'%s'`, tok.Sep, cQuotedString(tok.String()))
+ _, err = fmt.Fprintf(w, `%s'%s'`, tok.Sep, cQuotedString(tok.String(), false))
default:
_, err = fmt.Fprintf(w, "%s%s", tok.Sep, tok)
}
return err
}
-func cQuotedString(s string) []byte {
+func cQuotedString(s string, isString bool) []byte {
var b []byte
for i := 0; i < len(s); i++ {
c := s[i]
@@ -447,7 +447,20 @@ func cQuotedString(s string) []byte {
b = append(b, '\\', '\\')
continue
case '"':
- b = append(b, '\\', '"')
+ switch {
+ case isString:
+ b = append(b, '\\', '"')
+ default:
+ b = append(b, '"')
+ }
+ continue
+ case '\'':
+ switch {
+ case isString:
+ b = append(b, '\'')
+ default:
+ b = append(b, '\\', '\'')
+ }
continue
}
@@ -590,7 +603,11 @@ func (n *BlockItem) Closure() map[StringID]struct{} { return n.closure }
// FunctionDefinition returns the nested function (case BlockItemFuncDef).
func (n *BlockItem) FunctionDefinition() *FunctionDefinition { return n.fn }
-func (n *Declarator) IsStatic() bool { return n.td != nil && n.td.static() }
+func (n *Declarator) IsStatic() bool { return n.td != nil && n.td.static() }
+
+// IsImplicit reports whether n was not declared nor defined, only inferred.
+func (n *Declarator) IsImplicit() bool { return n.implicit }
+
func (n *Declarator) isVisible(at int32) bool { return at == 0 || n.DirectDeclarator.ends() < at }
func (n *Declarator) setLHS(lhs *Declarator) {
@@ -790,7 +807,8 @@ func (n *AndExpression) Promote() Type { return n.promote }
func (n *InitDeclarator) Value() *InitializerValue { return n.initializer }
-// FirstDesignatorField returns the first field a designator denotes, if any.
+// FirstDesignatorField returns the first field a designator of an union type
+// denotes, if any.
func (n *Initializer) FirstDesignatorField() Field { return n.field0 }
// TrailingComma returns the comma token following n, if any.
@@ -894,6 +912,15 @@ func (n *EnumSpecifier) LexicalScope() Scope { return n.lexicalScope }
// // TypeSpecifierTypedefName was resolved in, if any.
// func (n *TypeSpecifier) ResolvedIn() Scope { return n.resolvedIn }
+func (n *TypeSpecifier) list() (r []*TypeSpecifier) {
+ switch n.Case {
+ case TypeSpecifierAtomic:
+ return n.AtomicTypeSpecifier.list
+ default:
+ return []*TypeSpecifier{n}
+ }
+}
+
// // LexicalScope returns the lexical scope of n.
// func (n *UnaryExpression) LexicalScope() Scope { return n.lexicalScope }
diff --git a/vendor/modernc.org/cc/v3/cc.go b/vendor/modernc.org/cc/v3/cc.go
index 745d0e52d..cc8e90c4e 100644
--- a/vendor/modernc.org/cc/v3/cc.go
+++ b/vendor/modernc.org/cc/v3/cc.go
@@ -509,14 +509,18 @@ type Config struct {
PragmaHandler func(Pragma, []Token) // Called on pragmas, other than #pragma STDC ..., if non nil
- // SharedFunctionDefinitions collects function definitions having the
- // same position and definition. This can happen, for example, when a
- // function is defined in a header file included multiple times. Either
- // within a single translation unit or across translation units. In the
- // later case just supply the same SharedFunctionDefinitions in Config
- // when translating/parsing each translation unit.
+ // SharedFunctionDefinitions collects function definitions having the same
+ // position and definition. This can happen, for example, when a function is
+ // defined in a header file included multiple times. Either within a single
+ // translation unit or across translation units. In the later case just supply
+ // the same SharedFunctionDefinitions in Config when translating/parsing each
+ // translation unit.
SharedFunctionDefinitions *SharedFunctionDefinitions
+ // IncludeFileHandler, when non nil, is called by the preprocessor for every
+ // successfully included file.
+ IncludeFileHandler func(pos gotoken.Position, includePath string)
+
MaxErrors int // 0: default (10), < 0: unlimited, n: n.
CheckExternInlineFnBodies bool // Translate will consider extern inline function bodies.
diff --git a/vendor/modernc.org/cc/v3/check.go b/vendor/modernc.org/cc/v3/check.go
index 57b6a463d..3c4bed427 100644
--- a/vendor/modernc.org/cc/v3/check.go
+++ b/vendor/modernc.org/cc/v3/check.go
@@ -6,6 +6,7 @@ package cc // import "modernc.org/cc/v3"
import (
"fmt"
+ "go/token"
"math"
"math/big"
"math/bits"
@@ -14,6 +15,7 @@ import (
"strings"
"modernc.org/mathutil"
+ "modernc.org/strutil"
)
const longDoublePrec = 256
@@ -237,7 +239,7 @@ func (n *InitDeclarator) check(ctx *context, td typeDescriptor, typ Type, tld bo
typ := n.Declarator.check(ctx, td, typ, tld)
n.Declarator.hasInitializer = true
n.Declarator.Write++
- n.Initializer.check(ctx, &n.Initializer.list, typ, n.Declarator.StorageClass, nil, 0, nil, nil)
+ n.Initializer.check(ctx, &n.Initializer.list, typ, n.Declarator.StorageClass, nil, 0, nil, nil, false)
n.Initializer.setConstZero()
n.initializer = &InitializerValue{typ: typ, initializer: n.Initializer}
if ctx.cfg.TrackAssignments {
@@ -282,8 +284,8 @@ func (n *InitializerList) setConstZero() {
}
// [0], 6.7.8 Initialization
-func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, fld Field, off uintptr, il *InitializerList, designatorList *DesignatorList) *InitializerList {
- // trc("Initializer.check: %v: t %v, off %v, designatorList != nil %v", n.Position(), t, off, designatorList != nil)
+func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, fld Field, off uintptr, il *InitializerList, designatorList *DesignatorList, inList bool) *InitializerList {
+ // trc("==== %v: case %v, t %v, off %v, designatorList != nil %v, inList %v", n.Position(), n.Case, t.Alias(), off, designatorList != nil, inList)
// if fld != nil {
// trc("\tfld %q", fld.Name())
// }
@@ -307,7 +309,7 @@ func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc Stora
single := n.single()
var op Operand
if single != nil {
- op = single.AssignmentExpression.check(ctx)
+ op = single.AssignmentExpression.check(ctx, false)
single.typ = t
single.Field = fld
single.Offset = off
@@ -418,11 +420,11 @@ func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc Stora
if il != nil {
switch t.Kind() {
case Array:
- return il.checkArray(ctx, list, t, sc, off, designatorList)
+ return il.checkArray(ctx, list, t, sc, off, designatorList, inList)
case Struct:
- return il.checkStruct(ctx, list, t, sc, off, designatorList)
+ return il.checkStruct(ctx, list, t, sc, off, designatorList, inList)
case Union:
- return il.checkUnion(ctx, list, t, sc, off, designatorList)
+ return il.checkUnion(ctx, list, t, sc, off, designatorList, inList)
case Vector:
return il.InitializerList //TODO
default:
@@ -448,7 +450,7 @@ func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc Stora
return true
})
if l != nil {
- l.check(ctx, list, t, sc, off, designatorList)
+ l.check(ctx, list, t, sc, off, designatorList, inList)
return nil
}
@@ -456,7 +458,7 @@ func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc Stora
return nil
}
- n.InitializerList.check(ctx, list, t, sc, off, designatorList)
+ n.InitializerList.check(ctx, list, t, sc, off, designatorList, inList)
if il != nil {
return il.InitializerList
}
@@ -464,7 +466,7 @@ func (n *Initializer) check(ctx *context, list *[]*Initializer, t Type, sc Stora
return nil
}
-func (n *InitializerList) checkArray(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList) *InitializerList {
+func (n *InitializerList) checkArray(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList {
elem := t.Elem()
esz := elem.Size()
length := t.Len()
@@ -476,14 +478,15 @@ loop:
switch {
case retOnDesignator && n.Designation != nil:
return n
- case designatorList == nil && n.Designation != nil:
+ case designatorList == nil && !inList && n.Designation != nil:
designatorList = n.Designation.DesignatorList
fallthrough
case designatorList != nil:
d := designatorList.Designator
+ designatorList = designatorList.DesignatorList
switch d.Case {
case DesignatorIndex: // '[' ConstantExpression ']'
- switch x := d.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr).Value().(type) {
+ switch x := d.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) {
case Int64Value:
i = uintptr(x)
case Uint64Value:
@@ -491,6 +494,9 @@ loop:
default:
panic(todo("%v: %T", n.Position(), x))
}
+ if !inList && i > maxI {
+ maxI = i
+ }
case DesignatorField: // '.' IDENTIFIER
panic(todo("", n.Position(), d.Position()))
case DesignatorField2: // IDENTIFIER ':'
@@ -499,7 +505,7 @@ loop:
panic(todo(""))
}
- n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, designatorList.DesignatorList)
+ n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, designatorList, designatorList != nil)
designatorList = nil
if nestedDesignator {
retOnDesignator = true
@@ -513,7 +519,7 @@ loop:
if i > maxI {
maxI = i
}
- n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, nil)
+ n = n.Initializer.check(ctx, list, elem, sc, nil, off+i*esz, n, nil, inList)
i++
}
}
@@ -523,25 +529,26 @@ loop:
return n
}
-func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList) *InitializerList {
- // trc("InitializerList.checkStruct: %v: t %v, off %v, dl %v", n.Position(), t, off, designatorList != nil)
+func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList {
+ // trc("==== (A) %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList)
+ // defer trc("==== (Z) %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList)
t = t.underlyingType()
- // trc("==== struct %v: %v, off %v", n.Position(), t, off) //TODO-
+ // trc("%v: %v, off %v", n.Position(), t, off) //TODO-
nf := t.NumField()
i := []int{0}
var f Field
nestedDesignator := designatorList != nil
retOnDesignator := false
for n != nil {
- // trc("---- %v: t %v, dl %v", n.Position(), t, designatorList != nil)
switch {
case retOnDesignator && n.Designation != nil:
return n
- case designatorList == nil && n.Designation != nil:
+ case designatorList == nil && !inList && n.Designation != nil:
designatorList = n.Designation.DesignatorList
fallthrough
case designatorList != nil:
d := designatorList.Designator
+ designatorList = designatorList.DesignatorList
var nm StringID
switch d.Case {
case DesignatorIndex: // '[' ConstantExpression ']'
@@ -559,9 +566,9 @@ func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type
panic(todo("%v: t %v %q", d.Position(), t, nm))
}
+ t0 := t
switch {
case len(xa) != 1:
- panic(todo("%v: t %v %q, xa %v", d.Position(), t, nm, xa))
var f2 Field
var off2 uintptr
for len(xa) != 1 {
@@ -570,9 +577,12 @@ func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type
t = f2.Type()
xa = xa[1:]
}
- n = n.Initializer.check(ctx, list, t, sc, f, off+off2+f.Offset(), n, designatorList)
+ n = n.Initializer.check(ctx, list, t, sc, f, off+off2, n, designatorList, designatorList != nil)
+ if t.Kind() == Union {
+ t = t0
+ }
default:
- n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList.DesignatorList)
+ n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList, designatorList != nil)
}
designatorList = nil
if nestedDesignator {
@@ -594,7 +604,7 @@ func (n *InitializerList) checkStruct(ctx *context, list *[]*Initializer, t Type
f = t.FieldByIndex(i)
if f.Name() != 0 || !f.Type().IsBitFieldType() {
- n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil)
+ n = n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil, inList)
i[0]++
break
}
@@ -610,18 +620,20 @@ func spos(n Node) string {
return p.String()
}
-func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList) *InitializerList {
+func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) *InitializerList {
+ // trc("==== %v: t %v, off %v, dl %v, inList %v", n.Position(), t, off, designatorList != nil, inList)
t = t.underlyingType()
- // trc("==== union %v: %v, off %v", n.Position(), t, off) //TODO-
+ // trc("%v: %v, off %v", n.Position(), t, off) //TODO-
nf := t.NumField()
i := []int{0}
- for n != nil {
+ for pass := 0; n != nil; pass++ {
switch {
- case designatorList == nil && n.Designation != nil:
+ case designatorList == nil && !inList && n.Designation != nil:
designatorList = n.Designation.DesignatorList
fallthrough
case designatorList != nil:
d := designatorList.Designator
+ designatorList = designatorList.DesignatorList
var nm StringID
switch d.Case {
case DesignatorIndex: // '[' ConstantExpression ']'
@@ -639,6 +651,9 @@ func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type,
panic(todo("", d.Position()))
}
+ if !inList && pass == 0 {
+ n.Initializer.field0 = f
+ }
switch {
case len(xa) != 1:
var f2 Field
@@ -649,15 +664,14 @@ func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type,
t = f2.Type()
xa = xa[1:]
}
- next := n.Initializer.check(ctx, list, t, sc, f, off+off2+f.Offset(), n, designatorList)
+ next := n.Initializer.check(ctx, list, t, sc, f, off+off2+f.Offset(), n, designatorList, designatorList != nil)
if designatorList != nil && designatorList.DesignatorList != nil {
panic(todo("", n.Position(), d.Position()))
}
return next
default:
- designatorList = designatorList.DesignatorList
- next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList)
+ next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, designatorList, designatorList != nil)
if designatorList != nil && designatorList.DesignatorList != nil {
panic(todo("", n.Position(), d.Position()))
}
@@ -679,7 +693,7 @@ func (n *InitializerList) checkUnion(ctx *context, list *[]*Initializer, t Type,
f := t.FieldByIndex(i)
if f.Name() != 0 || !f.Type().IsBitFieldType() {
- next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil)
+ next := n.Initializer.check(ctx, list, f.Type(), sc, f, off+f.Offset(), n, nil, inList)
return next
}
}
@@ -714,7 +728,7 @@ func (n *Initializer) single() *Initializer {
}
// [0], 6.7.8 Initialization
-func (n *InitializerList) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList) {
+func (n *InitializerList) check(ctx *context, list *[]*Initializer, t Type, sc StorageClass, off uintptr, designatorList *DesignatorList, inList bool) {
switch t.Kind() {
case Array, Vector:
if n == nil { // {}
@@ -724,25 +738,25 @@ func (n *InitializerList) check(ctx *context, list *[]*Initializer, t Type, sc S
return
}
- n.checkArray(ctx, list, t, sc, off, designatorList)
+ n.checkArray(ctx, list, t, sc, off, designatorList, inList)
case Struct:
if n == nil { // {}
return
}
- n.checkStruct(ctx, list, t, sc, off, designatorList)
+ n.checkStruct(ctx, list, t, sc, off, designatorList, inList)
case Union:
if n == nil { // {}
return
}
- n.checkUnion(ctx, list, t, sc, off, designatorList)
+ n.checkUnion(ctx, list, t, sc, off, designatorList, inList)
default:
if n == nil || t == nil || t.Kind() == Invalid {
return
}
- n.Initializer.check(ctx, list, t, sc, nil, off, nil, designatorList)
+ n.Initializer.check(ctx, list, t, sc, nil, off, nil, designatorList, inList)
}
}
@@ -780,7 +794,7 @@ func setLHS(lhs map[*Declarator]struct{}, rhs Node) {
})
}
-func (n *AssignmentExpression) check(ctx *context) Operand {
+func (n *AssignmentExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -810,10 +824,10 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
n.Operand = noOperand
switch n.Case {
case AssignmentExpressionCond: // ConditionalExpression
- n.Operand = n.ConditionalExpression.check(ctx)
+ n.Operand = n.ConditionalExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ConditionalExpression.IsSideEffectsFree
case AssignmentExpressionAssign: // UnaryExpression '=' AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Declarator(); d != nil {
d.Read -= ctx.readDelta
}
@@ -830,11 +844,11 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
_ = r //TODO check assignability
n.Operand = l.(*lvalue).Operand
case AssignmentExpressionMul: // UnaryExpression "*=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -845,7 +859,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if l.Type().IsArithmeticType() {
op, _ := usualArithmeticConversions(ctx, n, l, r, true)
@@ -853,7 +867,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionDiv: // UnaryExpression "/=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -864,7 +878,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if l.Type().IsArithmeticType() {
op, _ := usualArithmeticConversions(ctx, n, l, r, true)
@@ -872,7 +886,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionMod: // UnaryExpression "%=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -883,7 +897,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if l.Type().IsArithmeticType() {
op, _ := usualArithmeticConversions(ctx, n, l, r, true)
@@ -891,7 +905,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionAdd: // UnaryExpression "+=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -902,7 +916,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
n.promote = n.UnaryExpression.Operand.Type()
if l.Type().IsArithmeticType() {
@@ -911,7 +925,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionSub: // UnaryExpression "-=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -922,7 +936,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
n.promote = n.UnaryExpression.Operand.Type()
if l.Type().IsArithmeticType() {
@@ -931,7 +945,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionLsh: // UnaryExpression "<<=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -942,7 +956,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() {
//TODO report error
@@ -952,7 +966,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
n.promote = r.integerPromotion(ctx, n).Type()
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: l.Type()}).integerPromotion(ctx, n)
case AssignmentExpressionRsh: // UnaryExpression ">>=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -963,7 +977,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() {
//TODO report error
@@ -973,7 +987,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
n.promote = r.integerPromotion(ctx, n).Type()
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: l.Type()}).integerPromotion(ctx, n)
case AssignmentExpressionAnd: // UnaryExpression "&=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -984,7 +998,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() {
//TODO report error
@@ -995,7 +1009,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
n.promote = op.Type()
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionXor: // UnaryExpression "^=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -1006,7 +1020,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() {
//TODO report error
@@ -1017,7 +1031,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
n.promote = op.Type()
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: l.Type()}
case AssignmentExpressionOr: // UnaryExpression "|=" AssignmentExpression
- l := n.UnaryExpression.check(ctx)
+ l := n.UnaryExpression.check(ctx, isAsmArg)
if d := n.UnaryExpression.Operand.Declarator(); d != nil {
d.SubjectOfAsgnOp = true
d.Read += ctx.readDelta
@@ -1028,7 +1042,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
break
}
- r := n.AssignmentExpression.check(ctx)
+ r := n.AssignmentExpression.check(ctx, isAsmArg)
//TODO check assignability
if !l.Type().IsIntegerType() || !r.Type().IsIntegerType() {
//TODO report error
@@ -1044,7 +1058,7 @@ func (n *AssignmentExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *UnaryExpression) check(ctx *context) Operand {
+func (n *UnaryExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -1052,10 +1066,10 @@ func (n *UnaryExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case UnaryExpressionPostfix: // PostfixExpression
- n.Operand = n.PostfixExpression.check(ctx, false)
+ n.Operand = n.PostfixExpression.check(ctx, false, isAsmArg)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree
case UnaryExpressionInc: // "++" UnaryExpression
- op := n.UnaryExpression.check(ctx)
+ op := n.UnaryExpression.check(ctx, isAsmArg)
if d := op.Declarator(); d != nil {
d.SubjectOfIncDec = true
d.Read += ctx.readDelta
@@ -1063,7 +1077,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()}
case UnaryExpressionDec: // "--" UnaryExpression
- op := n.UnaryExpression.check(ctx)
+ op := n.UnaryExpression.check(ctx, isAsmArg)
if d := op.Declarator(); d != nil {
d.SubjectOfIncDec = true
d.Read += ctx.readDelta
@@ -1103,7 +1117,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
n.Operand = op
case UnaryExpressionDeref: // '*' CastExpression
ctx.not(n, mIntConstExpr)
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
if x, ok := op.(*funcDesignator); ok {
n.Operand = x
@@ -1122,7 +1136,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: op.Type().Elem()}}
case UnaryExpressionPlus: // '+' CastExpression
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
if !op.Type().IsArithmeticType() {
//TODO report error
@@ -1134,7 +1148,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
}
n.Operand = op
case UnaryExpressionMinus: // '-' CastExpression
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
if op.Type().Kind() == Vector {
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()}
@@ -1154,7 +1168,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
}
n.Operand = op
case UnaryExpressionCpl: // '~' CastExpression
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
if op.Type().Kind() == Vector {
if !op.Type().Elem().IsIntegerType() {
@@ -1180,7 +1194,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
}
n.Operand = op
case UnaryExpressionNot: // '!' CastExpression
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
op2 := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)}
switch {
@@ -1203,7 +1217,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
ctx.readDelta = 0
}
ctx.push(ctx.mode &^ mIntConstExpr)
- op := n.UnaryExpression.check(ctx)
+ op := n.UnaryExpression.check(ctx, isAsmArg)
ctx.pop()
ctx.readDelta = rd
if op.Type().IsIncomplete() {
@@ -1223,7 +1237,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
if ctx.mode&mIntConstExpr != 0 {
ctx.mode |= mIntConstExprAnyCast
}
- t := n.TypeName.check(ctx, false, false)
+ t := n.TypeName.check(ctx, false, false, nil)
ctx.pop()
ctx.readDelta = rd
if t.IsIncomplete() {
@@ -1249,7 +1263,7 @@ func (n *UnaryExpression) check(ctx *context) Operand {
case UnaryExpressionAlignofExpr: // "_Alignof" UnaryExpression
n.IsSideEffectsFree = true
ctx.push(ctx.mode &^ mIntConstExpr)
- op := n.UnaryExpression.check(ctx)
+ op := n.UnaryExpression.check(ctx, isAsmArg)
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(op.Type().Align())}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token))
ctx.pop()
case UnaryExpressionAlignofType: // "_Alignof" '(' TypeName ')'
@@ -1258,17 +1272,17 @@ func (n *UnaryExpression) check(ctx *context) Operand {
if ctx.mode&mIntConstExpr != 0 {
ctx.mode |= mIntConstExprAnyCast
}
- t := n.TypeName.check(ctx, false, false)
+ t := n.TypeName.check(ctx, false, false, nil)
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(ULongLong), value: Uint64Value(t.Align())}).convertTo(ctx, n, sizeT(ctx, n.lexicalScope, n.Token))
ctx.pop()
case UnaryExpressionImag: // "__imag__" UnaryExpression
ctx.not(n, mIntConstExpr)
- n.UnaryExpression.check(ctx)
+ n.UnaryExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree
n.Operand = complexPart(ctx, n.UnaryExpression.Operand)
case UnaryExpressionReal: // "__real__" UnaryExpression
ctx.not(n, mIntConstExpr)
- n.UnaryExpression.check(ctx)
+ n.UnaryExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree
n.Operand = complexPart(ctx, n.UnaryExpression.Operand)
default:
@@ -1361,7 +1375,7 @@ func (n *UnaryExpression) addrOf(ctx *context) Operand {
case UnaryExpressionAddrof: // '&' CastExpression
panic(n.Position().String())
case UnaryExpressionDeref: // '*' CastExpression
- n.Operand = n.CastExpression.check(ctx)
+ n.Operand = n.CastExpression.check(ctx, false)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
case UnaryExpressionPlus: // '+' CastExpression
panic(n.Position().String())
@@ -1404,12 +1418,12 @@ func (n *PostfixExpression) addrOf(ctx *context) Operand {
n.Operand = n.PrimaryExpression.addrOf(ctx)
n.IsSideEffectsFree = n.PrimaryExpression.IsSideEffectsFree
case PostfixExpressionIndex: // PostfixExpression '[' Expression ']'
- pe := n.PostfixExpression.check(ctx, false)
+ pe := n.PostfixExpression.check(ctx, false, false)
if d := n.PostfixExpression.Declarator(); d != nil && d.Type().Kind() != Ptr {
setAddressTaken(n, d, "PostfixExpression '[' Expression ']'")
d.Read += ctx.readDelta
}
- e := n.Expression.check(ctx)
+ e := n.Expression.check(ctx, false)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree && n.Expression.IsSideEffectsFree
t := pe.Type().Decay()
if t.Kind() == Invalid {
@@ -1498,7 +1512,7 @@ func (n *PostfixExpression) addrOf(ctx *context) Operand {
n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ot, offset: op.Offset() + f.Offset()}, declarator: op.Declarator()}
}
case PostfixExpressionPSelect: // PostfixExpression "->" IDENTIFIER
- op := n.PostfixExpression.check(ctx, false)
+ op := n.PostfixExpression.check(ctx, false, false)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree
if d := n.PostfixExpression.Declarator(); d != nil {
d.Read += ctx.readDelta
@@ -1554,11 +1568,11 @@ func (n *PostfixExpression) addrOf(ctx *context) Operand {
if f := ctx.checkFn; f != nil {
f.CompositeLiterals = append(f.CompositeLiterals, n)
}
- t := n.TypeName.check(ctx, false, false)
+ t := n.TypeName.check(ctx, false, false, nil)
var v *InitializerValue
if n.InitializerList != nil {
n.InitializerList.isConst = true
- n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil)
+ n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil, false)
n.InitializerList.setConstZero()
v = &InitializerValue{typ: ctx.cfg.ABI.Ptr(n, t), initializer: n.InitializerList}
}
@@ -1611,7 +1625,7 @@ func (n *PrimaryExpression) addrOf(ctx *context) Operand {
switch n.Case {
case PrimaryExpressionIdent: // IDENTIFIER
n.IsSideEffectsFree = true
- n.check(ctx, false)
+ n.check(ctx, false, false)
if d := n.Operand.Declarator(); d != nil {
switch d.Type().Kind() {
case Function:
@@ -1920,12 +1934,12 @@ func (n *MultiplicativeExpression) addrOf(ctx *context) Operand {
return n.Operand
}
-func (n *TypeName) check(ctx *context, inUnion, isPacked bool) Type {
+func (n *TypeName) check(ctx *context, inUnion, isPacked bool, list *[]*TypeSpecifier) Type {
if n == nil {
return noType
}
- n.typ = n.SpecifierQualifierList.check(ctx, inUnion, isPacked)
+ n.typ = n.SpecifierQualifierList.check(ctx, inUnion, isPacked, list)
if n.AbstractDeclarator != nil {
n.typ = n.AbstractDeclarator.check(ctx, n.typ)
}
@@ -2127,13 +2141,16 @@ func (n *TypeQualifier) check(ctx *context, typ *typeBase) {
}
}
-func (n *SpecifierQualifierList) check(ctx *context, inUnion, isPacked bool) Type {
+func (n *SpecifierQualifierList) check(ctx *context, inUnion, isPacked bool, list *[]*TypeSpecifier) Type {
n0 := n
typ := &typeBase{}
for ; n != nil; n = n.SpecifierQualifierList {
switch n.Case {
case SpecifierQualifierListTypeSpec: // TypeSpecifier SpecifierQualifierList
n.TypeSpecifier.check(ctx, typ, inUnion)
+ if list != nil && n.TypeSpecifier.Case != TypeSpecifierAtomic {
+ *list = append(*list, n.TypeSpecifier)
+ }
case SpecifierQualifierListTypeQual: // TypeQualifier SpecifierQualifierList
n.TypeQualifier.check(ctx, typ)
case SpecifierQualifierListAlignSpec: // AlignmentSpecifier SpecifierQualifierList
@@ -2188,12 +2205,15 @@ func (n *TypeSpecifier) check(ctx *context, typ *typeBase, inUnion bool) {
case TypeSpecifierTypedefName: // TYPEDEFNAME
// nop
case TypeSpecifierTypeofExpr: // "typeof" '(' Expression ')'
- op := n.Expression.check(ctx)
+ op := n.Expression.check(ctx, false)
n.typ = op.Type()
case TypeSpecifierTypeofType: // "typeof" '(' TypeName ')'
- n.typ = n.TypeName.check(ctx, false, false)
+ n.typ = n.TypeName.check(ctx, false, false, nil)
case TypeSpecifierAtomic: // AtomicTypeSpecifier
- n.AtomicTypeSpecifier.check(ctx)
+ t := n.AtomicTypeSpecifier.check(ctx)
+ typ.kind = t.base().kind
+ typ.flags |= fAtomic
+ n.typ = typ
case
TypeSpecifierFract, // "_Fract"
TypeSpecifierSat, // "_Sat"
@@ -2204,12 +2224,12 @@ func (n *TypeSpecifier) check(ctx *context, typ *typeBase, inUnion bool) {
}
}
-func (n *AtomicTypeSpecifier) check(ctx *context) {
+func (n *AtomicTypeSpecifier) check(ctx *context) Type {
if n == nil {
- return
+ return nil
}
- n.TypeName.check(ctx, false, false)
+ return n.TypeName.check(ctx, false, false, &n.list)
}
func (n *EnumSpecifier) check(ctx *context) {
@@ -2371,7 +2391,7 @@ func (n *Enumerator) check(ctx *context, iota, min, max Value) (Value, Value, Va
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: iota}).normalize(ctx, n)
case EnumeratorExpr: // IDENTIFIER AttributeSpecifierList '=' ConstantExpression
n.AttributeSpecifierList.check(ctx, nil)
- n.Operand = n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr)
+ n.Operand = n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false)
iota = n.Operand.Value()
default:
panic(todo(""))
@@ -2448,13 +2468,13 @@ func (n *Enumerator) check(ctx *context, iota, min, max Value) (Value, Value, Va
return iota, min, max
}
-func (n *ConstantExpression) check(ctx *context, mode mode) Operand {
+func (n *ConstantExpression) check(ctx *context, mode mode, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
ctx.push(mode)
- n.Operand = n.ConditionalExpression.check(ctx)
+ n.Operand = n.ConditionalExpression.check(ctx, isAsmArg)
ctx.pop()
return n.Operand
}
@@ -2534,7 +2554,7 @@ func (n *StructDeclaration) check(ctx *context, inUnion, isPacked bool) (s []*fi
return nil
}
- typ := n.SpecifierQualifierList.check(ctx, inUnion, isPacked)
+ typ := n.SpecifierQualifierList.check(ctx, inUnion, isPacked, nil)
if n.StructDeclaratorList != nil {
return n.StructDeclaratorList.check(ctx, n.SpecifierQualifierList, typ, inUnion, isPacked)
}
@@ -2575,7 +2595,7 @@ func (n *StructDeclarator) check(ctx *context, td typeDescriptor, typ Type, inUn
sf.isBitField = true
sf.typ = &bitFieldType{Type: typ, field: sf}
sf.name = n.Declarator.Name()
- if op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr); op.Type().IsIntegerType() {
+ if op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false); op.Type().IsIntegerType() {
switch x := op.Value().(type) {
case Int64Value:
if x < 0 || x > 64 {
@@ -2617,7 +2637,7 @@ func (n *StructOrUnion) check(ctx *context) Kind {
}
}
-func (n *CastExpression) check(ctx *context) Operand {
+func (n *CastExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -2625,10 +2645,10 @@ func (n *CastExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case CastExpressionUnary: // UnaryExpression
- n.Operand = n.UnaryExpression.check(ctx)
+ n.Operand = n.UnaryExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.UnaryExpression.IsSideEffectsFree
case CastExpressionCast: // '(' TypeName ')' CastExpression
- t := n.TypeName.check(ctx, false, false)
+ t := n.TypeName.check(ctx, false, false, nil)
ctx.push(ctx.mode)
if m := ctx.mode; m&mIntConstExpr != 0 && m&mIntConstExprAnyCast == 0 {
if t := n.TypeName.Type(); t != nil && t.Kind() != Int {
@@ -2636,7 +2656,7 @@ func (n *CastExpression) check(ctx *context) Operand {
}
ctx.mode |= mIntConstExprFloat
}
- op := n.CastExpression.check(ctx)
+ op := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
ctx.pop()
n.Operand = op.convertTo(ctx, n, t)
@@ -2646,22 +2666,23 @@ func (n *CastExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
+func (n *PostfixExpression) check(ctx *context, implicitFunc, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
n.Operand = noOperand //TODO-
+out:
switch n.Case {
case PostfixExpressionPrimary: // PrimaryExpression
- n.Operand = n.PrimaryExpression.check(ctx, implicitFunc)
+ n.Operand = n.PrimaryExpression.check(ctx, implicitFunc, isAsmArg)
n.IsSideEffectsFree = n.PrimaryExpression.IsSideEffectsFree
case PostfixExpressionIndex: // PostfixExpression '[' Expression ']'
- pe := n.PostfixExpression.check(ctx, false)
+ pe := n.PostfixExpression.check(ctx, false, isAsmArg)
if d := pe.Declarator(); d != nil {
d.Read += ctx.readDelta
}
- e := n.Expression.check(ctx)
+ e := n.Expression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree && n.Expression.IsSideEffectsFree
t := pe.Type().Decay()
if t.Kind() == Invalid {
@@ -2705,7 +2726,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
ctx.errNode(n, "invalid index expression %v[%v]", pe.Type(), e.Type())
case PostfixExpressionCall: // PostfixExpression '(' ArgumentExpressionList ')'
- op := n.PostfixExpression.check(ctx, true)
+ op := n.PostfixExpression.check(ctx, true, isAsmArg)
Inspect(n.PostfixExpression, func(n Node, enter bool) bool {
if !enter {
return true
@@ -2718,7 +2739,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
}
return true
})
- args := n.ArgumentExpressionList.check(ctx, n.PostfixExpression.Declarator())
+ args := n.ArgumentExpressionList.check(ctx, n.PostfixExpression.Declarator(), isAsmArg)
switch op.Declarator().Name() {
case idBuiltinConstantPImpl:
if len(args) < 2 {
@@ -2731,10 +2752,19 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: v}
default:
+ switch n.PostfixExpression.Operand.Value().(type) {
+ case StringValue, WideStringValue:
+ if isAsmArg {
+ // asm("foo": "bar" (a))
+ // ^
+ break out
+ }
+ }
+
n.Operand = n.checkCall(ctx, n, op.Type(), args, n.ArgumentExpressionList)
}
case PostfixExpressionSelect: // PostfixExpression '.' IDENTIFIER
- op := n.PostfixExpression.check(ctx, false)
+ op := n.PostfixExpression.check(ctx, false, isAsmArg)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree
if d := op.Declarator(); d != nil {
d.Read += ctx.readDelta
@@ -2762,7 +2792,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ft, offset: op.Offset() + f.Offset()}}
case PostfixExpressionPSelect: // PostfixExpression "->" IDENTIFIER
- op := n.PostfixExpression.check(ctx, false)
+ op := n.PostfixExpression.check(ctx, false, isAsmArg)
n.IsSideEffectsFree = n.PostfixExpression.IsSideEffectsFree
if d := op.Declarator(); d != nil {
d.Read += ctx.readDelta
@@ -2792,7 +2822,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
}
n.Operand = &lvalue{Operand: &operand{abi: &ctx.cfg.ABI, typ: ft}}
case PostfixExpressionInc: // PostfixExpression "++"
- op := n.PostfixExpression.check(ctx, false)
+ op := n.PostfixExpression.check(ctx, false, isAsmArg)
if d := op.Declarator(); d != nil {
d.SubjectOfIncDec = true
d.Read += ctx.readDelta
@@ -2800,7 +2830,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
}
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: op.Type()}
case PostfixExpressionDec: // PostfixExpression "--"
- op := n.PostfixExpression.check(ctx, false)
+ op := n.PostfixExpression.check(ctx, false, isAsmArg)
if d := op.Declarator(); d != nil {
d.SubjectOfIncDec = true
d.Read += ctx.readDelta
@@ -2812,18 +2842,18 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
if f := ctx.checkFn; f != nil {
f.CompositeLiterals = append(f.CompositeLiterals, n)
}
- t := n.TypeName.check(ctx, false, false)
+ t := n.TypeName.check(ctx, false, false, nil)
var v *InitializerValue
if n.InitializerList != nil {
- n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil)
+ n.InitializerList.check(ctx, &n.InitializerList.list, t, Automatic, 0, nil, false)
n.InitializerList.setConstZero()
v = &InitializerValue{typ: t, initializer: n.InitializerList}
}
n.Operand = &lvalue{Operand: (&operand{abi: &ctx.cfg.ABI, typ: t, value: v}).normalize(ctx, n)}
case PostfixExpressionTypeCmp: // "__builtin_types_compatible_p" '(' TypeName ',' TypeName ')'
n.IsSideEffectsFree = true
- t1 := n.TypeName.check(ctx, false, false)
- t2 := n.TypeName2.check(ctx, false, false)
+ t1 := n.TypeName.check(ctx, false, false, nil)
+ t2 := n.TypeName2.check(ctx, false, false, nil)
v := 0
switch {
case t1.IsArithmeticType() && t2.IsArithmeticType():
@@ -2836,7 +2866,7 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int), value: Int64Value(v)}
case PostfixExpressionChooseExpr: // "__builtin_choose_expr" '(' ConstantExpression ',' AssignmentExpression ',' AssignmentExpression ')'
n.Operand = noOperand
- expr1 := n.AssignmentExpression.check(ctx)
+ expr1 := n.AssignmentExpression.check(ctx, isAsmArg)
if expr1 == nil {
ctx.errNode(n, "first argument of __builtin_choose_expr must be a constant expression")
break
@@ -2849,10 +2879,10 @@ func (n *PostfixExpression) check(ctx *context, implicitFunc bool) Operand {
switch {
case expr1.IsNonZero():
- n.Operand = n.AssignmentExpression2.check(ctx)
+ n.Operand = n.AssignmentExpression2.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AssignmentExpression2.IsSideEffectsFree
default:
- n.Operand = n.AssignmentExpression3.check(ctx)
+ n.Operand = n.AssignmentExpression3.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AssignmentExpression3.IsSideEffectsFree
}
default:
@@ -2924,9 +2954,10 @@ func (n *PostfixExpression) checkCall(ctx *context, nd Node, f Type, args []Oper
break
}
- fallthrough
+ ctx.errNode(nd, "expected function pointer type: %v, %v", f, f.Kind())
+ return r
default:
- //TODO report error
+ ctx.errNode(nd, "expected function type: %v, %v", f, f.Kind())
return r
}
@@ -2970,9 +3001,9 @@ func defaultArgumentPromotion(ctx *context, n Node, op Operand) Operand {
return op
}
-func (n *ArgumentExpressionList) check(ctx *context, f *Declarator) (r []Operand) {
+func (n *ArgumentExpressionList) check(ctx *context, f *Declarator, isAsmArg bool) (r []Operand) {
for ; n != nil; n = n.ArgumentExpressionList {
- op := n.AssignmentExpression.check(ctx)
+ op := n.AssignmentExpression.check(ctx, isAsmArg)
if op.Type() == nil {
ctx.errNode(n, "operand has usupported, invalid or incomplete type")
op = noOperand
@@ -2998,7 +3029,7 @@ func (n *ArgumentExpressionList) check(ctx *context, f *Declarator) (r []Operand
return r
}
-func (n *Expression) check(ctx *context) Operand {
+func (n *Expression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3006,11 +3037,11 @@ func (n *Expression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case ExpressionAssign: // AssignmentExpression
- n.Operand = n.AssignmentExpression.check(ctx)
+ n.Operand = n.AssignmentExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AssignmentExpression.IsSideEffectsFree
case ExpressionComma: // Expression ',' AssignmentExpression
- op := n.Expression.check(ctx)
- n.Operand = n.AssignmentExpression.check(ctx)
+ op := n.Expression.check(ctx, isAsmArg)
+ n.Operand = n.AssignmentExpression.check(ctx, isAsmArg)
if !op.IsConst() && n.Operand.IsConst() {
n.Operand = &operand{abi: &ctx.cfg.ABI, typ: n.Operand.Type()}
}
@@ -3021,7 +3052,7 @@ func (n *Expression) check(ctx *context) Operand {
return n.Operand
}
-func (n *PrimaryExpression) check(ctx *context, implicitFunc bool) Operand {
+func (n *PrimaryExpression) check(ctx *context, implicitFunc, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3101,7 +3132,7 @@ func (n *PrimaryExpression) check(ctx *context, implicitFunc bool) Operand {
arr.setLen(sz)
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: arr, value: WideStringValue(n.Token.Value)}).normalize(ctx, n)
case PrimaryExpressionExpr: // '(' Expression ')'
- n.Operand = n.Expression.check(ctx)
+ n.Operand = n.Expression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.Expression.IsSideEffectsFree
case PrimaryExpressionStmt: // '(' CompoundStatement ')'
//TODO IsSideEffectsFree
@@ -3192,6 +3223,7 @@ func (n *PrimaryExpression) checkIdentifier(ctx *context, implicitFunc bool) Ope
Token: Token{Value: nm},
},
},
+ implicit: true,
}
ed := &ExternalDeclaration{
Case: ExternalDeclarationDecl,
@@ -3483,7 +3515,7 @@ func intConst(ctx *context, n Node, s string, val uint64, list ...Kind) Operand
return nil
}
-func (n *ConditionalExpression) check(ctx *context) Operand {
+func (n *ConditionalExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3491,18 +3523,18 @@ func (n *ConditionalExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case ConditionalExpressionLOr: // LogicalOrExpression
- n.Operand = n.LogicalOrExpression.check(ctx)
+ n.Operand = n.LogicalOrExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree
case ConditionalExpressionCond: // LogicalOrExpression '?' Expression ':' ConditionalExpression
- op := n.LogicalOrExpression.check(ctx)
+ op := n.LogicalOrExpression.check(ctx, isAsmArg)
// The first operand shall have scalar type.
if !op.Type().Decay().IsScalarType() {
//TODO report error
break
}
- a := n.Expression.check(ctx)
- b := n.ConditionalExpression.check(ctx)
+ a := n.Expression.check(ctx, isAsmArg)
+ b := n.ConditionalExpression.check(ctx, isAsmArg)
at := a.Type().Decay()
bt := b.Type().Decay()
@@ -3544,14 +3576,6 @@ func (n *ConditionalExpression) check(ctx *context) Operand {
// is the type of the result.
op, _ := usualArithmeticConversions(ctx, n, a, b, true)
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: op.Type(), value: val}).normalize(ctx, n)
- // — both operands are pointers to qualified or unqualified versions of compatible types;
- case at.Kind() == Ptr && bt.Kind() == Ptr:
- //TODO check compatible
- //TODO if !at.isCompatibleIgnoreQualifiers(bt) {
- //TODO trc("%v: XXXX %v ? %v", n.Token2.Position(), at, bt)
- //TODO ctx.assignmentCompatibilityErrorCond(&n.Token2, at, bt)
- //TODO }
- n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: n.Expression.Operand.Type(), value: val}).normalize(ctx, n)
// — both operands have void type;
case a.Type().Kind() == Void && b.Type().Kind() == Void:
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n)
@@ -3560,6 +3584,14 @@ func (n *ConditionalExpression) check(ctx *context) Operand {
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n)
case (b.Type().Kind() == Ptr || b.Type().Kind() == Function) && a.IsZero():
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: b.Type(), value: val}).normalize(ctx, n)
+ // — both operands are pointers to qualified or unqualified versions of compatible types;
+ case at.Kind() == Ptr && bt.Kind() == Ptr:
+ //TODO check compatible
+ //TODO if !at.isCompatibleIgnoreQualifiers(bt) {
+ //TODO trc("%v: XXXX %v ? %v", n.Token2.Position(), at, bt)
+ //TODO ctx.assignmentCompatibilityErrorCond(&n.Token2, at, bt)
+ //TODO }
+ n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: n.Expression.Operand.Type(), value: val}).normalize(ctx, n)
case a.Type().Kind() == Ptr && a.Type().Elem().Kind() == Function && b.Type().Kind() == Function:
//TODO check compatible
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: val}).normalize(ctx, n)
@@ -3579,7 +3611,7 @@ func (n *ConditionalExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *LogicalOrExpression) check(ctx *context) Operand {
+func (n *LogicalOrExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3587,11 +3619,11 @@ func (n *LogicalOrExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case LogicalOrExpressionLAnd: // LogicalAndExpression
- n.Operand = n.LogicalAndExpression.check(ctx)
+ n.Operand = n.LogicalAndExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.LogicalAndExpression.IsSideEffectsFree
case LogicalOrExpressionLOr: // LogicalOrExpression "||" LogicalAndExpression
- lop := n.LogicalOrExpression.check(ctx)
- rop := n.LogicalAndExpression.check(ctx)
+ lop := n.LogicalOrExpression.check(ctx, isAsmArg)
+ rop := n.LogicalAndExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.LogicalOrExpression.IsSideEffectsFree && n.LogicalAndExpression.IsSideEffectsFree ||
lop.Value() != nil && lop.IsNonZero() && n.LogicalOrExpression.IsSideEffectsFree
var v Value
@@ -3610,7 +3642,7 @@ func (n *LogicalOrExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *LogicalAndExpression) check(ctx *context) Operand {
+func (n *LogicalAndExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3618,11 +3650,11 @@ func (n *LogicalAndExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case LogicalAndExpressionOr: // InclusiveOrExpression
- n.Operand = n.InclusiveOrExpression.check(ctx)
+ n.Operand = n.InclusiveOrExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.InclusiveOrExpression.IsSideEffectsFree
case LogicalAndExpressionLAnd: // LogicalAndExpression "&&" InclusiveOrExpression
- lop := n.LogicalAndExpression.check(ctx)
- rop := n.InclusiveOrExpression.check(ctx)
+ lop := n.LogicalAndExpression.check(ctx, isAsmArg)
+ rop := n.InclusiveOrExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.LogicalAndExpression.IsSideEffectsFree && n.InclusiveOrExpression.IsSideEffectsFree ||
lop.Value() != nil && lop.IsZero() && n.LogicalAndExpression.IsSideEffectsFree
var v Value
@@ -3641,7 +3673,7 @@ func (n *LogicalAndExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *InclusiveOrExpression) check(ctx *context) Operand {
+func (n *InclusiveOrExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3649,11 +3681,11 @@ func (n *InclusiveOrExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case InclusiveOrExpressionXor: // ExclusiveOrExpression
- n.Operand = n.ExclusiveOrExpression.check(ctx)
+ n.Operand = n.ExclusiveOrExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ExclusiveOrExpression.IsSideEffectsFree
case InclusiveOrExpressionOr: // InclusiveOrExpression '|' ExclusiveOrExpression
- a := n.InclusiveOrExpression.check(ctx)
- b := n.ExclusiveOrExpression.check(ctx)
+ a := n.InclusiveOrExpression.check(ctx, isAsmArg)
+ b := n.ExclusiveOrExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.InclusiveOrExpression.IsSideEffectsFree && n.ExclusiveOrExpression.IsSideEffectsFree
n.promote = noType
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
@@ -3699,7 +3731,7 @@ func checkBinaryVectorIntegerArtithmetic(ctx *context, n Node, a, b Operand) Ope
return &operand{abi: &ctx.cfg.ABI, typ: rt}
}
-func (n *ExclusiveOrExpression) check(ctx *context) Operand {
+func (n *ExclusiveOrExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3707,11 +3739,11 @@ func (n *ExclusiveOrExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case ExclusiveOrExpressionAnd: // AndExpression
- n.Operand = n.AndExpression.check(ctx)
+ n.Operand = n.AndExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AndExpression.IsSideEffectsFree
case ExclusiveOrExpressionXor: // ExclusiveOrExpression '^' AndExpression
- a := n.ExclusiveOrExpression.check(ctx)
- b := n.AndExpression.check(ctx)
+ a := n.ExclusiveOrExpression.check(ctx, isAsmArg)
+ b := n.AndExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ExclusiveOrExpression.IsSideEffectsFree && n.AndExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b)
@@ -3737,7 +3769,7 @@ func (n *ExclusiveOrExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *AndExpression) check(ctx *context) Operand {
+func (n *AndExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3745,11 +3777,11 @@ func (n *AndExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case AndExpressionEq: // EqualityExpression
- n.Operand = n.EqualityExpression.check(ctx)
+ n.Operand = n.EqualityExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.EqualityExpression.IsSideEffectsFree
case AndExpressionAnd: // AndExpression '&' EqualityExpression
- a := n.AndExpression.check(ctx)
- b := n.EqualityExpression.check(ctx)
+ a := n.AndExpression.check(ctx, isAsmArg)
+ b := n.EqualityExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AndExpression.IsSideEffectsFree && n.EqualityExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b)
@@ -3775,14 +3807,14 @@ func (n *AndExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *EqualityExpression) check(ctx *context) Operand {
+func (n *EqualityExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
switch n.Case {
case EqualityExpressionRel: // RelationalExpression
- n.Operand = n.RelationalExpression.check(ctx)
+ n.Operand = n.RelationalExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.RelationalExpression.IsSideEffectsFree
case
EqualityExpressionEq, // EqualityExpression "==" RelationalExpression
@@ -3790,8 +3822,8 @@ func (n *EqualityExpression) check(ctx *context) Operand {
op := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)}
n.Operand = op
- lo := n.EqualityExpression.check(ctx)
- ro := n.RelationalExpression.check(ctx)
+ lo := n.EqualityExpression.check(ctx, isAsmArg)
+ ro := n.RelationalExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.EqualityExpression.IsSideEffectsFree && n.RelationalExpression.IsSideEffectsFree
lt := lo.Type().Decay()
rt := ro.Type().Decay()
@@ -3852,7 +3884,7 @@ func checkVectorComparison(ctx *context, n Node, a, b Type) (r Operand) {
return r
}
-func (n *RelationalExpression) check(ctx *context) Operand {
+func (n *RelationalExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3860,7 +3892,7 @@ func (n *RelationalExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case RelationalExpressionShift: // ShiftExpression
- n.Operand = n.ShiftExpression.check(ctx)
+ n.Operand = n.ShiftExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree
case
RelationalExpressionLt, // RelationalExpression '<' ShiftExpression
@@ -3871,8 +3903,8 @@ func (n *RelationalExpression) check(ctx *context) Operand {
n.promote = noType
op := &operand{abi: &ctx.cfg.ABI, typ: ctx.cfg.ABI.Type(Int)}
n.Operand = op
- lo := n.RelationalExpression.check(ctx)
- ro := n.ShiftExpression.check(ctx)
+ lo := n.RelationalExpression.check(ctx, isAsmArg)
+ ro := n.ShiftExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.RelationalExpression.IsSideEffectsFree && n.ShiftExpression.IsSideEffectsFree
if lo.Type().Kind() == Vector && ro.Type().Kind() == Vector {
n.Operand = checkVectorComparison(ctx, n, lo.Type(), ro.Type())
@@ -3926,7 +3958,7 @@ func (n *RelationalExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *ShiftExpression) check(ctx *context) Operand {
+func (n *ShiftExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3934,11 +3966,11 @@ func (n *ShiftExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case ShiftExpressionAdd: // AdditiveExpression
- n.Operand = n.AdditiveExpression.check(ctx)
+ n.Operand = n.AdditiveExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree
case ShiftExpressionLsh: // ShiftExpression "<<" AdditiveExpression
- a := n.ShiftExpression.check(ctx)
- b := n.AdditiveExpression.check(ctx)
+ a := n.ShiftExpression.check(ctx, isAsmArg)
+ b := n.AdditiveExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree && n.AdditiveExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b)
@@ -3960,8 +3992,8 @@ func (n *ShiftExpression) check(ctx *context) Operand {
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().lsh(b.Value())}).normalize(ctx, n)
case ShiftExpressionRsh: // ShiftExpression ">>" AdditiveExpression
- a := n.ShiftExpression.check(ctx)
- b := n.AdditiveExpression.check(ctx)
+ a := n.ShiftExpression.check(ctx, isAsmArg)
+ b := n.AdditiveExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.ShiftExpression.IsSideEffectsFree && n.AdditiveExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorIntegerArtithmetic(ctx, n, a, b)
@@ -3988,7 +4020,7 @@ func (n *ShiftExpression) check(ctx *context) Operand {
return n.Operand
}
-func (n *AdditiveExpression) check(ctx *context) Operand {
+func (n *AdditiveExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -3996,12 +4028,12 @@ func (n *AdditiveExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case AdditiveExpressionMul: // MultiplicativeExpression
- n.Operand = n.MultiplicativeExpression.check(ctx)
+ n.Operand = n.MultiplicativeExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree
case AdditiveExpressionAdd: // AdditiveExpression '+' MultiplicativeExpression
n.promote = noType
- a := n.AdditiveExpression.check(ctx)
- b := n.MultiplicativeExpression.check(ctx)
+ a := n.AdditiveExpression.check(ctx, isAsmArg)
+ b := n.MultiplicativeExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree && n.MultiplicativeExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b)
@@ -4054,8 +4086,8 @@ func (n *AdditiveExpression) check(ctx *context) Operand {
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().add(b.Value())}).normalize(ctx, n)
case AdditiveExpressionSub: // AdditiveExpression '-' MultiplicativeExpression
n.promote = noType
- a := n.AdditiveExpression.check(ctx)
- b := n.MultiplicativeExpression.check(ctx)
+ a := n.AdditiveExpression.check(ctx, isAsmArg)
+ b := n.MultiplicativeExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.AdditiveExpression.IsSideEffectsFree && n.MultiplicativeExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b)
@@ -4147,7 +4179,7 @@ func ptrdiffT(ctx *context, s Scope, tok Token) Type {
return t
}
-func (n *MultiplicativeExpression) check(ctx *context) Operand {
+func (n *MultiplicativeExpression) check(ctx *context, isAsmArg bool) Operand {
if n == nil {
return noOperand
}
@@ -4155,11 +4187,11 @@ func (n *MultiplicativeExpression) check(ctx *context) Operand {
n.Operand = noOperand //TODO-
switch n.Case {
case MultiplicativeExpressionCast: // CastExpression
- n.Operand = n.CastExpression.check(ctx)
+ n.Operand = n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.CastExpression.IsSideEffectsFree
case MultiplicativeExpressionMul: // MultiplicativeExpression '*' CastExpression
- a := n.MultiplicativeExpression.check(ctx)
- b := n.CastExpression.check(ctx)
+ a := n.MultiplicativeExpression.check(ctx, isAsmArg)
+ b := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b)
@@ -4179,8 +4211,8 @@ func (n *MultiplicativeExpression) check(ctx *context) Operand {
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().mul(b.Value())}).normalize(ctx, n)
case MultiplicativeExpressionDiv: // MultiplicativeExpression '/' CastExpression
- a := n.MultiplicativeExpression.check(ctx)
- b := n.CastExpression.check(ctx)
+ a := n.MultiplicativeExpression.check(ctx, isAsmArg)
+ b := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b)
@@ -4200,8 +4232,8 @@ func (n *MultiplicativeExpression) check(ctx *context) Operand {
n.Operand = (&operand{abi: &ctx.cfg.ABI, typ: a.Type(), value: a.Value().div(b.Value())}).normalize(ctx, n)
case MultiplicativeExpressionMod: // MultiplicativeExpression '%' CastExpression
- a := n.MultiplicativeExpression.check(ctx)
- b := n.CastExpression.check(ctx)
+ a := n.MultiplicativeExpression.check(ctx, isAsmArg)
+ b := n.CastExpression.check(ctx, isAsmArg)
n.IsSideEffectsFree = n.MultiplicativeExpression.IsSideEffectsFree && n.CastExpression.IsSideEffectsFree
if a.Type().Kind() == Vector || b.Type().Kind() == Vector {
n.Operand = checkBinaryVectorArtithmetic(ctx, n, a, b)
@@ -4456,7 +4488,7 @@ func checkArray(ctx *context, n Node, typ Type, expr *AssignmentExpression, expr
case expr != nil && noExpr:
panic(todo(""))
case expr != nil:
- op := expr.check(ctx)
+ op := expr.check(ctx, false)
if op.Type().Kind() == Invalid {
return noType
}
@@ -4532,7 +4564,7 @@ func (n *AsmExpressionList) check(ctx *context) {
for ; n != nil; n = n.AsmExpressionList {
n.AsmIndex.check(ctx)
- n.AssignmentExpression.check(ctx)
+ n.AssignmentExpression.check(ctx, true)
}
}
@@ -4541,7 +4573,7 @@ func (n *AsmIndex) check(ctx *context) {
return
}
- n.Expression.check(ctx)
+ n.Expression.check(ctx, true)
}
func (n *AsmQualifierList) check(ctx *context) {
@@ -4603,7 +4635,7 @@ func (n *AttributeValue) check(ctx *context, t *typeBase) {
v := ctx.cfg.ignoreErrors
ctx.cfg.ignoreErrors = true
defer func() { ctx.cfg.ignoreErrors = v }()
- n.ExpressionList.check(ctx)
+ n.ExpressionList.check(ctx, false)
if n.Token.Value == idAligned && n.ExpressionList != nil && t != nil {
switch x := n.ExpressionList.AssignmentExpression.Operand.Value().(type) {
case Int64Value:
@@ -4619,9 +4651,9 @@ func (n *AttributeValue) check(ctx *context, t *typeBase) {
}
}
-func (n *ExpressionList) check(ctx *context) {
+func (n *ExpressionList) check(ctx *context, isAsmArg bool) {
for ; n != nil; n = n.ExpressionList {
- n.AssignmentExpression.check(ctx)
+ n.AssignmentExpression.check(ctx, isAsmArg)
}
}
@@ -4668,10 +4700,10 @@ func (n *AlignmentSpecifier) check(ctx *context) {
switch n.Case {
case AlignmentSpecifierAlignasType: // "_Alignas" '(' TypeName ')'
- n.TypeName.check(ctx, false, false)
+ n.TypeName.check(ctx, false, false, nil)
//TODO actually set the alignment
case AlignmentSpecifierAlignasExpr: // "_Alignas" '(' ConstantExpression ')'
- n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr)
+ n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false)
//TODO actually set the alignment
default:
panic(todo(""))
@@ -4913,7 +4945,7 @@ func (n *JumpStatement) check(ctx *context) {
}
ctx.checkFn.Gotos[n.Token2.Value] = n
case JumpStatementGotoExpr: // "goto" '*' Expression ';'
- n.Expression.check(ctx)
+ n.Expression.check(ctx, false)
//TODO
case JumpStatementContinue: // "continue" ';'
n.context = ctx.breakCtx
@@ -4929,7 +4961,7 @@ func (n *JumpStatement) check(ctx *context) {
//TODO
case JumpStatementReturn: // "return" Expression ';'
n.context = ctx.breakCtx
- op := n.Expression.check(ctx)
+ op := n.Expression.check(ctx, false)
if op.Type().IsComplexType() {
ctx.checkFn.ReturnComplexExpr = append(ctx.checkFn.ReturnComplexExpr, n.Expression)
}
@@ -4950,7 +4982,7 @@ func (n *IterationStatement) check(ctx *context) {
switch n.Case {
case IterationStatementWhile: // "while" '(' Expression ')' Statement
- n.Expression.check(ctx)
+ n.Expression.check(ctx, false)
ctx.breaks++
ctx.continues++
n.Statement.check(ctx)
@@ -4962,11 +4994,11 @@ func (n *IterationStatement) check(ctx *context) {
n.Statement.check(ctx)
ctx.breaks--
ctx.continues--
- n.Expression.check(ctx)
+ n.Expression.check(ctx, false)
case IterationStatementFor: // "for" '(' Expression ';' Expression ';' Expression ')' Statement
- n.Expression.check(ctx)
- n.Expression2.check(ctx)
- n.Expression3.check(ctx)
+ n.Expression.check(ctx, false)
+ n.Expression2.check(ctx, false)
+ n.Expression3.check(ctx, false)
ctx.breaks++
ctx.continues++
n.Statement.check(ctx)
@@ -4974,8 +5006,8 @@ func (n *IterationStatement) check(ctx *context) {
ctx.continues--
case IterationStatementForDecl: // "for" '(' Declaration Expression ';' Expression ')' Statement
n.Declaration.check(ctx, false)
- n.Expression.check(ctx)
- n.Expression2.check(ctx)
+ n.Expression.check(ctx, false)
+ n.Expression2.check(ctx, false)
ctx.breaks++
ctx.continues++
n.Statement.check(ctx)
@@ -4993,10 +5025,10 @@ func (n *SelectionStatement) check(ctx *context) {
switch n.Case {
case SelectionStatementIf: // "if" '(' Expression ')' Statement
- n.Expression.check(ctx)
+ n.Expression.check(ctx, false)
n.Statement.check(ctx)
case SelectionStatementIfElse: // "if" '(' Expression ')' Statement "else" Statement
- n.Expression.check(ctx)
+ n.Expression.check(ctx, false)
n.Statement.check(ctx)
n.Statement2.check(ctx)
if !n.Expression.Operand.Type().IsScalarType() {
@@ -5013,7 +5045,7 @@ func (n *SelectionStatement) check(ctx *context) {
defer func() { ctx.breakCtx = sv }()
- op := n.Expression.check(ctx)
+ op := n.Expression.check(ctx, false)
n.promote = op.integerPromotion(ctx, n).Type()
cp := ctx.casePromote
ctx.casePromote = n.promote
@@ -5038,7 +5070,7 @@ func (n *ExpressionStatement) check(ctx *context) Operand {
}
n.AttributeSpecifierList.check(ctx, nil)
- return n.Expression.check(ctx)
+ return n.Expression.check(ctx, false)
}
func (n *LabeledStatement) check(ctx *context) {
@@ -5063,7 +5095,7 @@ func (n *LabeledStatement) check(ctx *context) {
break
}
- switch op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr); op.Value().(type) {
+ switch op := n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false); op.Value().(type) {
case Int64Value, Uint64Value:
if t := ctx.casePromote; t.Kind() != Invalid {
n.ConstantExpression.Operand = op.convertTo(ctx, n, t)
@@ -5082,13 +5114,13 @@ func (n *LabeledStatement) check(ctx *context) {
break
}
- switch n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr).Value().(type) {
+ switch n.ConstantExpression.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) {
case Int64Value, Uint64Value:
// ok
default:
//TODO report error
}
- switch n.ConstantExpression2.check(ctx, ctx.mode|mIntConstExpr).Value().(type) {
+ switch n.ConstantExpression2.check(ctx, ctx.mode|mIntConstExpr, false).Value().(type) {
case Int64Value, Uint64Value:
// ok
default:
@@ -5121,3 +5153,114 @@ func setAddressTaken(n Node, d *Declarator, s string) {
// n.Position(), d.Name(), d.Type(), d.Type().Kind(), d.Type().Size(), d.Position(), s,
// ) //TODO-
}
+
+// Dump returns a debug form of n.
+func (n *Initializer) Dump() string {
+ var b strings.Builder
+ f := strutil.IndentFormatter(&b, "\t")
+ n.dump(f)
+ return b.String()
+}
+
+func pos(n Node) (r token.Position) {
+ if n == nil {
+ return r
+ }
+
+ r = token.Position(n.Position())
+ if r.IsValid() {
+ r.Filename = filepath.Base(r.Filename)
+ }
+ return r
+}
+
+func (n *Initializer) dump(f strutil.Formatter) {
+ list := n.List()
+ if len(list) != 0 {
+ for i, v := range list {
+ f.Format("Initializer.List() #%d/%d: %v: off %v type %v", i, len(list), pos(v), v.Offset, v.Type())
+ if fld := v.FirstDesignatorField(); fld != nil {
+ f.Format(" [FirstDesignatorField %q]", fld.Name())
+ }
+ f.Format("\n")
+ }
+ }
+ if f0 := n.FirstDesignatorField(); f0 != nil {
+ f.Format("[FirstDesignatorField: %q, index %v, off %v, type %v] ", f0.Name(), f0.Index(), n.Offset, n.Type().Alias())
+ }
+ switch n.Case {
+ case InitializerExpr: // AssignmentExpression
+ if op := n.AssignmentExpression.Operand; op != nil {
+ n.isConst = op.IsConst()
+ n.isZero = op.IsZero()
+ }
+ var t Type
+ if n.AssignmentExpression != nil && n.AssignmentExpression.Operand != nil {
+ t = n.AssignmentExpression.Operand.Type()
+ }
+ f.Format("%v: %T@%[2]p, .Case %v, off %v, type %v\n", pos(n), n, n.Case, n.Offset, t.Alias())
+ case InitializerInitList: // '{' InitializerList ',' '}'
+ n.InitializerList.dump(f)
+ default:
+ panic(todo("%v:", n.Position()))
+ }
+}
+
+// Dump returns a debug form of n.
+func (n *InitializerList) Dump() string {
+ var b strings.Builder
+ f := strutil.IndentFormatter(&b, "\t")
+ n.dump(f)
+ return b.String()
+}
+
+func (n *InitializerList) dump(f strutil.Formatter) {
+ if n == nil {
+ f.Format("<nil>")
+ return
+ }
+
+ f.Format("%v: %T@%[2]p, len(.List()) %v {%i\n", pos(n), n, len(n.List()))
+ list := n.List()
+ for ; n != nil; n = n.InitializerList {
+ n.Designation.dump(f)
+ n.Initializer.dump(f)
+ }
+ for i, v := range list {
+ f.Format("InitializerList.List() #%d/%d:", i, len(list))
+ v.dump(f)
+ }
+ f.Format("%u}\n")
+}
+
+func (n *Designation) dump(f strutil.Formatter) {
+ if n == nil {
+ return
+ }
+
+ cnt := 0
+ designatorField2 := false
+ for n := n.DesignatorList; n != nil; n = n.DesignatorList {
+ n.Designator.dump(f)
+ if n.Designator.Case == DesignatorField2 {
+ designatorField2 = true
+ }
+ cnt++
+ }
+ if cnt > 1 || !designatorField2 {
+ f.Format(" = ")
+ }
+}
+
+func (n *Designator) dump(f strutil.Formatter) {
+ switch n.Case {
+ case DesignatorIndex: // '[' ConstantExpression ']'
+ f.Format("[%v]", n.ConstantExpression.Operand.Value())
+ case DesignatorField: // '.' IDENTIFIER
+ f.Format(".%s", n.Token2.Value)
+ case DesignatorField2: // IDENTIFIER ':'
+ f.Format("%s:", n.Token.Value)
+ default:
+ panic(todo(""))
+ }
+}
diff --git a/vendor/modernc.org/cc/v3/cpp.go b/vendor/modernc.org/cc/v3/cpp.go
index 44d7ed7de..4b7f19983 100644
--- a/vendor/modernc.org/cc/v3/cpp.go
+++ b/vendor/modernc.org/cc/v3/cpp.go
@@ -7,6 +7,7 @@ package cc // import "modernc.org/cc/v3"
import (
"bytes"
"fmt"
+ gotoken "go/token"
"math"
"os"
"path/filepath"
@@ -2182,6 +2183,8 @@ func decodeEscapeSequence(ctx *context, tok cppToken, s string) (rune, int) {
return 7, 2
case 'b':
return 8, 2
+ case 'e':
+ return 0x1b, 2
case 'f':
return 12, 2
case 'n':
@@ -2444,21 +2447,7 @@ func (n *ppIncludeDirective) translationPhase4(c *cpp) {
v = dir
}
- var p string
- switch {
- case strings.HasPrefix(nm, "./"):
- wd := c.ctx.cfg.WorkingDir
- if wd == "" {
- var err error
- if wd, err = os.Getwd(); err != nil {
- c.err(toks[0], "cannot determine working dir: %v", err)
- return
- }
- }
- p = filepath.Join(wd, nm)
- default:
- p = filepath.Join(v, nm)
- }
+ p := filepath.Join(v, nm)
fi, err := c.ctx.statFile(p, sys)
if err != nil || fi.IsDir() {
continue
@@ -2475,6 +2464,17 @@ func (n *ppIncludeDirective) translationPhase4(c *cpp) {
return
}
+ if h := c.ctx.cfg.IncludeFileHandler; h != nil {
+ var position gotoken.Position
+ if p := toks[0].Pos(); p.IsValid() {
+ position = gotoken.Position(c.file.PositionFor(p, true))
+ }
+ apath, err := filepath.Abs(path)
+ if err != nil {
+ c.err(toks[0], "%s: cannot compute absolute path: %v", path, err)
+ }
+ h(position, apath)
+ }
cf, err := cache.getFile(c.ctx, path, sys, false)
if err != nil {
c.err(toks[0], "%s: %v", path, err)
diff --git a/vendor/modernc.org/cc/v3/lexer.go b/vendor/modernc.org/cc/v3/lexer.go
index 2819ac376..d1366135b 100644
--- a/vendor/modernc.org/cc/v3/lexer.go
+++ b/vendor/modernc.org/cc/v3/lexer.go
@@ -360,7 +360,7 @@ yystate20:
switch {
default:
goto yyabort
- case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
+ case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'e' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
goto yystate18
case c == 'U':
goto yystate21
@@ -662,7 +662,7 @@ yystate53:
switch {
default:
goto yyabort
- case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
+ case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'e' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
goto yystate51
case c == 'U':
goto yystate54
@@ -1137,7 +1137,7 @@ yystate105:
switch {
default:
goto yyabort
- case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
+ case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'e' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
goto yystate103
case c == 'U':
goto yystate106
@@ -1254,7 +1254,7 @@ yystate117:
switch {
default:
goto yyabort
- case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
+ case c == '"' || c == '\'' || c >= '0' && c <= '7' || c == '?' || c == '\\' || c == 'a' || c == 'b' || c == 'e' || c == 'f' || c == 'n' || c == 'r' || c == 't' || c == 'v':
goto yystate115
case c == 'U':
goto yystate118
diff --git a/vendor/modernc.org/cc/v3/lexer.l b/vendor/modernc.org/cc/v3/lexer.l
index f3da98783..4a2bf53a5 100644
--- a/vendor/modernc.org/cc/v3/lexer.l
+++ b/vendor/modernc.org/cc/v3/lexer.l
@@ -34,7 +34,7 @@ pp-number ({digit}|\.{digit})({digit}|{identifier-nondigit}|[eEpP]{sign}|\.)*
s-char [^\x22\n\x80\\]|{escape-sequence}
s-char-sequence {s-char}+
sign [-+]
-simple-sequence \\['\x22?\\abfnrtv]
+simple-sequence \\['\x22?\\abefnrtv]
string-literal \x22{s-char-sequence}?\x22
universal-character-name \\u{hex-quad}|\\U{hex-quad}{hex-quad}
white-space [ \t\f\v]
diff --git a/vendor/modernc.org/cc/v3/parser.yy b/vendor/modernc.org/cc/v3/parser.yy
index cd976d509..7d7848ff5 100644
--- a/vendor/modernc.org/cc/v3/parser.yy
+++ b/vendor/modernc.org/cc/v3/parser.yy
@@ -608,7 +608,8 @@ package cc // import "modernc.org/cc/v3"
/*yy:case Expr */ | IDENTIFIER AttributeSpecifierList '=' ConstantExpression
/* [2], 6.7.2.4 Atomic type specifiers */
- /*yy:example _Atomic(int) i; */
+ /*yy:field list []*TypeSpecifier */
+ /*yy:example _Atomic(int) i; */
AtomicTypeSpecifier:
"_Atomic" '(' TypeName ')'
@@ -647,6 +648,7 @@ package cc // import "modernc.org/cc/v3"
/*yy:field called bool */
/*yy:field fnDef bool */
/*yy:field hasInitializer bool */
+ /*yy:field implicit bool */
/*yy:example int *p __attribute__ ((foo)); */
Declarator:
Pointer DirectDeclarator AttributeSpecifierList %prec BELOW_ATTRIBUTE
diff --git a/vendor/modernc.org/cc/v3/scanner.go b/vendor/modernc.org/cc/v3/scanner.go
index 60ccef34b..6217d7db5 100644
--- a/vendor/modernc.org/cc/v3/scanner.go
+++ b/vendor/modernc.org/cc/v3/scanner.go
@@ -1178,10 +1178,6 @@ func (c *ppCache) getFile(ctx *context, name string, sys bool, doNotCache bool)
size := int(fi.Size())
if !filepath.IsAbs(name) { // Never cache relative paths
- if isTesting {
- panic(internalError())
- }
-
f, err := ctx.openFile(name, sys)
if err != nil {
return nil, err
diff --git a/vendor/modernc.org/cc/v3/type.go b/vendor/modernc.org/cc/v3/type.go
index 7e9e9ca4b..f339f3684 100644
--- a/vendor/modernc.org/cc/v3/type.go
+++ b/vendor/modernc.org/cc/v3/type.go
@@ -403,8 +403,8 @@ type Type interface {
// Name returns type name, if any.
Name() StringID
- // atomic reports whether type has type qualifier "_Atomic".
- atomic() bool
+ // IsAtomic reports whether type has type qualifier "_Atomic".
+ IsAtomic() bool
// hasConst reports whether type has type qualifier "const".
hasConst() bool
@@ -611,7 +611,7 @@ func (t *typeBase) check(ctx *context, td typeDescriptor, defaultInt bool) (r Ty
case DeclarationSpecifiersStorage: // StorageClassSpecifier DeclarationSpecifiers
// nop
case DeclarationSpecifiersTypeSpec: // TypeSpecifier DeclarationSpecifiers
- typeSpecifiers = append(typeSpecifiers, n.TypeSpecifier)
+ typeSpecifiers = append(typeSpecifiers, n.TypeSpecifier.list()...)
case DeclarationSpecifiersTypeQual: // TypeQualifier DeclarationSpecifiers
// nop
case DeclarationSpecifiersFunc: // FunctionSpecifier DeclarationSpecifiers
@@ -628,7 +628,7 @@ func (t *typeBase) check(ctx *context, td typeDescriptor, defaultInt bool) (r Ty
for ; n != nil; n = n.SpecifierQualifierList {
switch n.Case {
case SpecifierQualifierListTypeSpec: // TypeSpecifier SpecifierQualifierList
- typeSpecifiers = append(typeSpecifiers, n.TypeSpecifier)
+ typeSpecifiers = append(typeSpecifiers, n.TypeSpecifier.list()...)
case SpecifierQualifierListTypeQual: // TypeQualifier SpecifierQualifierList
// nop
case SpecifierQualifierListAlignSpec: // AlignmentSpecifier SpecifierQualifierList
@@ -931,8 +931,8 @@ func (t *typeBase) UnionCommon() Kind {
panic(internalErrorf("%s: UnionCommon of invalid type", t.Kind()))
}
-// atomic implements Type.
-func (t *typeBase) atomic() bool { return t.flags&fAtomic != 0 }
+// IsAtomic implements Type.
+func (t *typeBase) IsAtomic() bool { return t.flags&fAtomic != 0 }
// Attributes implements Type.
func (t *typeBase) Attributes() (a []*AttributeSpecifier) { return nil }
@@ -1220,7 +1220,7 @@ func (t *typeBase) Tag() StringID {
// string implements Type.
func (t *typeBase) string(b *bytes.Buffer) {
spc := ""
- if t.atomic() {
+ if t.IsAtomic() {
b.WriteString("atomic")
spc = " "
}
@@ -1944,7 +1944,7 @@ func (t *aliasType) Size() uintptr { return t.d.Type().Size() }
// String implements Type.
func (t *aliasType) String() string {
var a []string
- if t.typeBase.atomic() {
+ if t.typeBase.IsAtomic() {
a = append(a, "atomic")
}
if t.typeBase.hasConst() {
@@ -1972,8 +1972,8 @@ func (t *aliasType) Tag() StringID { return t.d.Type().Tag() }
// Name implements Type.
func (t *aliasType) Name() StringID { return t.nm }
-// atomic implements Type.
-func (t *aliasType) atomic() bool { return t.d.Type().atomic() }
+// IsAtomic implements Type.
+func (t *aliasType) IsAtomic() bool { return t.d.Type().IsAtomic() }
// Inline implements Type.
func (t *aliasType) Inline() bool { return t.d.Type().Inline() }
@@ -2544,12 +2544,11 @@ func (t *taggedType) isAssingmentCompatibleOperand(rhs Operand) (r bool) {
// IsCompatible implements Type.
func (t *taggedType) IsCompatible(u Type) (r bool) {
- // defer func() {
- // u0 := u
- // if !r {
- // trc("TRACE %v <- %v\n%s", t, u0, debug.Stack()) //TODO-
- // }
- // }()
+ defer func() {
+ // if !r {
+ // trc("TRACE %v <- %v: %v (%s)", t, u0, r, origin(2)) //TODO-
+ // }
+ }()
if t == nil || u == nil {
return false
}
@@ -3164,10 +3163,6 @@ func NewStructLayout(t Type) *StructLayout {
//trc("%q off %d pos %d %v %v %v", f.Name(), off, pos, ft, ft.Kind(), ft.IsIncomplete())
switch {
case ft.IsBitFieldType():
- if f.BitFieldOffset() != 0 {
- break
- }
-
if p := int(off - pos); p != 0 {
if pads == nil {
pads = map[Field]int{}