]> git.tdb.fi Git - libs/gl.git/commitdiff
Give declaration nodes to all GLSL types.
authorMikko Rasa <tdb@tdb.fi>
Thu, 4 Mar 2021 23:06:46 +0000 (01:06 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 4 Mar 2021 23:16:31 +0000 (01:16 +0200)
Even the builtin ones.  This makes various operations with expressions
easier and helps with SPIR-V.

15 files changed:
builtin_data/_builtin.glsl
source/glsl/builtin.cpp
source/glsl/compiler.cpp
source/glsl/debug.cpp
source/glsl/debug.h
source/glsl/generate.cpp
source/glsl/generate.h
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/validate.cpp
source/glsl/validate.h
source/glsl/visitor.cpp
source/glsl/visitor.h

index f6a3574f52dac374991e348afc309ab117fba570..df39bcc0a49020f4e16baf4cc13e6c4c9da1b604 100644 (file)
@@ -1,3 +1,37 @@
+typedef vector(2) float vec2;
+typedef vector(3) float vec3;
+typedef vector(4) float vec4;
+typedef vector(2) vec2 mat2;
+typedef mat2 mat2x2;
+typedef vector(3) vec2 mat3x2;
+typedef vector(4) vec2 mat4x2;
+typedef vector(2) vec3 mat2x3;
+typedef vector(3) vec3 mat3;
+typedef mat3 mat3x3;
+typedef vector(4) vec3 mat4x3;
+typedef vector(2) vec4 mat2x4;
+typedef vector(3) vec4 mat3x4;
+typedef vector(4) vec4 mat4;
+typedef mat4 mat4x4;
+
+typedef vector(2) int ivec2;
+typedef vector(3) int ivec3;
+typedef vector(4) int ivec4;
+
+typedef image(dimensions=1, sampled) float sampler1D;
+typedef image(dimensions=2, sampled) float sampler2D;
+typedef image(dimensions=3, sampled) float sampler3D;
+typedef image(dimensions=cube, sampled) float samplerCube;
+typedef image(dimensions=1[], sampled) float sampler1DArray;
+typedef image(dimensions=2[], sampled) float sampler2DArray;
+typedef image(dimensions=cube[], sampled) float samplerCubeArray;
+typedef image(dimensions=1, shadow, sampled) float sampler1DShadow;
+typedef image(dimensions=2, shadow, sampled) float sampler2DShadow;
+typedef image(dimensions=1[], shadow, sampled) float sampler1DArrayShadow;
+typedef image(dimensions=2[], shadow, sampled) float sampler2DArrayShadow;
+typedef image(dimensions=cube, shadow, sampled) float samplerCubeShadow;
+typedef image(dimensions=cube[], shadow, sampled) float samplerCubeArrayShadow;
+
 #pragma MSP stage(vertex)
 out gl_PerVertex
 {
index 3800e14bbc0d412552e679f3e2697c514d1deba4..670cfc2d9f4878b1d55abca1cf453adf8c628816 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/gl/resources.h>
 #include <msp/io/seekable.h>
 #include "builtin.h"
+#include "generate.h"
 #include "parser.h"
 
 using namespace std;
@@ -24,6 +25,38 @@ Module *get_builtins_module()
                Parser parser;
                Module *module = new Module(parser.parse(*io, "<builtin>", BUILTIN_SOURCE));
 
+               NodeList<Statement> &shared_body = module->shared.content.body;
+
+               RefPtr<BasicTypeDeclaration> type = new BasicTypeDeclaration;
+               type->source = BUILTIN_SOURCE;
+               type->name = "void";
+               type->kind = BasicTypeDeclaration::VOID;
+               shared_body.insert(shared_body.begin(), type);
+
+               type = new BasicTypeDeclaration;
+               type->source = BUILTIN_SOURCE;
+               type->name = "bool";
+               type->kind = BasicTypeDeclaration::BOOL;
+               shared_body.insert(shared_body.begin(), type);
+
+               type = new BasicTypeDeclaration;
+               type->source = BUILTIN_SOURCE;
+               type->name = "int";
+               type->size = 32;
+               type->kind = BasicTypeDeclaration::INT;
+               shared_body.insert(shared_body.begin(), type);
+
+               type = new BasicTypeDeclaration;
+               type->source = BUILTIN_SOURCE;
+               type->name = "float";
+               type->size = 32;
+               type->kind = BasicTypeDeclaration::FLOAT;
+               shared_body.insert(shared_body.begin(), type);
+
+               TypeResolver().apply(module->shared);
+               for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+                       TypeResolver().apply(*i);
+
                builtins_module = module;
        }
        return builtins_module.get();
index 8caeba1fcf13c600759b7ed53ca790254759b4f1..f5540139e3391cffd1afd1b9f2f8e709fa4b99d5 100644 (file)
@@ -241,12 +241,14 @@ void Compiler::generate(Stage &stage, Mode mode)
 
        // Initial resolving pass
        BlockHierarchyResolver().apply(stage);
+       TypeResolver().apply(stage);
        FunctionResolver().apply(stage);
        VariableResolver().apply(stage);
 
        /* All variables local to a stage have been resolved.  Resolve non-local
        variables through interfaces. */
        InterfaceGenerator().apply(stage);
+       TypeResolver().apply(stage);
        VariableResolver().apply(stage);
 
        FunctionResolver().apply(stage);
@@ -274,6 +276,7 @@ Compiler::OptimizeResult Compiler::optimize(Stage &stage)
        any_inlined |= ExpressionInliner().apply(stage);
        if(any_inlined)
        {
+               TypeResolver().apply(stage);
                VariableResolver().apply(stage);
                FunctionResolver().apply(stage);
        }
index 06bf1925cea7e4102015f999cd198d3b67f4615c..d49b9a5f142e8a09b29bcc304e7c29056b87f412 100644 (file)
@@ -14,7 +14,7 @@ const std::string &DumpTree::apply(Stage &stage)
        tree.push_back(BRANCH);
        append(format("Version: %d.%02d", stage.required_features.glsl_version.major, stage.required_features.glsl_version.minor));
 
-       for(std::map<string, StructDeclaration *>::const_iterator i=stage.types.begin(); i!=stage.types.end(); ++i)
+       for(std::map<string, TypeDeclaration *>::const_iterator i=stage.types.begin(); i!=stage.types.end(); ++i)
                append(format("Type: %%%d %s", get_label(*i->second), i->first));
 
        set<InterfaceBlock *> seen_interfaces;
@@ -236,6 +236,45 @@ void DumpTree::visit(InterfaceLayout &layout)
        annotated_branch(format("Layout: %s", layout.interface), layout.layout);
 }
 
