diff options
| author | 2022-03-07 11:08:26 +0100 | |
|---|---|---|
| committer | 2022-03-07 11:08:26 +0100 | |
| commit | 07727753b96d209406783e5e539725bcdafebdc7 (patch) | |
| tree | b32f11cbc304d633ed0acd8f84b4c11e909bb5f3 /vendor/modernc.org/cc/v3 | |
| parent | [documentation] Creates Docker documentation and docker-compose.yaml (#416) (diff) | |
| download | gotosocial-07727753b96d209406783e5e539725bcdafebdc7.tar.xz | |
[feature] Clean up/uncache remote media (#407)
* Add whereNotEmptyAndNotNull
* Add GetRemoteOlderThanDays
* Add GetRemoteOlderThanDays
* Add PruneRemote to Manager interface
* Start implementing PruneRemote
* add new attachment + status to tests
* fix up and test GetRemoteOlderThan
* fix bad import
* PruneRemote: return number pruned
* add Cached column to mediaattachment
* update + test pruneRemote
* update mediaTest
* use Cached column
* upstep bun to latest version
* embed structs in mediaAttachment
* migrate mediaAttachment to new format
* don't default cached to true
* select only remote media
* update db dependencies
* step bun back to last working version
* update pruneRemote to use Cached field
* fix storage path of test attachments
* add recache logic to manager
* fix trimmed aspect ratio
* test prune and recache
* return errwithcode
* tidy up different paths for emoji vs attachment
* fix incorrect thumbnail type being stored
* expose TransportController to media processor
* implement tee-ing recached content
* add thoughts of dog to test fedi attachments
* test get remote files
* add comment on PruneRemote
* add postData cleanup to recache
* test thumbnail fetching
* add incredible diagram
* go mod tidy
* buffer pipes for recache streaming
* test for client stops reading after 1kb
* add media-remote-cache-days to config
* add cron package
* wrap logrus so it's available to cron
* start and stop cron jobs gracefully
Diffstat (limited to 'vendor/modernc.org/cc/v3')
| -rw-r--r-- | vendor/modernc.org/cc/v3/Makefile | 3 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/abi_platforms.go | 36 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/ast.go | 6 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/check.go | 2 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/cpp.go | 215 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/parser.go | 22 | ||||
| -rw-r--r-- | vendor/modernc.org/cc/v3/parser.yy | 2 |
7 files changed, 180 insertions, 106 deletions
diff --git a/vendor/modernc.org/cc/v3/Makefile b/vendor/modernc.org/cc/v3/Makefile index 12f21d040..af9215598 100644 --- a/vendor/modernc.org/cc/v3/Makefile +++ b/vendor/modernc.org/cc/v3/Makefile @@ -61,10 +61,13 @@ test_windows386: build_all_targets: GOOS=darwin GOARCH=amd64 go build -v ./... GOOS=darwin GOARCH=arm64 go build -v ./... + GOOS=freebsd GOARCH=amd64 go build -v ./... + GOOS=freebsd GOARCH=386 go build -v ./... GOOS=linux GOARCH=386 go build -v ./... GOOS=linux GOARCH=amd64 go build -v ./... GOOS=linux GOARCH=arm go build -v ./... GOOS=linux GOARCH=arm64 go build -v ./... + GOOS=netbsd GOARCH=amd64 go build -v ./... GOOS=windows GOARCH=386 go build -v ./... GOOS=windows GOARCH=amd64 go build -v ./... diff --git a/vendor/modernc.org/cc/v3/abi_platforms.go b/vendor/modernc.org/cc/v3/abi_platforms.go index 5b1820c78..24c8d7621 100644 --- a/vendor/modernc.org/cc/v3/abi_platforms.go +++ b/vendor/modernc.org/cc/v3/abi_platforms.go @@ -20,6 +20,7 @@ var ( {"darwin", "amd64"}: true, {"darwin", "arm64"}: true, {"freebsd", "amd64"}: true, + {"freebsd", "386"}: true, {"linux", "386"}: true, {"linux", "amd64"}: true, {"netbsd", "amd64"}: true, @@ -382,6 +383,41 @@ var abiTypes = map[[2]string]map[Kind]ABIType{ Int128: {16, 16, 16}, UInt128: {16, 16, 16}, }, + // gcc (FreeBSD Ports Collection) 10.3.0 + {"freebsd", "386"}: { + 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: {4, 4, 4}, + ULong: {4, 4, 4}, + LongLong: {8, 4, 4}, + ULongLong: {8, 4, 4}, + Ptr: {4, 4, 4}, + Function: {4, 4, 4}, + Float: {4, 4, 4}, + Double: {8, 4, 4}, + LongDouble: {12, 4, 4}, + 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, 4, 4}, + UInt64: {8, 4, 4}, + Float32: {4, 4, 4}, + Float32x: {8, 4, 4}, + Float64: {8, 4, 4}, + Float64x: {16, 16, 16}, + Float128: {16, 16, 16}, + }, // gcc (GCC) 8.4.0 {"openbsd", "amd64"}: { Void: {1, 1, 1}, diff --git a/vendor/modernc.org/cc/v3/ast.go b/vendor/modernc.org/cc/v3/ast.go index 28a1569bb..7cd777a6b 100644 --- a/vendor/modernc.org/cc/v3/ast.go +++ b/vendor/modernc.org/cc/v3/ast.go @@ -3527,6 +3527,7 @@ type PointerCase int const ( PointerTypeQual PointerCase = iota PointerPtr + PointerBlock ) // String implements fmt.Stringer @@ -3536,6 +3537,8 @@ func (n PointerCase) String() string { return "PointerTypeQual" case PointerPtr: return "PointerPtr" + case PointerBlock: + return "PointerBlock" default: return fmt.Sprintf("PointerCase(%v)", int(n)) } @@ -3546,6 +3549,7 @@ func (n PointerCase) String() string { // Pointer: // '*' TypeQualifiers // Case PointerTypeQual // | '*' TypeQualifiers Pointer // Case PointerPtr +// | '^' TypeQualifiers // Case PointerBlock type Pointer struct { typeQualifiers *typeBase Case PointerCase `PrettyPrint:"stringer,zero"` @@ -3564,7 +3568,7 @@ func (n *Pointer) Position() (r token.Position) { } switch n.Case { - case 0: + case 0, 2: if p := n.Token.Position(); p.IsValid() { return p } diff --git a/vendor/modernc.org/cc/v3/check.go b/vendor/modernc.org/cc/v3/check.go index 3c4bed427..508878709 100644 --- a/vendor/modernc.org/cc/v3/check.go +++ b/vendor/modernc.org/cc/v3/check.go @@ -2093,6 +2093,8 @@ func (n *Pointer) check(ctx *context, typ Type) (t Type) { case PointerPtr: // '*' TypeQualifiers Pointer n.TypeQualifiers.check(ctx, &n.typeQualifiers) typ = n.Pointer.check(ctx, typ) + case PointerBlock: // '^' TypeQualifiers + n.TypeQualifiers.check(ctx, &n.typeQualifiers) default: panic(todo("")) } diff --git a/vendor/modernc.org/cc/v3/cpp.go b/vendor/modernc.org/cc/v3/cpp.go index 4b7f19983..db4cee0ff 100644 --- a/vendor/modernc.org/cc/v3/cpp.go +++ b/vendor/modernc.org/cc/v3/cpp.go @@ -143,6 +143,15 @@ func cppToksStr(toks []cppToken, sep string) string { return b.String() } +func cppToksStr2(toks [][]cppToken) string { + panic(todo("")) + var a []string + for _, v := range toks { + a = append(a, fmt.Sprintf("%q", cppToksStr(v, "|"))) + } + return fmt.Sprint(a) +} + type cppReader struct { buf []cppToken ungetBuf @@ -267,6 +276,10 @@ func (m *Macro) param2(varArgs []cppToken, ap [][]cppToken, nm StringID, out *[] } func (m *Macro) param(varArgs []cppToken, ap [][]cppToken, nm StringID, out *[]cppToken) bool { + // trc("select (A) varArgs %q, ap %v, nm %q, out %q", cppToksStr(varArgs, "|"), cppToksStr2(ap), nm, cppToksStr(*out, "|")) + // defer func() { + // trc("select (A) varArgs %q, ap %v, nm %q, out %q", cppToksStr(varArgs, "|"), cppToksStr2(ap), nm, cppToksStr(*out, "|")) + // }() return m.param2(varArgs, ap, nm, out, nil) } @@ -287,6 +300,7 @@ type cpp struct { macros map[StringID]*Macro out chan *[]token4 outBuf *[]token4 + pragmaOpBuf []token4 rq chan struct{} timeMacro Macro ungetBuf @@ -296,6 +310,7 @@ type cpp struct { intmaxChecked bool nonFirstRead bool seenEOF bool + inPragmaOp bool } func newCPP(ctx *context) *cpp { @@ -408,87 +423,72 @@ func (c *cpp) write(tok cppToken) { //dbg("%T.write %q", c, tok) c.last = tok.char - *c.outBuf = append(*c.outBuf, tok.token4) - if tok.char == '\n' { - for i, tok := range *c.outBuf { - if tok.char != ' ' { - if tok.char == IDENTIFIER && tok.value == idPragmaOp { - toks := (*c.outBuf)[i:] - b := token4Pool.Get().(*[]token4) - *b = (*b)[:0] - c.outBuf = b - c.pragmaOp(toks) - return - } - + switch { + case c.inPragmaOp: + out: + switch tok.char { + case ')': + c.inPragmaOp = false + b := c.pragmaOpBuf + if len(b) == 0 || b[0].char != '(' { + c.err(b[0], "expected (") break } - } - c.out <- c.outBuf - b := token4Pool.Get().(*[]token4) - *b = (*b)[:0] - c.outBuf = b - } -} -func (c *cpp) pragmaOp(toks []token4) { - var a []string -loop: - for { - tok := toks[0] - toks = toks[1:] // Skip "_Pragma" - toks = ltrim4(toks) - if len(toks) == 0 || toks[0].char != '(' { - c.err(tok, "expected (") - break loop - } + var a []string + for _, v := range b[1:] { + if v.char != STRINGLITERAL { + c.err(v, "expected string literal") + break out + } - tok = toks[0] - toks = toks[1:] // Skip '(' - toks = ltrim4(toks) - if len(toks) == 0 || (toks[0].char != STRINGLITERAL && toks[0].char != LONGSTRINGLITERAL) { - c.err(toks[0], "expected string literal") - break loop - } + a = append(a, v.String()) + } - tok = toks[0] - a = append(a, tok.String()) - toks = toks[1:] // Skip string literal - toks = ltrim4(toks) - if len(toks) == 0 || toks[0].char != ')' { - c.err(toks[0], "expected )") - break loop - } + if len(a) == 0 { + break + } - toks = toks[1:] // Skip ')' - toks = ltrim4(toks) - if len(toks) == 0 { - break loop + for i, v := range a { + // [0], 6.10.9, 1 + if v[0] == 'L' { + v = v[1:] + } + v = v[1 : len(v)-1] + v = strings.ReplaceAll(v, `\"`, `"`) + a[i] = "#pragma " + strings.ReplaceAll(v, `\\`, `\`) + "\n" + } + src := strings.Join(a, "") + s := newScanner0(c.ctx, strings.NewReader(src), tokenNewFile("", len(src)), 4096) + if ppf := s.translationPhase3(); ppf != nil { + ppf.translationPhase4(c) + } + default: + c.pragmaOpBuf = append(c.pragmaOpBuf, tok.token4) } - - switch tok := toks[0]; { + default: + switch { case tok.char == '\n': - break loop + *c.outBuf = append(*c.outBuf, tok.token4) + c.out <- c.outBuf + b := token4Pool.Get().(*[]token4) + *b = (*b)[:0] + c.outBuf = b case tok.char == IDENTIFIER && tok.value == idPragmaOp: - // ok + if len(*c.outBuf) != 0 { + tok.char = '\n' + tok.value = 0 + *c.outBuf = append(*c.outBuf, tok.token4) + c.out <- c.outBuf + b := token4Pool.Get().(*[]token4) + *b = (*b)[:0] + c.outBuf = b + } + c.inPragmaOp = true + c.pragmaOpBuf = c.pragmaOpBuf[:0] default: - c.err(tok, "expected new-line") - break loop - } - } - for i, v := range a { - // [0], 6.10.9, 1 - if v[0] == 'L' { - v = v[1:] + *c.outBuf = append(*c.outBuf, tok.token4) } - v = v[1 : len(v)-1] - v = strings.ReplaceAll(v, `\"`, `"`) - a[i] = "#pragma " + strings.ReplaceAll(v, `\\`, `\`) + "\n" - } - src := strings.Join(a, "") - s := newScanner0(c.ctx, strings.NewReader(src), tokenNewFile("", len(src)), 4096) - if ppf := s.translationPhase3(); ppf != nil { - ppf.translationPhase4(c) } } @@ -531,7 +531,7 @@ func (c *cpp) writes(toks []cppToken) { // return T^HS • expand(TS’); // } func (c *cpp) expand(ts tokenReader, w tokenWriter, expandDefined bool) { - // dbg("==== expand enter") + // trc("==== expand enter") start: tok, ok := ts.read() tok.file = c.file @@ -539,7 +539,7 @@ start: if !ok { // ---------------------------------------------------------- A // return {}; - // dbg("---- expand A") + // trc("---- expand A") return } @@ -559,8 +559,8 @@ start: if tok.has(nm) { // -------------------------------------------------- B // return T^HS • expand(TS’); - // dbg("---- expand B") - // dbg("expand write %q", tok) + // trc("---- expand B") + // trc("expand write %q", tok) w.write(tok) goto start } @@ -592,7 +592,7 @@ start: if m != nil { // -------------------------------------------------- C // return expand(subst(ts(T), {}, {}, HS \cup {T}, {}) • TS’ ); - // dbg("---- expand C") + // trc("---- expand C") hs := hideSet{nm: {}} for k, v := range tok.hs { hs[k] = v @@ -623,7 +623,7 @@ start: // -------------------------------------------------- D // check TS’ is actuals • )^HS’ • TS’’ and actuals are "correct for T" // return expand(subst(ts(T), fp(T), actuals,(HS \cap HS’) \cup {T }, {}) • TS’’); - // dbg("---- expand D") + // trc("---- expand D") hs := tok.hs var skip []cppToken again: @@ -704,8 +704,8 @@ start: // ------------------------------------------------------------------ E // note TS must be T^HS • TS’ // return T^HS • expand(TS’); - // dbg("---- expand E") - // dbg("expand write %q", tok) + // trc("---- expand E") + // trc("expand write %q", tok) w.write(tok) goto start } @@ -913,28 +913,28 @@ func (c *cpp) actuals(m *Macro, r tokenReader) (varArgs []cppToken, ap [][]cppTo // combinations. After the entire input sequence is finished, the updated hide // set is applied to the output sequence, and that is the result of subst. func (c *cpp) subst(m *Macro, is []cppToken, fp []StringID, varArgs []cppToken, ap [][]cppToken, hs hideSet, os *[]cppToken, expandDefined bool) (r []cppToken) { - // var a []string - // for _, v := range ap { - // a = append(a, fmt.Sprintf("%q", cppToksStr(v, "|"))) - // } - // dbg("==== subst: is %q, fp %v ap %v", cppToksStr(is, "|"), fp, a) + var ap0 [][]cppToken + for _, v := range ap { + ap0 = append(ap0, append([]cppToken(nil), v...)) + } + // trc("==== subst: is %q, fp, %v ap@%p %v", cppToksStr(is, "|"), fp, &ap, cppToksStr2(ap)) start: - // dbg("start: %q", cppToksStr(is, "|")) + // trc("start: is %q, fp %v, ap@%p %v, os %q", cppToksStr(is, "|"), fp, &ap, cppToksStr2(ap), cppToksStr(*os, "|")) if len(is) == 0 { // ---------------------------------------------------------- A // return hsadd(HS, OS); - // dbg("---- A") - // dbg("subst returns %q", cppToksStr(os, "|")) + // trc("---- A") + // trc("subst RETURNS %q", cppToksStr(*os, "|")) return c.hsAdd(hs, os) } tok := is[0] var arg []cppToken if tok.char == '#' { - if len(is) > 1 && is[1].char == IDENTIFIER && m.param(varArgs, ap, is[1].value, &arg) { + if len(is) > 1 && is[1].char == IDENTIFIER && m.param(varArgs, ap0, is[1].value, &arg) { // -------------------------------------------------- B // return subst(IS’, FP, AP, HS, OS • stringize(select(i, AP))); - // dbg("---- subst B") + // trc("---- subst B") *os = append(*os, c.stringize(arg)) is = is[2:] goto start @@ -942,14 +942,14 @@ start: } if tok.char == PPPASTE { - if len(is) > 1 && is[1].char == IDENTIFIER && m.param(varArgs, ap, is[1].value, &arg) { + if len(is) > 1 && is[1].char == IDENTIFIER && m.param(varArgs, ap0, is[1].value, &arg) { // -------------------------------------------------- C - // dbg("---- subst C") + // trc("---- subst C") if len(arg) == 0 { // TODO "only if actuals can be empty" // ------------------------------------------ D // return subst(IS’, FP, AP, HS, OS); - // dbg("---- D") + // trc("---- D") if c := len(*os); c != 0 && (*os)[c-1].char == ',' { *os = (*os)[:c-1] } @@ -959,7 +959,7 @@ start: // -------------------------------------------------- E // return subst(IS’, FP, AP, HS, glue(OS, select(i, AP))); - // dbg("---- subst E") + // trc("---- subst E, arg %q", cppToksStr(arg, "|")) *os = c.glue(*os, arg) is = is[2:] goto start @@ -968,39 +968,39 @@ start: if len(is) > 1 { // -------------------------------------------------- F // return subst(IS’, FP, AP, HS, glue(OS, T^HS’)); - // dbg("---- subst F") + // trc("---- subst F") *os = c.glue(*os, is[1:2]) is = is[2:] goto start } } - if tok.char == IDENTIFIER && (len(is) > 1 && is[1].char == PPPASTE) && m.param(varArgs, ap, tok.value, &arg) { + if tok.char == IDENTIFIER && (len(is) > 1 && is[1].char == PPPASTE) && m.param(varArgs, ap0, tok.value, &arg) { // ---------------------------------------------------------- G - // dbg("---- subst G") + // trc("---- subst G") if len(arg) == 0 { // TODO "only if actuals can be empty" // -------------------------------------------------- H - // dbg("---- subst H") + // trc("---- subst H") is = is[2:] // skip T## if len(is) > 0 && is[0].char == IDENTIFIER && m.param(varArgs, ap, is[0].value, &arg) { // -------------------------------------------------- I // return subst(IS’’, FP, AP, HS, OS • select(j, AP)); - // dbg("---- subst I") + // trc("---- subst I") *os = append(*os, arg...) is = is[1:] goto start } else { // -------------------------------------------------- J // return subst(IS’, FP, AP, HS, OS); - // dbg("---- subst J") + // trc("---- subst J") goto start } } // ---------------------------------------------------------- K // return subst(##^HS’ • IS’, FP, AP, HS, OS • select(i, AP)); - // dbg("---- subst K") + // trc("---- subst K") *os = append(*os, arg...) is = is[1:] goto start @@ -1010,7 +1010,7 @@ start: if tok.char == IDENTIFIER && m.param2(varArgs, ap, tok.value, &arg, &ax) { // ------------------------------------------ L // return subst(IS’, FP, AP, HS, OS • expand(select(i, AP))); - // dbg("---- subst L") + // trc("---- subst L") // if toks, ok := cache[tok.value]; ok { // os = append(os, toks...) // is = is[1:] @@ -1019,7 +1019,9 @@ start: sel := cppReader{buf: arg} var w cppWriter + // trc("---- L(1) ap@%p %v", &ap, cppToksStr2(ap)) c.expand(&sel, &w, expandDefined) + // trc("---- L(2) ap@%p %v", &ap, cppToksStr2(ap)) *os = append(*os, w.toks...) if ax >= 0 { ap[ax] = w.toks @@ -1031,9 +1033,9 @@ start: // ------------------------------------------------------------------ M // note IS must be T^HS’ • IS’ // return subst(IS’, FP, AP, HS, OS • T^HS’); - // dbg("---- subst M") *os = append(*os, tok) is = is[1:] + // trc("---- subst M: is %q, os %q", cppToksStr(is, "|"), cppToksStr(*os, "|")) goto start } @@ -1058,7 +1060,18 @@ start: // 43 // 0 // $ +// +// ---------------------------------------------------------------------------- +// glue(LS,RS ) /* paste last of left side with first of right side */ +// { +// if LS is L^HS and RS is R^HS’ • RS’ then +// return L&R^(HS∩HS’) • RS’; /* undefined if L&R is invalid */ + +// // note LS must be L HS • LS’ +// return L^HS • glue(LS’,RS ); +// } func (c *cpp) glue(ls, rs []cppToken) (out []cppToken) { + // trc("ls %q, rs %q", cppToksStr(ls, "|"), cppToksStr(rs, "|")) if len(rs) == 0 { return ls } diff --git a/vendor/modernc.org/cc/v3/parser.go b/vendor/modernc.org/cc/v3/parser.go index cf021e9f4..d73b2c6b3 100644 --- a/vendor/modernc.org/cc/v3/parser.go +++ b/vendor/modernc.org/cc/v3/parser.go @@ -313,6 +313,7 @@ var ( dict.sid("__pragma_stdc"): PRAGMASTDC, dict.sid("__restrict"): RESTRICT, dict.sid("__restrict__"): RESTRICT, + dict.sid("__signed"): SIGNED, dict.sid("__signed__"): SIGNED, dict.sid("__thread"): THREADLOCAL, dict.sid("__typeof"): TYPEOF, @@ -2263,7 +2264,7 @@ func (p *parser) functionSpecifier(inline *bool) *FunctionSpecifier { // declarator: // pointer_opt direct-declarator attribute-specifier-list_opt func (p *parser) declarator(declare, isTypedefName bool, ptr *Pointer) *Declarator { - if ptr == nil && p.rune() == '*' { + if ptr == nil && (p.rune() == '*' || p.rune() == '^') { ptr = p.pointer() } r := &Declarator{IsTypedefName: isTypedefName, Pointer: ptr, DirectDeclarator: p.directDeclarator(nil)} @@ -2488,9 +2489,21 @@ func (p *parser) directDeclarator(d *DirectDeclarator) (r *DirectDeclarator) { // pointer: // * type-qualifier-list_opt // * type-qualifier-list_opt pointer +// ^ type-qualifier-list_opt func (p *parser) pointer() (r *Pointer) { + if p.rune() == '^' { + t := p.shift() + var list *TypeQualifiers + switch p.rune() { + case ATTRIBUTE, CONST, RESTRICT, VOLATILE, ATOMIC: + list = p.typeQualifierList() + } + + return &Pointer{Case: PointerBlock, Token: t, TypeQualifiers: list} + } + if p.rune() != '*' { - p.err("expected *") + p.err("expected * or ^") return nil } @@ -2608,7 +2621,8 @@ func (p *parser) parameterDeclaration() *ParameterDeclaration { func (p *parser) declaratorOrAbstractDeclarator(isTypedefName bool) (r Node) { var ptr *Pointer - if p.rune() == '*' { + switch p.rune() { + case '*', '^': ptr = p.pointer() } switch p.rune() { @@ -2766,7 +2780,7 @@ func (p *parser) typeName() *TypeName { // pointer // pointer_opt direct-abstract-declarator func (p *parser) abstractDeclarator(ptr *Pointer) *AbstractDeclarator { - if ptr == nil && p.rune() == '*' { + if ptr == nil && (p.rune() == '*' || p.rune() == '^') { ptr = p.pointer() } switch p.rune() { diff --git a/vendor/modernc.org/cc/v3/parser.yy b/vendor/modernc.org/cc/v3/parser.yy index 7d7848ff5..a51b600b8 100644 --- a/vendor/modernc.org/cc/v3/parser.yy +++ b/vendor/modernc.org/cc/v3/parser.yy @@ -688,6 +688,8 @@ package cc // import "modernc.org/cc/v3" '*' TypeQualifiers /*yy:example int **p; */ /*yy:case Ptr */ | '*' TypeQualifiers Pointer + /*yy:example int atexit_b(void (^ _Nonnull)(void)); */ +/*yy:case Block */ | '^' TypeQualifiers /*yy:field noStorageClass */ /*yy:example int * const i; */ |
