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:
parent
57d6bd2ef3
commit
04bd2e8083
|
@ -30,7 +30,7 @@ enum storage_class {
|
||||||
workgroup
|
workgroup
|
||||||
uniform
|
uniform
|
||||||
storage
|
storage
|
||||||
handle
|
[[internal]] handle
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
|
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
|
||||||
|
|
|
@ -56,18 +56,34 @@ func (a AST) String() string {
|
||||||
type EnumDecl struct {
|
type EnumDecl struct {
|
||||||
Source tok.Source
|
Source tok.Source
|
||||||
Name string
|
Name string
|
||||||
Entries []string
|
Entries []EnumEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format implements the fmt.Formatter interface
|
// Format implements the fmt.Formatter interface
|
||||||
func (e EnumDecl) Format(w fmt.State, verb rune) {
|
func (e EnumDecl) Format(w fmt.State, verb rune) {
|
||||||
fmt.Fprintf(w, "enum %v {\n", e.Name)
|
fmt.Fprintf(w, "enum %v {\n", e.Name)
|
||||||
for _, e := range e.Entries {
|
for _, e := range e.Entries {
|
||||||
fmt.Fprintf(w, " %s\n", e)
|
fmt.Fprintf(w, " %v\n", e)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "}\n")
|
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
|
// MatcherDecl describes a matcher declaration
|
||||||
type MatcherDecl struct {
|
type MatcherDecl struct {
|
||||||
Source tok.Source
|
Source tok.Source
|
||||||
|
|
|
@ -73,11 +73,17 @@ func (p *parser) enumDecl() ast.EnumDecl {
|
||||||
e := ast.EnumDecl{Source: name.Source, Name: string(name.Runes)}
|
e := ast.EnumDecl{Source: name.Source, Name: string(name.Runes)}
|
||||||
p.expect(tok.Lbrace, "enum declaration")
|
p.expect(tok.Lbrace, "enum declaration")
|
||||||
for p.err == nil && p.match(tok.Rbrace) == nil {
|
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
|
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 {
|
func (p *parser) matcherDecl() ast.MatcherDecl {
|
||||||
p.expect(tok.Match, "matcher declaration")
|
p.expect(tok.Match, "matcher declaration")
|
||||||
name := p.expect(tok.Identifier, "matcher name")
|
name := p.expect(tok.Identifier, "matcher name")
|
||||||
|
|
|
@ -31,10 +31,17 @@ func TestParser(t *testing.T) {
|
||||||
{"enum E {}", ast.AST{
|
{"enum E {}", ast.AST{
|
||||||
Enums: []ast.EnumDecl{{Name: "E"}},
|
Enums: []ast.EnumDecl{{Name: "E"}},
|
||||||
}},
|
}},
|
||||||
{"enum E { A B C }", ast.AST{
|
{"enum E { A [[deco]] B C }", ast.AST{
|
||||||
Enums: []ast.EnumDecl{{
|
Enums: []ast.EnumDecl{{
|
||||||
Name: "E",
|
Name: "E",
|
||||||
Entries: []string{"A", "B", "C"},
|
Entries: []ast.EnumEntry{
|
||||||
|
{Name: "A"},
|
||||||
|
{
|
||||||
|
Decorations: ast.Decorations{{Name: "deco"}},
|
||||||
|
Name: "B",
|
||||||
|
},
|
||||||
|
{Name: "C"},
|
||||||
|
},
|
||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
{"type T", ast.AST{
|
{"type T", ast.AST{
|
||||||
|
|
|
@ -90,9 +90,18 @@ func (r *resolver) enum(e ast.EnumDecl) error {
|
||||||
// Register each of the enum entries
|
// Register each of the enum entries
|
||||||
for _, ast := range e.Entries {
|
for _, ast := range e.Entries {
|
||||||
entry := &sem.EnumEntry{
|
entry := &sem.EnumEntry{
|
||||||
Name: ast,
|
Name: ast.Name,
|
||||||
Enum: s,
|
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 {
|
if err := r.globals.declare(entry, e.Source); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ func (e *Enum) FindEntry(name string) *EnumEntry {
|
||||||
type EnumEntry struct {
|
type EnumEntry struct {
|
||||||
Enum *Enum
|
Enum *Enum
|
||||||
Name string
|
Name string
|
||||||
|
IsInternal bool // True if this entry is not part of the WGSL grammar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type declares a type
|
// Type declares a type
|
||||||
|
|
Loading…
Reference in New Issue