+void DumpTree::visit(BasicTypeDeclaration &type)
+{
+       append(format("%%%d typedef %s", get_label(type), type.name));
+       begin_sub();
+       if(type.kind!=BasicTypeDeclaration::VECTOR && type.kind!=BasicTypeDeclaration::MATRIX)
+               last_branch();
+       if(type.base_type)
+               append(format("%s: %%%d %s", (type.kind==BasicTypeDeclaration::ALIAS ? "Alias of" : "Base"), get_label(*type.base_type), type.base_type->name));
+
+       last_branch();
+       if(type.kind==BasicTypeDeclaration::VECTOR)
+               append(format("Vector: %d", type.size));
+       else if(type.kind==BasicTypeDeclaration::MATRIX)
+               append(format("Matrix: %dx%d", type.size&0xFFFF, type.size>>16));
+       end_sub();
+}
+
+void DumpTree::visit(ImageTypeDeclaration &type)
+{
+       append(format("%%%d typedef %s", get_label(type), type.name));
+       begin_sub();
+
+       if(!type.shadow && !type.base_type)
+               last_branch();
+       static const char *dims[] = { "1D", "2D", "3D", "Cube" };
+       append(format("Dimensions: %s%s", dims[type.dimensions-1], (type.array ? " array" : "")));
+
+       if(!type.shadow)
+               last_branch();
+       if(type.base_type)
+               append(format("Element type: %%%d %s", get_label(*type.base_type), type.base_type->name));
+
+       last_branch();
+       if(type.shadow)
+               append("Shadow");
+
+       end_sub();
+}
+
 void DumpTree::visit(StructDeclaration &strct)
 {
        annotated_branch(format("%%%d struct %s", get_label(strct), strct.name), strct.members);
@@ -262,6 +301,11 @@ void DumpTree::visit(VariableDeclaration &var)
        append(decl);
 
        begin_sub();
+       if(!var.layout && !var.array && !var.init_expression)
+               last_branch();
+       if(var.type_declaration)
+               append(format("Type: %%%d %s", get_label(*var.type_declaration), var.type_declaration->name));
+
        if(!var.array && !var.init_expression)
                last_branch();
        if(var.layout)
index 87ec4734e0b1bda18e4513a481688bbfee693fc0..b377b84488a5cd897645f63ad728d80337262858 100644 (file)
@@ -55,6 +55,8 @@ private:
        virtual void visit(Precision &);
        virtual void visit(Layout &);
        virtual void visit(InterfaceLayout &);
+       virtual void visit(BasicTypeDeclaration &);
+       virtual void visit(ImageTypeDeclaration &);
        virtual void visit(StructDeclaration &);
        virtual void visit(VariableDeclaration &);
        virtual void visit(InterfaceBlock &);
index b91c2e2614ef2d577ce1e501893222eed678507d..c4a29110ffc8783f6d671340a5bdb05f8d0c5759 100644 (file)
@@ -114,6 +114,55 @@ void BlockHierarchyResolver::enter(Block &block)
 }
 
 
