intrinsic-gen: Support decorations on enum entries

Add `[[internal]]` decoration on `storage_class.handle` - its not an entry that should ever appear in WGSL.

Bug: tint:832
Change-Id: I210f64c495bf37a8f48422919248806e7b096638
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53045
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-06-03 08:42:14 +00:00 committed by Tint LUCI CQ
parent 57d6bd2ef3
commit 04bd2e8083
6 changed files with 49 additions and 10 deletions

View File

@ -30,7 +30,7 @@ enum storage_class {
workgroup
uniform
storage
handle
[[internal]] handle
}
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode

View File

@ -56,18 +56,34 @@ func (a AST) String() string {
type EnumDecl struct {
Source tok.Source
Name string
Entries []string
Entries []EnumEntry
}
// Format implements the fmt.Formatter interface
func (e EnumDecl) Format(w fmt.State, verb rune) {
fmt.Fprintf(w, "enum %v {\n", e.Name)
for _, e := range e.Entries {
fmt.Fprintf(w, " %s\n", e)
fmt.Fprintf(w, " %v\n", e)
}
fmt.Fprintf(w, "}\n")
}
// EnumEntry describes an entry in a enumerator
type EnumEntry struct {
Source tok.Source
Name string
Decorations Decorations
}
// Format implements the fmt.Formatter interface
func (e EnumEntry) Format(w fmt.State, verb rune) {
if len(e.Decorations) > 0 {
fmt.Fprintf(w, "%v %v", e.Decorations, e.Name)
} else {
fmt.Fprint(w, e.Name)
}
}
// MatcherDecl describes a matcher declaration
type MatcherDecl struct {
Source tok.Source

View File

@ -73,11 +73,17 @@ func (p *parser) enumDecl() ast.EnumDecl {
e := ast.EnumDecl{Source: name.Source, Name: string(name.Runes)}
p.expect(tok.Lbrace, "enum declaration")
for p.err == nil && p.match(tok.Rbrace) == nil {
e.Entries = append(e.Entries, p.ident("enumerator value"))
e.Entries = append(e.Entries, p.enumEntry())
}
return e
}
func (p *parser) enumEntry() ast.EnumEntry {
decos := p.decorations()
name := p.expect(tok.Identifier, "enum entry")
return ast.EnumEntry{Source: name.Source, Decorations: decos, Name: string(name.Runes)}
}
func (p *parser) matcherDecl() ast.MatcherDecl {
p.expect(tok.Match, "matcher declaration")
name := p.expect(tok.Identifier, "matcher name")

View File

@ -31,10 +31,17 @@ func TestParser(t *testing.T) {
{"enum E {}", ast.AST{
Enums: []ast.EnumDecl{{Name: "E"}},
}},
{"enum E { A B C }", ast.AST{
{"enum E { A [[deco]] B C }", ast.AST{
Enums: []ast.EnumDecl{{
Name: "E",
Entries: []string{"A", "B", "C"},
Name: "E",
Entries: []ast.EnumEntry{
{Name: "A"},
{
Decorations: ast.Decorations{{Name: "deco"}},
Name: "B",
},
{Name: "C"},
},
}},
}},
{"type T", ast.AST{

View File

@ -90,9 +90,18 @@ func (r *resolver) enum(e ast.EnumDecl) error {
// Register each of the enum entries
for _, ast := range e.Entries {
entry := &sem.EnumEntry{
Name: ast,
Name: ast.Name,
Enum: s,
}
if internal := ast.Decorations.Take("internal"); internal != nil {
entry.IsInternal = true
if len(internal.Values) != 0 {
return fmt.Errorf("%v unexpected value for internal decoration", ast.Source)
}
}
if len(ast.Decorations) != 0 {
return fmt.Errorf("%v unknown decoration", ast.Decorations[0].Source)
}
if err := r.globals.declare(entry, e.Source); err != nil {
return err
}

View File

@ -63,8 +63,9 @@ func (e *Enum) FindEntry(name string) *EnumEntry {
// EnumEntry is an entry in an enumerator
type EnumEntry struct {
Enum *Enum
Name string
Enum *Enum
Name string
IsInternal bool // True if this entry is not part of the WGSL grammar
}
// Type declares a type