diff --git a/src/parse.fs b/src/parse.fs index 0a0a6d89..61182fa9 100644 --- a/src/parse.fs +++ b/src/parse.fs @@ -159,15 +159,7 @@ type private ParseImpl() = // A type block, like struct or interface blocks let blockSpecifier prefix = - - // Restriction on field names - let check ((_,l) as arg : Ast.Decl) = - for decl in l do - if decl.name.Name <> Rewriter.renameField decl.name.Name then - failwithf "Record field name '%s' is not allowed by Shader Minifier,\nbecause it looks like a vec4 field name." decl.name.Name - arg - - let decls = many (declaration .>> ch ';' |>> check) + let decls = many (declaration .>> ch ';') let name = opt ident pipe2 name (between (ch '{') (ch '}') decls) (fun n d -> diff --git a/src/renamer.fs b/src/renamer.fs index 782bbe97..f5121ea0 100644 --- a/src/renamer.fs +++ b/src/renamer.fs @@ -4,6 +4,11 @@ open System.Collections.Generic open Ast open Options.Globals +let renameField field = + if Builtin.isFieldSwizzle field then + field |> String.map (fun c -> options.canonicalFieldNames.[Builtin.swizzleIndex c]) + else field + module private RenamerImpl = // Environment for renamer @@ -328,10 +333,24 @@ module private RenamerImpl = renList env renCase cl |> ignore env + let renStructElts (decls: Decl list) = + let allFields = Dictionary() + for _, elts in decls do + for elt in elts do + let newName = renameField elt.name.Name + match allFields.TryGetValue(newName) with + | true, conflict -> + failwithf "Field '%s' will conflict with field '%s' after renaming: both will be named '%s'" elt.name.Name conflict newName + | _ -> + allFields.[newName] <- elt.name.Name + elt.name.Rename(newName) + // e.g. struct foo { int a; float b; } // or uniform foo { int a; float b; } let renTyBlock (env: Env) = function - | TypeBlock("struct", _, _) -> env + | TypeBlock("struct", _, fields) -> + renStructElts fields + env | TypeBlock(_, _, fields) -> // treat the fields as if they were global variables renList env (renDecl Level.TopLevel) fields diff --git a/src/rewriter.fs b/src/rewriter.fs index 644c872e..d029818c 100644 --- a/src/rewriter.fs +++ b/src/rewriter.fs @@ -6,11 +6,6 @@ open Builtin open Ast open Options.Globals -let renameField field = - if isFieldSwizzle field then - field |> String.map (fun c -> options.canonicalFieldNames.[swizzleIndex c]) - else field - let private commaSeparatedExprs = List.reduce (fun a b -> FunCall(Op ",", [a; b])) let rec private sideEffects = function @@ -336,7 +331,7 @@ module private RewriterImpl = | FunCall(Var constr, args) when constr.Name = "vec2" || constr.Name = "vec3" || constr.Name = "vec4" -> simplifyVec constr args - | Dot(e, field) when options.canonicalFieldNames <> "" -> Dot(e, renameField field) + | Dot(e, field) when options.canonicalFieldNames <> "" -> Dot(e, Renamer.renameField field) | Var s as e -> match env.vars.TryFind s.Name with diff --git a/tests/commands.txt b/tests/commands.txt index eb400f3a..f0ea2193 100644 --- a/tests/commands.txt +++ b/tests/commands.txt @@ -33,6 +33,7 @@ --no-remove-unused --format indented -o tests/unit/interface_block.frag.expected tests/unit/interface_block.frag --no-remove-unused --no-renaming --format indented -o tests/unit/ternary.frag.expected tests/unit/ternary.frag --no-remove-unused --no-renaming --format indented -o tests/unit/reuse-var.frag.expected tests/unit/reuse-var.frag +--no-remove-unused --format indented -o tests/unit/struct.frag.expected tests/unit/struct.frag # Unused removal tests diff --git a/tests/unit/struct.frag b/tests/unit/struct.frag new file mode 100644 index 00000000..d8c7795c --- /dev/null +++ b/tests/unit/struct.frag @@ -0,0 +1,14 @@ +struct Foo { + int field1; + int field2; + int ab; + int st; +}; + +void main() { + Foo f; + f.field1 = 1; + f.field2 = 2; + f.ab = 3; + f.st = 4; +} diff --git a/tests/unit/struct.frag.expected b/tests/unit/struct.frag.expected new file mode 100644 index 00000000..a6119c8b --- /dev/null +++ b/tests/unit/struct.frag.expected @@ -0,0 +1,9 @@ +struct Foo{int field1;int field2;int wz;int xy;}; +void main() +{ + Foo i; + i.field1=1; + i.field2=2; + i.wz=3; + i.xy=4; +}