+TypeResolver::TypeResolver():
+       stage(0)
+{ }
+
+void TypeResolver::apply(Stage &s)
+{
+       stage = &s;
+       s.types.clear();
+       s.content.visit(*this);
+}
+
+void TypeResolver::visit(BasicTypeDeclaration &type)
+{
+       map<string, TypeDeclaration *>::iterator i = stage->types.find(type.base);
+       type.base_type = (i!=stage->types.end() ? i->second : 0);
+
+       if(type.kind==BasicTypeDeclaration::VECTOR && type.base_type)
+               if(BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type))
+                       if(basic_base->kind==BasicTypeDeclaration::VECTOR)
+                       {
+                               type.kind = BasicTypeDeclaration::MATRIX;
+                               type.size |= basic_base->size<<16;
+                       }
+
+       stage->types.insert(make_pair(type.name, &type));
+}
+
+void TypeResolver::visit(ImageTypeDeclaration &type)
+{
+       map<string, TypeDeclaration *>::iterator i = stage->types.find(type.base);
+       type.base_type = (i!=stage->types.end() ? i->second : 0);
+
+       stage->types.insert(make_pair(type.name, &type));
+}
+
+void TypeResolver::visit(StructDeclaration &strct)
+{
+       stage->types.insert(make_pair(strct.name, &strct));
+       TraversingVisitor::visit(strct);
+}
+
+void TypeResolver::visit(VariableDeclaration &var)
+{
+       map<string, TypeDeclaration *>::iterator i = stage->types.find(var.type);
+       if(i!=stage->types.end())
+               var.type_declaration = i->second;
+}
+
+
 VariableResolver::VariableResolver():
        stage(0),
        r_members(0),
@@ -125,7 +174,6 @@ VariableResolver::VariableResolver():
 void VariableResolver::apply(Stage &s)
 {
        stage = &s;
-       s.types.clear();
        s.interface_blocks.clear();
        s.content.visit(*this);
 }
