From 73f77a0b8e3f3bec4c42392a5840cc2c5966f33c Mon Sep 17 00:00:00 2001
From: Rhys Weatherley <rhys.weatherley@nokia.com>
Date: Fri, 12 Nov 2010 09:53:08 +1000
Subject: [PATCH] Making GLSL AST nodes while preserving lineno info

Eventually we will need some way to locate an identifier's
definition, so add "lineno" to each AST node.  May want to
change this to "position" later.  The makeAstNode<T>() function
takes care of automatically decorating nodes with line numbers.
---
 src/libs/glsl/glsl.g         |  56 ++-
 src/libs/glsl/glslast.h      |   5 +-
 src/libs/glsl/glslparser.cpp | 646 +++++++++++++++++------------------
 src/libs/glsl/glslparser.h   |  42 +++
 4 files changed, 417 insertions(+), 332 deletions(-)

diff --git a/src/libs/glsl/glsl.g b/src/libs/glsl/glsl.g
index d851c25037c..9472eb4a10e 100644
--- a/src/libs/glsl/glsl.g
+++ b/src/libs/glsl/glsl.g
@@ -242,6 +242,7 @@
 #include "$header"
 #include "glsllexer.h"
 #include "glslast.h"
+#include "glslengine.h"
 #include <vector>
 #include <stack>
 
@@ -279,10 +280,51 @@ private:
     inline int tokenKind(int index) const { return _tokens.at(index).kind; }
     void reduce(int ruleno);
 
