]> git.tdb.fi Git - libs/gl.git/commitdiff
Record location information in all syntax nodes
authorMikko Rasa <tdb@tdb.fi>
Thu, 4 Mar 2021 22:27:31 +0000 (00:27 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 4 Mar 2021 23:14:57 +0000 (01:14 +0200)
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/validate.cpp
source/glsl/validate.h

index b09d2b5550b47c321fba2a69feedc4d7c36f0293..0f7122f50dae119283390b22f51bbae31ce245eb 100644 (file)
@@ -188,6 +188,15 @@ bool Parser::is_identifier(const string &token)
        return re.match(token);
 }
 
+template<typename T>
+RefPtr<T> Parser::create_node()
+{
+       RefPtr<T> node = new T;
+       node->source = source_index;
+       node->line = tokenizer.get_location().line;
+       return node;
+}
+
 template<typename T>
 RefPtr<T> Parser::parse_with_recovery(RefPtr<T> (Parser::*parse_func)())
 {
@@ -247,9 +256,7 @@ RefPtr<Statement> Parser::parse_global_declaration()
                token = tokenizer.peek_token();
                if(is_interface_qualifier(token) && tokenizer.peek_token(1)==";")
                {
-                       RefPtr<InterfaceLayout> iface_lo = new InterfaceLayout;
-                       iface_lo->source = source_index;
-                       iface_lo->line = tokenizer.get_location().line;
+                       RefPtr<InterfaceLayout> iface_lo = create_node<InterfaceLayout>();
                        iface_lo->layout.qualifiers = layout->qualifiers;
                        iface_lo->interface = tokenizer.parse_token();
                        tokenizer.expect(";");
@@ -302,9 +309,7 @@ RefPtr<Statement> Parser::parse_statement()
                return parse_return();
        else if(token=="break" || token=="continue" || token=="discard")
        {
-               RefPtr<Jump> jump = new Jump;
-               jump->source = source_index;
-               jump->line = tokenizer.get_location().line;
+               RefPtr<Jump> jump = create_node<Jump>();
                jump->keyword = tokenizer.parse_token();
                tokenizer.expect(";");
 
@@ -319,9 +324,7 @@ RefPtr<Statement> Parser::parse_statement()
        }
        else if(!token.empty())
        {
-               RefPtr<ExpressionStatement> expr = new ExpressionStatement;
-               expr->source = source_index;
-               expr->line = tokenizer.get_location().line;
+               RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
                expr->expression = parse_expression();
                tokenizer.expect(";");
 
@@ -337,9 +340,7 @@ RefPtr<Import> Parser::parse_import()
                throw invalid_shader_source(tokenizer.get_location(), "Imports are only allowed in the shared section");
 
        tokenizer.expect("import");
-       RefPtr<Import> import = new Import;
-       import->source = source_index;
-       import->line = tokenizer.get_location().line;
+       RefPtr<Import> import = create_node<Import>();
        import->module = expect_identifier();
        tokenizer.expect(";");
        return import;
@@ -348,9 +349,7 @@ RefPtr<Import> Parser::parse_import()
 RefPtr<Precision> Parser::parse_precision()
 {
        tokenizer.expect("precision");
-       RefPtr<Precision> precision = new Precision;
-       precision->source = source_index;
-       precision->line = tokenizer.get_location().line;
+       RefPtr<Precision> precision = create_node<Precision>();
 
        precision->precision = tokenizer.parse_token();
        if(!is_precision_qualifier(precision->precision))
@@ -370,7 +369,7 @@ RefPtr<Layout> Parser::parse_layout()
 {
        tokenizer.expect("layout");
        tokenizer.expect("(");
-       RefPtr<Layout> layout = new Layout;
+       RefPtr<Layout> layout = create_node<Layout>();
        while(1)
        {
                string token = tokenizer.parse_token();
@@ -454,7 +453,7 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        }
                        else if(token==".")
                        {
-                               RefPtr<MemberAccess> memacc = new MemberAccess;
+                               RefPtr<MemberAccess> memacc = create_node<MemberAccess>();
                                memacc->left = left;
                                memacc->oper = oper;
                                tokenizer.parse_token();
@@ -463,7 +462,7 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        }
                        else if(oper && oper->type==Operator::POSTFIX)
                        {
-                               RefPtr<UnaryExpression> unary = new UnaryExpression;
+                               RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
                                unary->oper = oper;
                                tokenizer.parse_token();
                                unary->expression = left;
@@ -480,7 +479,7 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        if(token=="(")
                        {
                                tokenizer.parse_token();
-                               RefPtr<ParenthesizedExpression> parexpr = new ParenthesizedExpression;
+                               RefPtr<ParenthesizedExpression> parexpr = create_node<ParenthesizedExpression>();
                                parexpr->expression = parse_expression();
                                tokenizer.expect(")");
                                left = parexpr;
@@ -493,14 +492,14 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
                        }
                        else if(is_identifier(token))
                        {
-                               RefPtr<VariableReference> var = new VariableReference;
+                               RefPtr<VariableReference> var = create_node<VariableReference>();
                                var->name = expect_identifier();
                                left = var;
                                left_var = var.get();
                        }
                        else if(oper && oper->type==Operator::PREFIX)
                        {
-                               RefPtr<UnaryExpression> unary = new UnaryExpression;
+                               RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
                                unary->oper = oper;
                                tokenizer.parse_token();
                                unary->expression = parse_expression(oper->precedence);
@@ -514,7 +513,8 @@ RefPtr<Expression> Parser::parse_expression(unsigned precedence)
 
 RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, const Operator &oper)
 {
-       RefPtr<BinaryExpression> binary = (oper.precedence==16 ? new Assignment : new BinaryExpression);
+       RefPtr<BinaryExpression> binary = (oper.precedence==16 ?
+               static_cast<RefPtr<BinaryExpression> >(create_node<Assignment>()) : create_node<BinaryExpression>());
        binary->left = left;
        binary->oper = &oper;
        tokenizer.expect(oper.token);
@@ -530,7 +530,7 @@ RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, co
 
 RefPtr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
 {
-       RefPtr<FunctionCall> call = new FunctionCall;
+       RefPtr<FunctionCall> call = create_node<FunctionCall>();
        call->name = var.name;
        call->constructor = is_type(call->name);
        call->oper = &Operator::get_operator("(", Operator::POSTFIX);
@@ -548,9 +548,7 @@ RefPtr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
 RefPtr<StructDeclaration> Parser::parse_struct_declaration()
 {
        tokenizer.expect("struct");
-       RefPtr<StructDeclaration> strct = new StructDeclaration;
-       strct->source = source_index;
-       strct->line = tokenizer.get_location().line;
+       RefPtr<StructDeclaration> strct = create_node<StructDeclaration>();
 
        strct->name = expect_identifier();
        parse_block(strct->members, true, &Parser::parse_variable_declaration);
@@ -562,9 +560,7 @@ RefPtr<StructDeclaration> Parser::parse_struct_declaration()
 
 RefPtr<VariableDeclaration> Parser::parse_variable_declaration()
 {
-       RefPtr<VariableDeclaration> var = new VariableDeclaration;
-       var->source = source_index;
-       var->line = tokenizer.get_location().line;
+       RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
 
        string token = tokenizer.peek_token();
        while(is_qualifier(token))
@@ -617,9 +613,7 @@ RefPtr<VariableDeclaration> Parser::parse_variable_declaration_with_layout()
 
 RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
 {
-       RefPtr<FunctionDeclaration> func = new FunctionDeclaration;
-       func->source = source_index;
-       func->line = tokenizer.get_location().line;
+       RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
 
        func->return_type = expect_type();
        func->name = expect_identifier();
@@ -629,7 +623,7 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
                if(!func->parameters.empty())
                        tokenizer.expect(",");
 
-               RefPtr<VariableDeclaration> var = new VariableDeclaration;
+               RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
                string token = tokenizer.peek_token();
                if(token=="in" || token=="out" || token=="inout")
                        var->interface = tokenizer.parse_token();
@@ -655,9 +649,7 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
 
 RefPtr<InterfaceBlock> Parser::parse_interface_block()
 {
-       RefPtr<InterfaceBlock> iface = new InterfaceBlock;
-       iface->source = source_index;
-       iface->line = tokenizer.get_location().line;
+       RefPtr<InterfaceBlock> iface = create_node<InterfaceBlock>();
 
        iface->interface = tokenizer.parse_token();
        if(!is_interface_qualifier(iface->interface))
@@ -682,9 +674,7 @@ RefPtr<InterfaceBlock> Parser::parse_interface_block()
 RefPtr<Conditional> Parser::parse_conditional()
 {
        tokenizer.expect("if");
-       RefPtr<Conditional> cond = new Conditional;
-       cond->source = source_index;
-       cond->line = tokenizer.get_location().line;
+       RefPtr<Conditional> cond = create_node<Conditional>();
        tokenizer.expect("(");
        cond->condition = parse_expression();
        tokenizer.expect(")");
@@ -704,9 +694,7 @@ RefPtr<Conditional> Parser::parse_conditional()
 RefPtr<Iteration> Parser::parse_for()
 {
        tokenizer.expect("for");
-       RefPtr<Iteration> loop = new Iteration;
-       loop->source = source_index;
-       loop->line = tokenizer.get_location().line;
+       RefPtr<Iteration> loop = create_node<Iteration>();
        tokenizer.expect("(");
        string token = tokenizer.peek_token();
        if(is_type(token))
@@ -715,7 +703,7 @@ RefPtr<Iteration> Parser::parse_for()
        {
                if(token!=";")
                {
-                       RefPtr<ExpressionStatement> expr = new ExpressionStatement;
+                       RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
                        expr->expression = parse_expression();
                        loop->init_statement = expr;
                }
@@ -736,9 +724,7 @@ RefPtr<Iteration> Parser::parse_for()
 RefPtr<Iteration> Parser::parse_while()
 {
        tokenizer.expect("while");
-       RefPtr<Iteration> loop = new Iteration;
-       loop->source = source_index;
-       loop->line = tokenizer.get_location().line;
+       RefPtr<Iteration> loop = create_node<Iteration>();
        tokenizer.expect("(");
        loop->condition = parse_expression();
        tokenizer.expect(")");
@@ -751,9 +737,7 @@ RefPtr<Iteration> Parser::parse_while()
 RefPtr<Passthrough> Parser::parse_passthrough()
 {
        tokenizer.expect("passthrough");
-       RefPtr<Passthrough> pass = new Passthrough;
-       pass->source = source_index;
-       pass->line = tokenizer.get_location().line;
+       RefPtr<Passthrough> pass = create_node<Passthrough>();
        if(cur_stage->type==Stage::GEOMETRY)
        {
                tokenizer.expect("[");
@@ -767,9 +751,7 @@ RefPtr<Passthrough> Parser::parse_passthrough()
 RefPtr<Return> Parser::parse_return()
 {
        tokenizer.expect("return");
-       RefPtr<Return> ret = new Return;
-       ret->source = source_index;
-       ret->line = tokenizer.get_location().line;
+       RefPtr<Return> ret = create_node<Return>();
        if(tokenizer.peek_token()!=";")
                ret->expression = parse_expression();
        tokenizer.expect(";");
index 376ccc6cd77fa996d02aeff1aa0baf59aea6167b..21d86e9d488d875f6c09d5b9687ba26c9ed1986d 100644 (file)
@@ -60,9 +60,11 @@ private:
        void preprocess_pragma_msp();
        void preprocess_stage();
 
-       RefPtr<Statement> parse_global_declaration();
+       template<typename T>
+       RefPtr<T> create_node();
        template<typename T>
        RefPtr<T> parse_with_recovery(RefPtr<T> (Parser::*)());
+       RefPtr<Statement> parse_global_declaration();
        RefPtr<Statement> parse_statement();
        RefPtr<Import> parse_import();
        RefPtr<Precision> parse_precision();
index b74f482aa8df5a21dfffebc23c2f2b6fb8a8dd21..931578640b94fc4f874b25648dfef01fd0330c0d 100644 (file)
@@ -75,12 +75,6 @@ NodeContainer<C>::NodeContainer(const NodeContainer &c):
 }
 
 
-Statement::Statement():
-       source(GENERATED_SOURCE),
-       line(1)
-{ }
-
-
 Block::Block():
        use_braces(false),
        parent(0)
index da7b0907e37460d5b7041d32e2c921dee9473563..f275eab8c4ae454ee369ac10e40d3c0e4499190a 100644 (file)
@@ -55,9 +55,11 @@ struct NodeVisitor;
 
 struct Node
 {
-protected:
-       Node() { }
-       Node(const Node &) { }
+       int source;
+       unsigned line;
+
+       Node(): source(GENERATED_SOURCE), line(1) { }
+       Node(const Node &n): source(n.source), line(n.line) { }
 private:
        Node &operator=(const Node &);
 public:
@@ -106,11 +108,6 @@ struct FunctionDeclaration;
 
 struct Statement: Node
 {
-       int source;
-       unsigned line;
-
-       Statement();
-
        virtual Statement *clone() const = 0;
 };
 
index 1e967dc88f6f4d54f0e54f9a1f90cb499aaf7c86..78d3bb4be6a82ba919ef2a6dca4d61fc232fd5de 100644 (file)
@@ -12,15 +12,12 @@ Validator::Validator():
        stage(0)
 { }
 
-void Validator::diagnose(Statement *statement, Diagnostic::Severity severity, const string &message)
+void Validator::diagnose(Node &node, Diagnostic::Severity severity, const string &message)
 {
        Diagnostic diag;
        diag.severity = severity;
-       if(statement)
-       {
-               diag.source = statement->source;
-               diag.line = statement->line;
-       }
+       diag.source = node.source;
+       diag.line = node.line;
        diag.message = message;
        stage->diagnostics.push_back(diag);
 }
@@ -32,8 +29,8 @@ DeclarationValidator::DeclarationValidator():
 
 void DeclarationValidator::multiple_definition(const string &name, Statement &statement, Statement &previous)
 {
-       error(&statement, format("Multiple definition of %s", name));
-       diagnose(&previous, Diagnostic::INFO, "Previous definition is here");
+       error(statement, format("Multiple definition of %s", name));
+       diagnose(previous, Diagnostic::INFO, "Previous definition is here");
 }
 
 Statement *DeclarationValidator::find_definition(const string &name)
index 6149fd7f9b439fac7d26c01d7b59ce037624f62c..01f2ba4f82c75d6ce76cba2c77eef6eb43d7f707 100644 (file)
@@ -17,8 +17,8 @@ protected:
 
        Validator();
 
-       void diagnose(Statement *, Diagnostic::Severity, const std::string &);
-       void error(Statement *s, const std::string &m) { diagnose(s, Diagnostic::ERR, m); }
+       void diagnose(Node &, Diagnostic::Severity, const std::string &);
+       void error(Node &n, const std::string &m) { diagnose(n, Diagnostic::ERR, m); }
 };
 
 class DeclarationValidator: private Validator