@@ -151,8 +199,8 @@ void VariableResolver::visit(VariableReference &var)
 
        if(var.declaration)
        {
-               if(var.declaration->type_declaration)
-                       r_members = &var.declaration->type_declaration->members.variables;
+               if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(var.declaration->type_declaration))
+                       r_members = &strct->members.variables;
        }
        else
        {
@@ -228,8 +276,8 @@ void VariableResolver::visit(MemberAccess &memacc)
                if(i!=r_members->end())
                {
                        memacc.declaration = i->second;
-                       if(i->second->type_declaration)
-                               r_members = &i->second->type_declaration->members.variables;
+                       if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(i->second->type_declaration))
+                               r_members = &strct->members.variables;
                }
                else
                        r_members = 0;
@@ -292,18 +340,8 @@ void VariableResolver::visit(FunctionCall &call)
        r_iface_ref = 0;
 }
 
-void VariableResolver::visit(StructDeclaration &strct)
-{
-       TraversingVisitor::visit(strct);
-       stage->types.insert(make_pair(strct.name, &strct));
-}
-
 void VariableResolver::visit(VariableDeclaration &var)
 {
-       map<string, StructDeclaration *>::iterator i = stage->types.find(var.type);
-       if(i!=stage->types.end())
-               var.type_declaration = i->second;
-
        if(!block_interface.empty() && var.interface.empty())
                var.interface = block_interface;
 
index 951a672d89eb3d90bcc38aecdc3fd78b0febebbc..d303af3664b3294c74209b6dce738b999c8213ff 100644 (file)
@@ -55,6 +55,24 @@ private:
        virtual void enter(Block &);
 };
 
+/** Resolves types of variables and base types of other types. */
+class TypeResolver: private TraversingVisitor
+{
+private:
+       Stage *stage;
+
+public:
+       TypeResolver();
+
+       void apply(Stage &);
+
+private:
+       virtual void visit(BasicTypeDeclaration &);
+       virtual void visit(ImageTypeDeclaration &);
+       virtual void visit(StructDeclaration &);
+       virtual void visit(VariableDeclaration &);
+};
+
 /** Resolves variable references.  Variable references which match the name
 of an interface block are turned into interface block references. */
 class VariableResolver: private TraversingVisitor
@@ -82,7 +100,6 @@ private:
        virtual void visit(BinaryExpression &);
        virtual void visit(Assignment &);
        virtual void visit(FunctionCall &);
-       virtual void visit(StructDeclaration &);
        virtual void visit(VariableDeclaration &);
        virtual void visit(InterfaceBlock &);
 };
index 0f7122f50dae119283390b22f51bbae31ce245eb..c9a812ddbd62f8c45184d565186404b33541f410 100644 (file)
@@ -2,6 +2,7 @@
 #include <msp/strings/format.h>
 #include <msp/strings/regex.h>
 #include <msp/strings/utils.h>
+#include "builtin.h"
 #include "glsl_error.h"
 #include "parser.h"
 
@@ -53,11 +54,27 @@ void Parser::parse_source(const string &name, int index)
 {
        delete module;
        module = new Module;
+
        cur_stage = &module->shared;
        base_index = index;
        source_index = index;
        if(index>=0)
                source_reference(1, name);
+
+       // TODO Need to somehow get type names from imports
+       if(const Stage *builtin = get_builtins(Stage::SHARED))
+       {
+               for(map<string, TypeDeclaration *>::const_iterator i=builtin->types.begin(); i!=builtin->types.end(); ++i)
+                       declared_types.insert(i->first);
+       }
+       else
+       {
+               declared_types.insert("void");
+               declared_types.insert("bool");
+               declared_types.insert("int");
+               declared_types.insert("float");
+       }
+
        tokenizer.begin(source, name);
        allow_stage_change = true;
        while(!tokenizer.peek_token().empty())
@@ -171,15 +188,9 @@ bool Parser::is_qualifier(const string &token)
                is_precision_qualifier(token));
 }
 
-bool Parser::is_builtin_type(const string &token)
-{
-       static Regex re("^(void|float|int|bool|[ib]?vec[234]|mat[234](x[234])?|sampler((1D|2D|Cube)(Array)?(Shadow)?|3D))$");
-       return re.match(token);
-}
-
 bool Parser::is_type(const string &token)
 {
-       return is_builtin_type(token) || declared_types.count(token);
+       return declared_types.count(token);
 }
 
 bool Parser::is_identifier(const string &token)