+    template <typename T>
+    T *makeAstNode()
+    {
+        T *node = new (_engine->pool()) T ();
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1>
+    T *makeAstNode(A1 a1)
+    {
+        T *node = new (_engine->pool()) T (a1);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2>
+    T *makeAstNode(A1 a1, A2 a2)
+    {
+        T *node = new (_engine->pool()) T (a1, a2);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2, typename A3>
+    T *makeAstNode(A1 a1, A2 a2, A3 a3)
+    {
+        T *node = new (_engine->pool()) T (a1, a2, a3);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2, typename A3, typename A4>
+    T *makeAstNode(A1 a1, A2 a2, A3 a3, A4 a4)
+    {
+        T *node = new (_engine->pool()) T (a1, a2, a3, a4);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
 private:
     Engine *_engine;
     int _tos;
     int _index;
+    int yyloc;
     std::vector<int> _stateStack;
     std::vector<int> _locationStack;
     std::vector<Value> _symStack;
@@ -331,7 +373,7 @@ private:
 using namespace GLSL;
 
 Parser::Parser(Engine *engine, const char *source, unsigned size, int variant)
-    : _engine(engine), _tos(-1), _index(0)
+    : _engine(engine), _tos(-1), _index(0), yyloc(-1)
 {
     _tokens.reserve(1024);
 
@@ -398,7 +440,7 @@ TranslationUnit *Parser::parse()
 {
     int action = 0;
     int yytoken = -1;
-    int yyloc = -1;
+    yyloc = -1;
     void *yyval = 0; // value of the current token.
 
     _tos = -1;
@@ -465,7 +507,7 @@ switch(ruleno) {
 variable_identifier ::= IDENTIFIER ;
 /.
 case $rule_number: {
-    ast(1) = new (_engine->pool()) IdentifierExpression(sym(1).string);
+    ast(1) = makeAstNode<IdentifierExpression>(sym(1).string);
 }   break;
 ./
 
@@ -703,7 +745,7 @@ case $rule_number: {
 multiplicative_expression ::= multiplicative_expression STAR unary_expression ;
 /.
 case $rule_number: {
-    ast(1) = new (_engine->pool()) BinaryExpression(AST::Kind_Multiply, sym(1).expression, sym(3).expression);
+    ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Multiply, sym(1).expression, sym(3).expression);
 }   break;
 ./
 
@@ -2600,21 +2642,21 @@ case $rule_number: {
 translation_unit ::= external_declaration_list ;
 /.
 case $rule_number: {
-    ast(1) = new (_engine->pool()) TranslationUnit(sym(1).declaration_list);
+    ast(1) = makeAstNode<TranslationUnit>(sym(1).declaration_list);
 }   break;
 ./
 
 external_declaration_list ::= external_declaration ;
 /.
 case $rule_number: {
-    sym(1).declaration_list = new (_engine->pool()) List<Declaration *>(sym(1).declaration);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >(sym(1).declaration);
 }   break;
 ./
 
 external_declaration_list ::= external_declaration_list external_declaration ;
 /.
 case $rule_number: {
-    sym(1).declaration_list = new (_engine->pool())  List<Declaration *>(sym(1).declaration_list, sym(2).declaration);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >(sym(1).declaration_list, sym(2).declaration);
 }   break;
 ./
 
diff --git a/src/libs/glsl/glslast.h b/src/libs/glsl/glslast.h
index 7be3cae9a61..3fc5a961578 100644
--- a/src/libs/glsl/glslast.h
+++ b/src/libs/glsl/glslast.h
@@ -70,10 +70,10 @@ class GLSL_EXPORT List: public Managed
 {
 public:
     List(const T &value)
-        : value(value), next(this) {}
+        : value(value), next(this), lineno(0) {}
 
     List(List *previous, const T &value)
-        : value(value)
+        : value(value), lineno(0)
     {
         next = previous->next;
         previous->next = this;
@@ -88,6 +88,7 @@ public:
 
     T value;
     List *next;
+    int lineno;
 };
 
 // Append two lists, which are assumed to still be circular, pre-finish.
diff --git a/src/libs/glsl/glslparser.cpp b/src/libs/glsl/glslparser.cpp
index 6f128b43a63..e4da61befb3 100644
--- a/src/libs/glsl/glslparser.cpp
+++ b/src/libs/glsl/glslparser.cpp
@@ -1,5 +1,5 @@
 
-#line 295 "./glsl.g"
+#line 337 "./glsl.g"
 
 /**************************************************************************
 **
@@ -39,7 +39,7 @@
 using namespace GLSL;
 
 Parser::Parser(Engine *engine, const char *source, unsigned size, int variant)
-    : _engine(engine), _tos(-1), _index(0)
+    : _engine(engine), _tos(-1), _index(0), yyloc(-1)
 {
     _tokens.reserve(1024);
 
@@ -106,7 +106,7 @@ TranslationUnit *Parser::parse()
 {
     int action = 0;
     int yytoken = -1;
-    int yyloc = -1;
+    yyloc = -1;
     void *yyval = 0; // value of the current token.
 
     _tos = -1;
@@ -159,1891 +159,1891 @@ TranslationUnit *Parser::parse()
     return 0;
 }
 
-#line 457 "./glsl.g"
+#line 499 "./glsl.g"
 
 void Parser::reduce(int ruleno)
 {
 switch(ruleno) {
 
-#line 466 "./glsl.g"
+#line 508 "./glsl.g"
 
 case 0: {
-    ast(1) = new (_engine->pool()) IdentifierExpression(sym(1).string);
+    ast(1) = makeAstNode<IdentifierExpression>(sym(1).string);
 }   break;
 
-#line 473 "./glsl.g"
+#line 515 "./glsl.g"
 
 case 1: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 480 "./glsl.g"
+#line 522 "./glsl.g"
 
 case 2: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 487 "./glsl.g"
+#line 529 "./glsl.g"
 
 case 3: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 494 "./glsl.g"
+#line 536 "./glsl.g"
 
 case 4: {
     // nothing to do.
 }   break;
 
-#line 501 "./glsl.g"
+#line 543 "./glsl.g"
 
 case 5: {
     ast(1) = ast(2);
 }   break;
 
-#line 508 "./glsl.g"
+#line 550 "./glsl.g"
 
 case 6: {
     // nothing to do.
 }   break;
 
-#line 515 "./glsl.g"
+#line 557 "./glsl.g"
 
 case 7: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 522 "./glsl.g"
+#line 564 "./glsl.g"
 
 case 8: {
     // nothing to do.
 }   break;
 
-#line 529 "./glsl.g"
+#line 571 "./glsl.g"
 
 case 9: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 536 "./glsl.g"
+#line 578 "./glsl.g"
 
 case 10: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 543 "./glsl.g"
+#line 585 "./glsl.g"
 
 case 11: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 550 "./glsl.g"
+#line 592 "./glsl.g"
 
 case 12: {
     // nothing to do.
 }   break;
 
-#line 557 "./glsl.g"
+#line 599 "./glsl.g"
 
 case 13: {
     // nothing to do.
 }   break;
 
-#line 564 "./glsl.g"
+#line 606 "./glsl.g"
 
 case 14: {
     // nothing to do.
 }   break;
 
-#line 571 "./glsl.g"
+#line 613 "./glsl.g"
 
 case 15: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 578 "./glsl.g"
+#line 620 "./glsl.g"
 
 case 16: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 585 "./glsl.g"
+#line 627 "./glsl.g"
 
 case 17: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 592 "./glsl.g"
+#line 634 "./glsl.g"
 
 case 18: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 599 "./glsl.g"
+#line 641 "./glsl.g"
 
 case 19: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 606 "./glsl.g"
+#line 648 "./glsl.g"
 
 case 20: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 613 "./glsl.g"
+#line 655 "./glsl.g"
 
 case 21: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 620 "./glsl.g"
+#line 662 "./glsl.g"
 
 case 22: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 627 "./glsl.g"
+#line 669 "./glsl.g"
 
 case 23: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 634 "./glsl.g"
+#line 676 "./glsl.g"
 
 case 24: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 641 "./glsl.g"
+#line 683 "./glsl.g"
 
 case 25: {
     // nothing to do.
 }   break;
 
-#line 648 "./glsl.g"
+#line 690 "./glsl.g"
 
 case 26: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 655 "./glsl.g"
+#line 697 "./glsl.g"
 
 case 27: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 662 "./glsl.g"
+#line 704 "./glsl.g"
 
 case 28: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 669 "./glsl.g"
+#line 711 "./glsl.g"
 
 case 29: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 676 "./glsl.g"
+#line 718 "./glsl.g"
 
 case 30: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 683 "./glsl.g"
+#line 725 "./glsl.g"
 
 case 31: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 690 "./glsl.g"
+#line 732 "./glsl.g"
 
 case 32: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 697 "./glsl.g"
+#line 739 "./glsl.g"
 
 case 33: {
     // nothing to do.
 }   break;
 
-#line 704 "./glsl.g"
+#line 746 "./glsl.g"
 
 case 34: {
-    ast(1) = new (_engine->pool()) BinaryExpression(AST::Kind_Multiply, sym(1).expression, sym(3).expression);
+    ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Multiply, sym(1).expression, sym(3).expression);
 }   break;
 
-#line 711 "./glsl.g"
+#line 753 "./glsl.g"
 
 case 35: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 718 "./glsl.g"
+#line 760 "./glsl.g"
 
 case 36: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 725 "./glsl.g"
+#line 767 "./glsl.g"
 
 case 37: {
     // nothing to do.
 }   break;
 
-#line 732 "./glsl.g"
+#line 774 "./glsl.g"
 
 case 38: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 739 "./glsl.g"
+#line 781 "./glsl.g"
 
 case 39: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 746 "./glsl.g"
+#line 788 "./glsl.g"
 
 case 40: {
     // nothing to do.
 }   break;
 
-#line 753 "./glsl.g"
+#line 795 "./glsl.g"
 
 case 41: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 760 "./glsl.g"
+#line 802 "./glsl.g"
 
 case 42: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 767 "./glsl.g"
+#line 809 "./glsl.g"
 
 case 43: {
     // nothing to do.
 }   break;
 
-#line 774 "./glsl.g"
+#line 816 "./glsl.g"
 
 case 44: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 781 "./glsl.g"
+#line 823 "./glsl.g"
 
 case 45: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 788 "./glsl.g"
+#line 830 "./glsl.g"
 
 case 46: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 795 "./glsl.g"
+#line 837 "./glsl.g"
 
 case 47: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 802 "./glsl.g"
+#line 844 "./glsl.g"
 
 case 48: {
     // nothing to do.
 }   break;
 
-#line 809 "./glsl.g"
+#line 851 "./glsl.g"
 
 case 49: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 816 "./glsl.g"
+#line 858 "./glsl.g"
 
 case 50: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 823 "./glsl.g"
+#line 865 "./glsl.g"
 
 case 51: {
     // nothing to do.
 }   break;
 
-#line 830 "./glsl.g"
+#line 872 "./glsl.g"
 
 case 52: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 837 "./glsl.g"
+#line 879 "./glsl.g"
 
 case 53: {
     // nothing to do.
 }   break;
 
-#line 844 "./glsl.g"
+#line 886 "./glsl.g"
 
 case 54: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 851 "./glsl.g"
+#line 893 "./glsl.g"
 
 case 55: {
     // nothing to do.
 }   break;
 
-#line 858 "./glsl.g"
+#line 900 "./glsl.g"
 
 case 56: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 865 "./glsl.g"
+#line 907 "./glsl.g"
 
 case 57: {
     // nothing to do.
 }   break;
 
-#line 872 "./glsl.g"
+#line 914 "./glsl.g"
 
 case 58: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 879 "./glsl.g"
+#line 921 "./glsl.g"
 
 case 59: {
     // nothing to do.
 }   break;
 
-#line 886 "./glsl.g"
+#line 928 "./glsl.g"
 
 case 60: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 893 "./glsl.g"
+#line 935 "./glsl.g"
 
 case 61: {
     // nothing to do.
 }   break;
 
-#line 900 "./glsl.g"
+#line 942 "./glsl.g"
 
 case 62: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 907 "./glsl.g"
+#line 949 "./glsl.g"
 
 case 63: {
     // nothing to do.
 }   break;
 
-#line 914 "./glsl.g"
+#line 956 "./glsl.g"
 
 case 64: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 921 "./glsl.g"
+#line 963 "./glsl.g"
 
 case 65: {
     // nothing to do.
 }   break;
 
-#line 928 "./glsl.g"
+#line 970 "./glsl.g"
 
 case 66: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 935 "./glsl.g"
+#line 977 "./glsl.g"
 
 case 67: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 942 "./glsl.g"
+#line 984 "./glsl.g"
 
 case 68: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 949 "./glsl.g"
+#line 991 "./glsl.g"
 
 case 69: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 956 "./glsl.g"
+#line 998 "./glsl.g"
 
 case 70: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 963 "./glsl.g"
+#line 1005 "./glsl.g"
 
 case 71: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 970 "./glsl.g"
+#line 1012 "./glsl.g"
 
 case 72: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 977 "./glsl.g"
+#line 1019 "./glsl.g"
 
 case 73: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 984 "./glsl.g"
+#line 1026 "./glsl.g"
 
 case 74: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 991 "./glsl.g"
+#line 1033 "./glsl.g"
 
 case 75: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 998 "./glsl.g"
+#line 1040 "./glsl.g"
 
 case 76: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1005 "./glsl.g"
+#line 1047 "./glsl.g"
 
 case 77: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1012 "./glsl.g"
+#line 1054 "./glsl.g"
 
 case 78: {
     // nothing to do.
 }   break;
 
-#line 1019 "./glsl.g"
+#line 1061 "./glsl.g"
 
 case 79: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1026 "./glsl.g"
+#line 1068 "./glsl.g"
 
 case 80: {
     // nothing to do.
 }   break;
 
-#line 1033 "./glsl.g"
+#line 1075 "./glsl.g"
 
 case 81: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1040 "./glsl.g"
+#line 1082 "./glsl.g"
 
 case 82: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1047 "./glsl.g"
+#line 1089 "./glsl.g"
 
 case 83: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1054 "./glsl.g"
+#line 1096 "./glsl.g"
 
 case 84: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1061 "./glsl.g"
+#line 1103 "./glsl.g"
 
 case 85: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1068 "./glsl.g"
+#line 1110 "./glsl.g"
 
 case 86: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1075 "./glsl.g"
+#line 1117 "./glsl.g"
 
 case 87: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1082 "./glsl.g"
+#line 1124 "./glsl.g"
 
 case 88: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1089 "./glsl.g"
+#line 1131 "./glsl.g"
 
 case 89: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1096 "./glsl.g"
+#line 1138 "./glsl.g"
 
 case 90: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1103 "./glsl.g"
+#line 1145 "./glsl.g"
 
 case 91: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1110 "./glsl.g"
+#line 1152 "./glsl.g"
 
 case 92: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1117 "./glsl.g"
+#line 1159 "./glsl.g"
 
 case 93: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1124 "./glsl.g"
+#line 1166 "./glsl.g"
 
 case 94: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1131 "./glsl.g"
+#line 1173 "./glsl.g"
 
 case 95: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1138 "./glsl.g"
+#line 1180 "./glsl.g"
 
 case 96: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1145 "./glsl.g"
+#line 1187 "./glsl.g"
 
 case 97: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1152 "./glsl.g"
+#line 1194 "./glsl.g"
 
 case 98: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1159 "./glsl.g"
+#line 1201 "./glsl.g"
 
 case 99: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1166 "./glsl.g"
+#line 1208 "./glsl.g"
 
 case 100: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1173 "./glsl.g"
+#line 1215 "./glsl.g"
 
 case 101: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1180 "./glsl.g"
+#line 1222 "./glsl.g"
 
 case 102: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1187 "./glsl.g"
+#line 1229 "./glsl.g"
 
 case 103: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1194 "./glsl.g"
+#line 1236 "./glsl.g"
 
 case 104: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1201 "./glsl.g"
+#line 1243 "./glsl.g"
 
 case 105: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1208 "./glsl.g"
+#line 1250 "./glsl.g"
 
 case 106: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1215 "./glsl.g"
+#line 1257 "./glsl.g"
 
 case 107: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1222 "./glsl.g"
+#line 1264 "./glsl.g"
 
 case 108: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1229 "./glsl.g"
+#line 1271 "./glsl.g"
 
 case 109: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1236 "./glsl.g"
+#line 1278 "./glsl.g"
 
 case 110: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1243 "./glsl.g"
+#line 1285 "./glsl.g"
 
 case 111: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1250 "./glsl.g"
+#line 1292 "./glsl.g"
 
 case 112: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1257 "./glsl.g"
+#line 1299 "./glsl.g"
 
 case 113: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1264 "./glsl.g"
+#line 1306 "./glsl.g"
 
 case 114: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1271 "./glsl.g"
+#line 1313 "./glsl.g"
 
 case 115: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1278 "./glsl.g"
+#line 1320 "./glsl.g"
 
 case 116: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1285 "./glsl.g"
+#line 1327 "./glsl.g"
 
 case 117: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1292 "./glsl.g"
+#line 1334 "./glsl.g"
 
 case 118: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1299 "./glsl.g"
+#line 1341 "./glsl.g"
 
 case 119: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1306 "./glsl.g"
+#line 1348 "./glsl.g"
 
 case 120: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1313 "./glsl.g"
+#line 1355 "./glsl.g"
 
 case 121: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1320 "./glsl.g"
+#line 1362 "./glsl.g"
 
 case 122: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1327 "./glsl.g"
+#line 1369 "./glsl.g"
 
 case 123: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1334 "./glsl.g"
+#line 1376 "./glsl.g"
 
 case 124: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1341 "./glsl.g"
+#line 1383 "./glsl.g"
 
 case 125: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1348 "./glsl.g"
+#line 1390 "./glsl.g"
 
 case 126: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1355 "./glsl.g"
+#line 1397 "./glsl.g"
 
 case 127: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1362 "./glsl.g"
+#line 1404 "./glsl.g"
 
 case 128: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1369 "./glsl.g"
+#line 1411 "./glsl.g"
 
 case 129: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1376 "./glsl.g"
+#line 1418 "./glsl.g"
 
 case 130: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1383 "./glsl.g"
+#line 1425 "./glsl.g"
 
 case 131: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1390 "./glsl.g"
+#line 1432 "./glsl.g"
 
 case 132: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1397 "./glsl.g"
+#line 1439 "./glsl.g"
 
 case 133: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1404 "./glsl.g"
+#line 1446 "./glsl.g"
 
 case 134: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1411 "./glsl.g"
+#line 1453 "./glsl.g"
 
 case 135: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1418 "./glsl.g"
+#line 1460 "./glsl.g"
 
 case 136: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1425 "./glsl.g"
+#line 1467 "./glsl.g"
 
 case 137: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1432 "./glsl.g"
+#line 1474 "./glsl.g"
 
 case 138: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1439 "./glsl.g"
+#line 1481 "./glsl.g"
 
 case 139: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1446 "./glsl.g"
+#line 1488 "./glsl.g"
 
 case 140: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1453 "./glsl.g"
+#line 1495 "./glsl.g"
 
 case 141: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1460 "./glsl.g"
+#line 1502 "./glsl.g"
 
 case 142: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1467 "./glsl.g"
+#line 1509 "./glsl.g"
 
 case 143: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1474 "./glsl.g"
+#line 1516 "./glsl.g"
 
 case 144: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1481 "./glsl.g"
+#line 1523 "./glsl.g"
 
 case 145: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1488 "./glsl.g"
+#line 1530 "./glsl.g"
 
 case 146: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1495 "./glsl.g"
+#line 1537 "./glsl.g"
 
 case 147: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1502 "./glsl.g"
+#line 1544 "./glsl.g"
 
 case 148: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1509 "./glsl.g"
+#line 1551 "./glsl.g"
 
 case 149: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1516 "./glsl.g"
+#line 1558 "./glsl.g"
 
 case 150: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1523 "./glsl.g"
+#line 1565 "./glsl.g"
 
 case 151: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1530 "./glsl.g"
+#line 1572 "./glsl.g"
 
 case 152: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1537 "./glsl.g"
+#line 1579 "./glsl.g"
 
 case 153: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1544 "./glsl.g"
+#line 1586 "./glsl.g"
 
 case 154: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1551 "./glsl.g"
+#line 1593 "./glsl.g"
 
 case 155: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1558 "./glsl.g"
+#line 1600 "./glsl.g"
 
 case 156: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1565 "./glsl.g"
+#line 1607 "./glsl.g"
 
 case 157: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1572 "./glsl.g"
+#line 1614 "./glsl.g"
 
 case 158: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1579 "./glsl.g"
+#line 1621 "./glsl.g"
 
 case 159: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1586 "./glsl.g"
+#line 1628 "./glsl.g"
 
 case 160: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1593 "./glsl.g"
+#line 1635 "./glsl.g"
 
 case 161: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1600 "./glsl.g"
+#line 1642 "./glsl.g"
 
 case 162: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1607 "./glsl.g"
+#line 1649 "./glsl.g"
 
 case 163: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1614 "./glsl.g"
+#line 1656 "./glsl.g"
 
 case 164: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1621 "./glsl.g"
+#line 1663 "./glsl.g"
 
 case 165: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1628 "./glsl.g"
+#line 1670 "./glsl.g"
 
 case 166: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1635 "./glsl.g"
+#line 1677 "./glsl.g"
 
 case 167: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1642 "./glsl.g"
+#line 1684 "./glsl.g"
 
 case 168: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1649 "./glsl.g"
+#line 1691 "./glsl.g"
 
 case 169: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1656 "./glsl.g"
+#line 1698 "./glsl.g"
 
 case 170: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1663 "./glsl.g"
+#line 1705 "./glsl.g"
 
 case 171: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1670 "./glsl.g"
+#line 1712 "./glsl.g"
 
 case 172: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1677 "./glsl.g"
+#line 1719 "./glsl.g"
 
 case 173: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1684 "./glsl.g"
+#line 1726 "./glsl.g"
 
 case 174: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1691 "./glsl.g"
+#line 1733 "./glsl.g"
 
 case 175: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1698 "./glsl.g"
+#line 1740 "./glsl.g"
 
 case 176: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1705 "./glsl.g"
+#line 1747 "./glsl.g"
 
 case 177: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1712 "./glsl.g"
+#line 1754 "./glsl.g"
 
 case 178: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1719 "./glsl.g"
+#line 1761 "./glsl.g"
 
 case 179: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1726 "./glsl.g"
+#line 1768 "./glsl.g"
 
 case 180: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1733 "./glsl.g"
+#line 1775 "./glsl.g"
 
 case 181: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1740 "./glsl.g"
+#line 1782 "./glsl.g"
 
 case 182: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1747 "./glsl.g"
+#line 1789 "./glsl.g"
 
 case 183: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1754 "./glsl.g"
+#line 1796 "./glsl.g"
 
 case 184: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1761 "./glsl.g"
+#line 1803 "./glsl.g"
 
 case 185: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1768 "./glsl.g"
+#line 1810 "./glsl.g"
 
 case 186: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1775 "./glsl.g"
+#line 1817 "./glsl.g"
 
 case 187: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1782 "./glsl.g"
+#line 1824 "./glsl.g"
 
 case 188: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1789 "./glsl.g"
+#line 1831 "./glsl.g"
 
 case 189: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1796 "./glsl.g"
+#line 1838 "./glsl.g"
 
 case 190: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1803 "./glsl.g"
+#line 1845 "./glsl.g"
 
 case 191: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1810 "./glsl.g"
+#line 1852 "./glsl.g"
 
 case 192: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1817 "./glsl.g"
+#line 1859 "./glsl.g"
 
 case 193: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1824 "./glsl.g"
+#line 1866 "./glsl.g"
 
 case 194: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1831 "./glsl.g"
+#line 1873 "./glsl.g"
 
 case 195: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1838 "./glsl.g"
+#line 1880 "./glsl.g"
 
 case 196: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1845 "./glsl.g"
+#line 1887 "./glsl.g"
 
 case 197: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1852 "./glsl.g"
+#line 1894 "./glsl.g"
 
 case 198: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1859 "./glsl.g"
+#line 1901 "./glsl.g"
 
 case 199: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1866 "./glsl.g"
+#line 1908 "./glsl.g"
 
 case 200: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1873 "./glsl.g"
+#line 1915 "./glsl.g"
 
 case 201: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1880 "./glsl.g"
+#line 1922 "./glsl.g"
 
 case 202: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1887 "./glsl.g"
+#line 1929 "./glsl.g"
 
 case 203: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1894 "./glsl.g"
+#line 1936 "./glsl.g"
 
 case 204: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1901 "./glsl.g"
+#line 1943 "./glsl.g"
 
 case 205: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1908 "./glsl.g"
+#line 1950 "./glsl.g"
 
 case 206: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1915 "./glsl.g"
+#line 1957 "./glsl.g"
 
 case 207: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1922 "./glsl.g"
+#line 1964 "./glsl.g"
 
 case 208: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1929 "./glsl.g"
+#line 1971 "./glsl.g"
 
 case 209: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1936 "./glsl.g"
+#line 1978 "./glsl.g"
 
 case 210: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1943 "./glsl.g"
+#line 1985 "./glsl.g"
 
 case 211: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1950 "./glsl.g"
+#line 1992 "./glsl.g"
 
 case 212: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1957 "./glsl.g"
+#line 1999 "./glsl.g"
 
 case 213: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1964 "./glsl.g"
+#line 2006 "./glsl.g"
 
 case 214: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1971 "./glsl.g"
+#line 2013 "./glsl.g"
 
 case 215: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1978 "./glsl.g"
+#line 2020 "./glsl.g"
 
 case 216: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1985 "./glsl.g"
+#line 2027 "./glsl.g"
 
 case 217: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1992 "./glsl.g"
+#line 2034 "./glsl.g"
 
 case 218: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1999 "./glsl.g"
+#line 2041 "./glsl.g"
 
 case 219: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2006 "./glsl.g"
+#line 2048 "./glsl.g"
 
 case 220: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2013 "./glsl.g"
+#line 2055 "./glsl.g"
 
 case 221: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2020 "./glsl.g"
+#line 2062 "./glsl.g"
 
 case 222: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2027 "./glsl.g"
+#line 2069 "./glsl.g"
 
 case 223: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2034 "./glsl.g"
+#line 2076 "./glsl.g"
 
 case 224: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2041 "./glsl.g"
+#line 2083 "./glsl.g"
 
 case 225: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2048 "./glsl.g"
+#line 2090 "./glsl.g"
 
 case 226: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2055 "./glsl.g"
+#line 2097 "./glsl.g"
 
 case 227: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2062 "./glsl.g"
+#line 2104 "./glsl.g"
 
 case 228: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2069 "./glsl.g"
+#line 2111 "./glsl.g"
 
 case 229: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2076 "./glsl.g"
+#line 2118 "./glsl.g"
 
 case 230: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2083 "./glsl.g"
+#line 2125 "./glsl.g"
 
 case 231: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2090 "./glsl.g"
+#line 2132 "./glsl.g"
 
 case 232: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2097 "./glsl.g"
+#line 2139 "./glsl.g"
 
 case 233: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2104 "./glsl.g"
+#line 2146 "./glsl.g"
 
 case 234: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2111 "./glsl.g"
+#line 2153 "./glsl.g"
 
 case 235: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2118 "./glsl.g"
+#line 2160 "./glsl.g"
 
 case 236: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2125 "./glsl.g"
+#line 2167 "./glsl.g"
 
 case 237: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2132 "./glsl.g"
+#line 2174 "./glsl.g"
 
 case 238: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2139 "./glsl.g"
+#line 2181 "./glsl.g"
 
 case 239: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2146 "./glsl.g"
+#line 2188 "./glsl.g"
 
 case 240: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2153 "./glsl.g"
+#line 2195 "./glsl.g"
 
 case 241: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2160 "./glsl.g"
+#line 2202 "./glsl.g"
 
 case 242: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2167 "./glsl.g"
+#line 2209 "./glsl.g"
 
 case 243: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2174 "./glsl.g"
+#line 2216 "./glsl.g"
 
 case 244: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2181 "./glsl.g"
+#line 2223 "./glsl.g"
 
 case 245: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2188 "./glsl.g"
+#line 2230 "./glsl.g"
 
 case 246: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2195 "./glsl.g"
+#line 2237 "./glsl.g"
 
 case 247: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2202 "./glsl.g"
+#line 2244 "./glsl.g"
 
 case 248: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2209 "./glsl.g"
+#line 2251 "./glsl.g"
 
 case 249: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2216 "./glsl.g"
+#line 2258 "./glsl.g"
 
 case 250: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2223 "./glsl.g"
+#line 2265 "./glsl.g"
 
 case 251: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2230 "./glsl.g"
+#line 2272 "./glsl.g"
 
 case 252: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2237 "./glsl.g"
+#line 2279 "./glsl.g"
 
 case 253: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2244 "./glsl.g"
+#line 2286 "./glsl.g"
 
 case 254: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2251 "./glsl.g"
+#line 2293 "./glsl.g"
 
 case 255: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2258 "./glsl.g"
+#line 2300 "./glsl.g"
 
 case 256: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2265 "./glsl.g"
+#line 2307 "./glsl.g"
 
 case 257: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2272 "./glsl.g"
+#line 2314 "./glsl.g"
 
 case 258: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2279 "./glsl.g"
+#line 2321 "./glsl.g"
 
 case 259: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2286 "./glsl.g"
+#line 2328 "./glsl.g"
 
 case 260: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2293 "./glsl.g"
+#line 2335 "./glsl.g"
 
 case 261: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2300 "./glsl.g"
+#line 2342 "./glsl.g"
 
 case 262: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2307 "./glsl.g"
+#line 2349 "./glsl.g"
 
 case 263: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2314 "./glsl.g"
+#line 2356 "./glsl.g"
 
 case 264: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2321 "./glsl.g"
+#line 2363 "./glsl.g"
 
 case 265: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2328 "./glsl.g"
+#line 2370 "./glsl.g"
 
 case 266: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2335 "./glsl.g"
+#line 2377 "./glsl.g"
 
 case 267: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2342 "./glsl.g"
+#line 2384 "./glsl.g"
 
 case 268: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2349 "./glsl.g"
+#line 2391 "./glsl.g"
 
 case 269: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2356 "./glsl.g"
+#line 2398 "./glsl.g"
 
 case 270: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2363 "./glsl.g"
+#line 2405 "./glsl.g"
 
 case 271: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2370 "./glsl.g"
+#line 2412 "./glsl.g"
 
 case 272: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2377 "./glsl.g"
+#line 2419 "./glsl.g"
 
 case 273: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2384 "./glsl.g"
+#line 2426 "./glsl.g"
 
 case 274: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2391 "./glsl.g"
+#line 2433 "./glsl.g"
 
 case 275: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2398 "./glsl.g"
+#line 2440 "./glsl.g"
 
 case 276: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2405 "./glsl.g"
+#line 2447 "./glsl.g"
 
 case 277: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2412 "./glsl.g"
+#line 2454 "./glsl.g"
 
 case 278: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2419 "./glsl.g"
+#line 2461 "./glsl.g"
 
 case 279: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2426 "./glsl.g"
+#line 2468 "./glsl.g"
 
 case 280: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2433 "./glsl.g"
+#line 2475 "./glsl.g"
 
 case 281: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2440 "./glsl.g"
+#line 2482 "./glsl.g"
 
 case 282: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2447 "./glsl.g"
+#line 2489 "./glsl.g"
 
 case 283: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2454 "./glsl.g"
+#line 2496 "./glsl.g"
 
 case 284: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2461 "./glsl.g"
+#line 2503 "./glsl.g"
 
 case 285: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2468 "./glsl.g"
+#line 2510 "./glsl.g"
 
 case 286: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2475 "./glsl.g"
+#line 2517 "./glsl.g"
 
 case 287: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2482 "./glsl.g"
+#line 2524 "./glsl.g"
 
 case 288: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2489 "./glsl.g"
+#line 2531 "./glsl.g"
 
 case 289: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2496 "./glsl.g"
+#line 2538 "./glsl.g"
 
 case 290: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2503 "./glsl.g"
+#line 2545 "./glsl.g"
 
 case 291: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2510 "./glsl.g"
+#line 2552 "./glsl.g"
 
 case 292: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2517 "./glsl.g"
+#line 2559 "./glsl.g"
 
 case 293: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2524 "./glsl.g"
+#line 2566 "./glsl.g"
 
 case 294: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2531 "./glsl.g"
+#line 2573 "./glsl.g"
 
 case 295: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2538 "./glsl.g"
+#line 2580 "./glsl.g"
 
 case 296: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2545 "./glsl.g"
+#line 2587 "./glsl.g"
 
 case 297: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2552 "./glsl.g"
+#line 2594 "./glsl.g"
 
 case 298: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2559 "./glsl.g"
+#line 2601 "./glsl.g"
 
 case 299: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2566 "./glsl.g"
+#line 2608 "./glsl.g"
 
 case 300: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2573 "./glsl.g"
+#line 2615 "./glsl.g"
 
 case 301: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2580 "./glsl.g"
+#line 2622 "./glsl.g"
 
 case 302: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2587 "./glsl.g"
+#line 2629 "./glsl.g"
 
 case 303: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2594 "./glsl.g"
+#line 2636 "./glsl.g"
 
 case 304: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2601 "./glsl.g"
+#line 2643 "./glsl.g"
 
 case 305: {
-    ast(1) = new (_engine->pool()) TranslationUnit(sym(1).declaration_list);
+    ast(1) = makeAstNode<TranslationUnit>(sym(1).declaration_list);
 }   break;
 
-#line 2608 "./glsl.g"
+#line 2650 "./glsl.g"
 
 case 306: {
-    sym(1).declaration_list = new (_engine->pool()) List<Declaration *>(sym(1).declaration);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >(sym(1).declaration);
 }   break;
 
-#line 2615 "./glsl.g"
+#line 2657 "./glsl.g"
 
 case 307: {
-    sym(1).declaration_list = new (_engine->pool())  List<Declaration *>(sym(1).declaration_list, sym(2).declaration);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >(sym(1).declaration_list, sym(2).declaration);
 }   break;
 
-#line 2622 "./glsl.g"
+#line 2664 "./glsl.g"
 
 case 308: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2629 "./glsl.g"
+#line 2671 "./glsl.g"
 
 case 309: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2636 "./glsl.g"
+#line 2678 "./glsl.g"
 
 case 310: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2643 "./glsl.g"
+#line 2685 "./glsl.g"
 
 case 311: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2650 "./glsl.g"
+#line 2692 "./glsl.g"
 
 case 312: {
     ast(1) = 0;
 }   break;
 
-#line 2658 "./glsl.g"
+#line 2700 "./glsl.g"
 
 } // end switch
 } // end Parser::reduce()
diff --git a/src/libs/glsl/glslparser.h b/src/libs/glsl/glslparser.h
index 22841728ade..69d8008bf18 100644
--- a/src/libs/glsl/glslparser.h
+++ b/src/libs/glsl/glslparser.h
@@ -33,6 +33,7 @@
 #include "glslparsertable_p.h"
 #include "glsllexer.h"
 #include "glslast.h"
+#include "glslengine.h"
 #include <vector>
 #include <stack>
 
@@ -70,10 +71,51 @@ private:
     inline int tokenKind(int index) const { return _tokens.at(index).kind; }
     void reduce(int ruleno);
 
+    template <typename T>
+    T *makeAstNode()
+    {
+        T *node = new (_engine->pool()) T ();
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1>
+    T *makeAstNode(A1 a1)
+    {
+        T *node = new (_engine->pool()) T (a1);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2>
+    T *makeAstNode(A1 a1, A2 a2)
+    {
+        T *node = new (_engine->pool()) T (a1, a2);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2, typename A3>
+    T *makeAstNode(A1 a1, A2 a2, A3 a3)
+    {
+        T *node = new (_engine->pool()) T (a1, a2, a3);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
+    template <typename T, typename A1, typename A2, typename A3, typename A4>
+    T *makeAstNode(A1 a1, A2 a2, A3 a3, A4 a4)
+    {
+        T *node = new (_engine->pool()) T (a1, a2, a3, a4);
+        node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
+        return node;
+    }
+
 private:
     Engine *_engine;
     int _tos;
     int _index;
+    int yyloc;
     std::vector<int> _stateStack;
     std::vector<int> _locationStack;
     std::vector<Value> _symStack;
-- 
GitLab