@@ -269,6 +280,8 @@ RefPtr<Statement> Parser::parse_global_declaration()
                        return var;
                }
        }
+       else if(token=="typedef")
+               return parse_type_declaration();
        else if(token=="struct")
                return parse_struct_declaration();
        else if(is_interface_qualifier(token))
@@ -355,10 +368,8 @@ RefPtr<Precision> Parser::parse_precision()
        if(!is_precision_qualifier(precision->precision))
                throw parse_error(tokenizer.get_location(), precision->precision, "a precision qualifier");
 
-       precision->type = tokenizer.parse_token();
-       // Not entirely accurate; only float, int and sampler types are allowed
-       if(!is_builtin_type(precision->type))
-               throw parse_error(tokenizer.get_location(), precision->type, "a builtin type");
+       // TODO Add validation for this
+       precision->type = expect_type();
 
        tokenizer.expect(";");
 
@@ -545,6 +556,98 @@ RefPtr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
        return call;
 }
 
+RefPtr<TypeDeclaration> Parser::parse_type_declaration()
+{
+       tokenizer.expect("typedef");
+
+       RefPtr<TypeDeclaration> type;
+       if(tokenizer.peek_token()=="image")
+               type = parse_image_type_declaration();
+       else
+               type = parse_basic_type_declaration();
+
+       tokenizer.expect(";");
+       declared_types.insert(type->name);
+       return type;
+}
+
+RefPtr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
+{
+       RefPtr<BasicTypeDeclaration> type = create_node<BasicTypeDeclaration>();
+
+       if(tokenizer.peek_token()=="vector")
+       {
+               type->kind = BasicTypeDeclaration::VECTOR;
+
+               tokenizer.parse_token();
+               tokenizer.expect("(");
+               type->size = expect_integer();
+               tokenizer.expect(")");
+       }
+
+       type->base = expect_type();
+       type->name = expect_identifier();
+
+       if(type->kind==BasicTypeDeclaration::ALIAS && check("["))
+       {
+               type->kind = BasicTypeDeclaration::ARRAY;
+               tokenizer.expect("]");
+       }
+
+       return type;
+}
+
+RefPtr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
+{
+       tokenizer.expect("image");
+       tokenizer.expect("(");
+
+       RefPtr<ImageTypeDeclaration> type = create_node<ImageTypeDeclaration>();
+       while(1)
+       {
+               string token = tokenizer.parse_token();
+               if(token=="dimensions")
+               {
+                       tokenizer.expect("=");
+                       token = tokenizer.parse_token();
+                       if(token=="1")
+                               type->dimensions = ImageTypeDeclaration::ONE;
+                       else if(token=="2")
+                               type->dimensions = ImageTypeDeclaration::TWO;
+                       else if(token=="3")
+                               type->dimensions = ImageTypeDeclaration::THREE;
+                       else if(token=="cube")
+                               type->dimensions = ImageTypeDeclaration::CUBE;
+                       else
+                               throw parse_error(tokenizer.get_location(), token, "dimensions");
+
+                       if(check("["))
+                       {
+                               type->array = true;
+                               tokenizer.expect("]");
+                       }
+               }
+               else if(token=="sampled")
+                       type->sampled = true;
+               else if(token=="shadow")
+                       type->shadow = true;
+               else
+                       throw parse_error(tokenizer.get_location(), token, "image type attribute");
+
+               token = tokenizer.peek_token();
+               if(token==")")
+                       break;
+
+               tokenizer.expect(",");
+       }
+       tokenizer.expect(")");
+
+       type->base = expect_type();
+       type->name = expect_identifier();
+
+       return type;
+}
+
 RefPtr<StructDeclaration> Parser::parse_struct_declaration()
 {
        tokenizer.expect("struct");
index 21d86e9d488d875f6c09d5b9687ba26c9ed1986d..26867ec4dcd881230229b253927457ba1f1a72d7 100644 (file)
@@ -50,7 +50,6 @@ private:
        static bool is_interpolation_qualifier(const std::string &);
        static bool is_precision_qualifier(const std::string &);
        static bool is_qualifier(const std::string &);
-       static bool is_builtin_type(const std::string &);
        bool is_type(const std::string &);
        bool is_identifier(const std::string &);
 
@@ -74,6 +73,9 @@ private:
        RefPtr<Expression> parse_expression(unsigned = 0);
        RefPtr<BinaryExpression> parse_binary(const RefPtr<Expression> &, const Operator &);
        RefPtr<FunctionCall> parse_function_call(const VariableReference &);
+       RefPtr<TypeDeclaration> parse_type_declaration();
+       RefPtr<BasicTypeDeclaration> parse_basic_type_declaration();
+       RefPtr<ImageTypeDeclaration> parse_image_type_declaration();
        RefPtr<StructDeclaration> parse_struct_declaration();
        RefPtr<VariableDeclaration> parse_variable_declaration();
        RefPtr<VariableDeclaration> parse_variable_declaration_with_layout();
index 931578640b94fc4f874b25648dfef01fd0330c0d..e20d6c262eae2525a0a979922c800e9956f39f18 100644 (file)
@@ -237,6 +237,39 @@ void InterfaceLayout::visit(NodeVisitor &visitor)
 }
 
 
+BasicTypeDeclaration::BasicTypeDeclaration():
+       kind(ALIAS),
+       size(0),
+       base_type(0)
+{ }
+
+BasicTypeDeclaration::BasicTypeDeclaration(const BasicTypeDeclaration &other):
+       TypeDeclaration(other),
+       kind(other.kind),
+       size(other.size),
+       base(other.base),
+       base_type(0)
+{ }
+
+void BasicTypeDeclaration::visit(NodeVisitor &visitor)
+{
+       visitor.visit(*this);
+}
+
+
+ImageTypeDeclaration::ImageTypeDeclaration():
+       dimensions(TWO),
+       array(false),
+       sampled(true),
+       shadow(false)
+{ }
+
+void ImageTypeDeclaration::visit(NodeVisitor &visitor)
+{
+       visitor.visit(*this);
+}
+
+
 StructDeclaration::StructDeclaration()
 {
        members.use_braces = true;
index f275eab8c4ae454ee369ac10e40d3c0e4499190a..62c289d9fbb6ec48f61be268b7eec67072718e98 100644 (file)
@@ -285,9 +285,66 @@ struct InterfaceLayout: Statement
        virtual void visit(NodeVisitor &);
 };
 
-struct StructDeclaration: Statement
+struct TypeDeclaration: Statement
 {
        std::string name;
+
+       virtual TypeDeclaration *clone() const = 0;
+};
+
+struct BasicTypeDeclaration: TypeDeclaration
+{
+       enum Kind
+       {
+               ALIAS,
+               VOID,
+               BOOL,
+               INT,
+               FLOAT,
+               VECTOR,
+               MATRIX,
+               ARRAY
+       };
+
+       Kind kind;
+       unsigned size;
+       std::string base;
+
+       TypeDeclaration *base_type;
+
+       BasicTypeDeclaration();
+       BasicTypeDeclaration(const BasicTypeDeclaration &);
+
+       virtual BasicTypeDeclaration *clone() const { return new BasicTypeDeclaration(*this); }
+       virtual void visit(NodeVisitor &);
+};
+
+struct ImageTypeDeclaration: TypeDeclaration
+{
+       enum Dimensions
+       {
+               ONE = 1,
+               TWO,
+               THREE,
+               CUBE
+       };
+
+       Dimensions dimensions;
+       bool array;
+       bool sampled;
+       bool shadow;
+       std::string base;
+
+       TypeDeclaration *base_type;
+
+       ImageTypeDeclaration();
+
+       virtual ImageTypeDeclaration *clone() const { return new ImageTypeDeclaration(*this); }
+       virtual void visit(NodeVisitor &);
+};
+
+struct StructDeclaration: TypeDeclaration
+{
        Block members;
 
        StructDeclaration();
@@ -310,7 +367,7 @@ struct VariableDeclaration: Statement
        NodePtr<Expression> array_size;
        NodePtr<Expression> init_expression;
 
-       StructDeclaration *type_declaration;
+       TypeDeclaration *type_declaration;
        VariableDeclaration *linked_declaration;
 
        VariableDeclaration();
@@ -413,7 +470,7 @@ struct Stage
        Type type;
        Stage *previous;
        Block content;
-       std::map<std::string, StructDeclaration *> types;
+       std::map<std::string, TypeDeclaration *> types;
        std::map<std::string, InterfaceBlock *> interface_blocks;
        std::map<std::string, FunctionDeclaration *> functions;
        std::map<std::string, unsigned> locations;
index 78d3bb4be6a82ba919ef2a6dca4d61fc232fd5de..6d0f8e51ac2cb9a95ee94883f8a7449f0c97fa44 100644 (file)
@@ -60,6 +60,11 @@ void DeclarationValidator::record_definition(const string &name, Statement &stat
                declarations[current_block->parent].insert(make_pair(name, &statement));
 }
 
+void DeclarationValidator::visit(TypeDeclaration &type)
+{
+       check_definition(type.name, type);
+}
+
 void DeclarationValidator::visit(StructDeclaration &strct)
 {
        check_definition(strct.name, strct);
index 01f2ba4f82c75d6ce76cba2c77eef6eb43d7f707..c723b995567f869330d0c4f393278c824c33cab8 100644 (file)
@@ -41,6 +41,9 @@ private:
        void check_definition(const std::string &, Statement &);
        void record_definition(const std::string &, Statement &);
 
+       virtual void visit(TypeDeclaration &);
+       virtual void visit(BasicTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
+       virtual void visit(ImageTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
        virtual void visit(StructDeclaration &);
        virtual void visit(VariableDeclaration &);
        virtual void visit(InterfaceBlock &);
index fa6e614c6394a1705e4d45b6214fc55efbc760a1..bee312fd187d333fd94ef529d81d5fa489898f58 100644 (file)
@@ -154,10 +154,10 @@ void NodeRemover::visit(Block &block)
        }
 }
 
-void NodeRemover::visit(StructDeclaration &strct)
+void NodeRemover::visit(TypeDeclaration &type)
 {
-       if(to_remove->count(&strct))
-               remove_from_map(stage->types, strct.name, strct);
+       if(to_remove->count(&type))
+               remove_from_map(stage->types, type.name, type);
 }
 
 void NodeRemover::visit(VariableDeclaration &var)
index cd9dafb0b016338eb2f8a12c58e1eb94eeb48a8c..6fe1868ca8221a4619fc30cb889524b68f7b9f9e 100644 (file)
@@ -32,6 +32,8 @@ public:
        virtual void visit(Precision &) { }
        virtual void visit(Layout &) { }
        virtual void visit(InterfaceLayout &) { }
+       virtual void visit(BasicTypeDeclaration &) { }
+       virtual void visit(ImageTypeDeclaration &) { }
        virtual void visit(StructDeclaration &) { }
        virtual void visit(VariableDeclaration &) { }
        virtual void visit(InterfaceBlock &) { }
@@ -104,7 +106,10 @@ private:
        void remove_from_map(std::map<std::string, T *> &, const std::string &, T &);
 
        virtual void visit(Block &);
-       virtual void visit(StructDeclaration &);
+       void visit(TypeDeclaration &);
+       virtual void visit(BasicTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
+       virtual void visit(ImageTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
+       virtual void visit(StructDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
        virtual void visit(VariableDeclaration &);
        virtual void visit(InterfaceBlock &);
        virtual void visit(FunctionDeclaration &);