OSDN Git Service

Variable and parameter declarations for GLSL
authorRhys Weatherley <rhys.weatherley@nokia.com>
Wed, 17 Nov 2010 04:46:11 +0000 (14:46 +1000)
committerRhys Weatherley <rhys.weatherley@nokia.com>
Wed, 17 Nov 2010 05:23:13 +0000 (15:23 +1000)
src/libs/glsl/glsl.g
src/libs/glsl/glslast.cpp
src/libs/glsl/glslast.h
src/libs/glsl/glslastvisitor.h
src/libs/glsl/glslparser.cpp
src/libs/glsl/glslparser.h

index 2bb9d2a..b3295e9 100644 (file)
@@ -288,6 +288,10 @@ public:
             int qualifier;
             List<LayoutQualifier *> *layout_list;
         } type_qualifier;
+        struct {
+            Type *type;
+            const std::string *name;
+        } param_declarator;
         // ### ast nodes...
     };
 
@@ -1126,7 +1130,7 @@ case $rule_number: {
 declaration ::= init_declarator_list SEMICOLON ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<InitDeclaration>(sym(1).declaration_list);
 }   break;
 ./
 
@@ -1217,182 +1221,230 @@ case $rule_number: {
 parameter_declarator ::= type_specifier IDENTIFIER ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).param_declarator.type = type(1);
+    sym(1).param_declarator.name = string(2);
 }   break;
 ./
 
 parameter_declarator ::= type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).param_declarator.type = makeAstNode<ArrayType>(type(1), expression(4));
+    sym(1).param_declarator.name = string(2);
 }   break;
 ./
 
 parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_declarator ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (makeAstNode<QualifiedType>
+            (sym(1).qualifier, sym(3).param_declarator.type,
+             (List<LayoutQualifier *> *)0),
+         ParameterDeclaration::Qualifier(sym(2).qualifier),
+         sym(3).param_declarator.name);
 }   break;
 ./
 
 parameter_declaration ::= parameter_qualifier parameter_declarator ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (sym(2).param_declarator.type,
+         ParameterDeclaration::Qualifier(sym(1).qualifier),
+         sym(2).param_declarator.name);
 }   break;
 ./
 
 parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_type_specifier ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (makeAstNode<QualifiedType>
+            (sym(1).qualifier, type(3), (List<LayoutQualifier *> *)0),
+         ParameterDeclaration::Qualifier(sym(2).qualifier),
+         (const std::string *)0);
 }   break;
 ./
 
 parameter_declaration ::= parameter_qualifier parameter_type_specifier ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (type(2), ParameterDeclaration::Qualifier(sym(1).qualifier),
+         (const std::string *)0);
 }   break;
 ./
 
 parameter_qualifier ::= empty ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::In;
 }   break;
 ./
 
 parameter_qualifier ::= IN ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::In;
 }   break;
 ./
 
 parameter_qualifier ::= OUT ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::Out;
 }   break;
 ./
 
 parameter_qualifier ::= INOUT ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::InOut;
 }   break;
 ./
 
 parameter_type_specifier ::= type_specifier ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 ./
 
 init_declarator_list ::= single_declaration ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+        (sym(1).declaration);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type);
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type, expression(5));
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type);
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(7));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type, expression(5));
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(8));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 init_declarator_list ::= init_declarator_list COMMA IDENTIFIER EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(5));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 ./
 
 single_declaration ::= fully_specified_type ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<TypeDeclaration>(type(1));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>(type(1), string(2));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1)), string(2));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1), expression(4)), string(2));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1)), string(2), expression(6));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1), expression(4)),
+         string(2), expression(7));
 }   break;
 ./
 
 single_declaration ::= fully_specified_type IDENTIFIER EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (type(1), string(2), expression(4));
 }   break;
 ./
 
 single_declaration ::= INVARIANT IDENTIFIER ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<InvariantDeclaration>(string(2));
 }   break;
 ./
 
@@ -2391,14 +2443,14 @@ case $rule_number: {
 initializer ::= assignment_expression ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 ./
 
 declaration_statement ::= declaration ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<DeclarationStatement>(sym(1).declaration_list);
 }   break;
 ./
 
@@ -2568,7 +2620,8 @@ case $rule_number: {
 condition ::= fully_specified_type IDENTIFIER EQUAL initializer ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<DeclarationExpression>
+        (type(1), string(2), expression(4));
 }   break;
 ./
 
@@ -2755,7 +2808,7 @@ case $rule_number: {
 external_declaration ::= declaration ;
 /.
 case $rule_number: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 ./
 
index 08252d5..28c8c97 100644 (file)
@@ -124,6 +124,15 @@ void FunctionIdentifier::accept0(Visitor *visitor)
     visitor->endVisit(this);
 }
 
+void DeclarationExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(type, visitor);
+        accept(initializer, visitor);
+    }
+    visitor->endVisit(this);
+}
+
 void ExpressionStatement::accept0(Visitor *visitor)
 {
     if (visitor->visit(this))
@@ -206,6 +215,13 @@ void CaseLabelStatement::accept0(Visitor *visitor)
     visitor->endVisit(this);
 }
 
+void DeclarationStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(decls, visitor);
+    visitor->endVisit(this);
+}
+
 BasicType::BasicType(int _token, const char *_name, Category _category)
     : Type(Kind_BasicType), token(_token), name(_name), categ(_category)
 {
@@ -348,3 +364,45 @@ void PrecisionDeclaration::accept0(Visitor *visitor)
         accept(type, visitor);
     visitor->endVisit(this);
 }
+
+void ParameterDeclaration::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(type, visitor);
+    visitor->endVisit(this);
+}
+
+void VariableDeclaration::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(type, visitor);
+        accept(initializer, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+Type *VariableDeclaration::declarationType(List<Declaration *> *decls)
+{
+    VariableDeclaration *var = decls->value->asVariableDeclaration();
+    return var ? var->type : 0;
+}
+
+void TypeDeclaration::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(type, visitor);
+    visitor->endVisit(this);
+}
+
+void InvariantDeclaration::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+void InitDeclaration::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(decls, visitor);
+    visitor->endVisit(this);
+}
index 74176f1..7e4493e 100644 (file)
@@ -47,6 +47,7 @@ class AssignmentExpression;
 class MemberAccessExpression;
 class FunctionCallExpression;
 class FunctionIdentifier;
+class DeclarationExpression;
 class Statement;
 class ExpressionStatement;
 class CompoundStatement;
@@ -58,6 +59,7 @@ class JumpStatement;
 class ReturnStatement;
 class SwitchStatement;
 class CaseLabelStatement;
+class DeclarationStatement;
 class Type;
 class BasicType;
 class NamedType;
@@ -66,6 +68,11 @@ class StructType;
 class QualifiedType;
 class Declaration;
 class PrecisionDeclaration;
+class ParameterDeclaration;
+class VariableDeclaration;
+class TypeDeclaration;
+class InvariantDeclaration;
+class InitDeclaration;
 class Visitor;
 
 template <typename T>
@@ -161,6 +168,7 @@ public:
         Kind_FunctionCall,
         Kind_MemberFunctionCall,
         Kind_FunctionIdentifier,
+        Kind_DeclarationExpression,
 
         // Assignment expressions
         Kind_Assign,
@@ -190,6 +198,7 @@ public:
         Kind_Switch,
         Kind_CaseLabel,
         Kind_DefaultLabel,
+        Kind_DeclarationStatement,
 
         // Types
         Kind_BasicType,
@@ -202,7 +211,12 @@ public:
         Kind_QualifiedType,
 
         // Declarations
-        Kind_PrecisionDeclaration
+        Kind_PrecisionDeclaration,
+        Kind_ParameterDeclaration,
+        Kind_VariableDeclaration,
+        Kind_TypeDeclaration,
+        Kind_InvariantDeclaration,
+        Kind_InitDeclaration
     };
 
     virtual TranslationUnit *asTranslationUnit() { return 0; }
@@ -217,6 +231,7 @@ public:
     virtual MemberAccessExpression *asMemberAccessExpression() { return 0; }
     virtual FunctionCallExpression *asFunctionCallExpression() { return 0; }
     virtual FunctionIdentifier *asFunctionIdentifier() { return 0; }
+    virtual DeclarationExpression *asDeclarationExpression() { return 0; }
 
     virtual Statement *asStatement() { return 0; }
     virtual ExpressionStatement *asExpressionStatement() { return 0; }
@@ -229,6 +244,7 @@ public:
     virtual ReturnStatement *asReturnStatement() { return 0; }
     virtual SwitchStatement *asSwitchStatement() { return 0; }
     virtual CaseLabelStatement *asCaseLabelStatement() { return 0; }
+    virtual DeclarationStatement *asDeclarationStatement() { return 0; }
 
     virtual Type *asType() { return 0; }
     virtual BasicType *asBasicType() { return 0; }
@@ -239,6 +255,11 @@ public:
 
     virtual Declaration *asDeclaration() { return 0; }
     virtual PrecisionDeclaration *asPrecisionDeclaration() { return 0; }
+    virtual ParameterDeclaration *asParameterDeclaration() { return 0; }
+    virtual VariableDeclaration *asVariableDeclaration() { return 0; }
+    virtual TypeDeclaration *asTypeDeclaration() { return 0; }
+    virtual InvariantDeclaration *asInvariantDeclaration() { return 0; }
+    virtual InitDeclaration *asInitDeclaration() { return 0; }
 
     void accept(Visitor *visitor);
     static void accept(AST *ast, Visitor *visitor);
@@ -436,6 +457,24 @@ public: // attributes
     Type *type;
 };
 
+class GLSL_EXPORT DeclarationExpression: public Expression
+{
+public:
+    DeclarationExpression(Type *_type, const std::string *_name,
+                          Expression *_initializer)
+        : Expression(Kind_DeclarationExpression), type(_type)
+        , name(_name), initializer(_initializer) {}
+
+    virtual DeclarationExpression *asDeclarationExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Type *type;
+    const std::string *name;
+    Expression *initializer;
+};
+
 class GLSL_EXPORT Statement: public AST
 {
 protected:
@@ -594,6 +633,20 @@ public: // attributes
     Expression *expr;
 };
 
+class GLSL_EXPORT DeclarationStatement: public Statement
+{
+public:
+    DeclarationStatement(List<Declaration *> *_decls)
+        : Statement(Kind_DeclarationStatement), decls(finish(_decls)) {}
+
+    virtual DeclarationStatement *asDeclarationStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    List<Declaration *> *decls;
+};
+
 class GLSL_EXPORT Type: public AST
 {
 protected:
@@ -775,7 +828,7 @@ class GLSL_EXPORT QualifiedType: public Type
 public:
     QualifiedType(int _qualifiers, Type *_type, List<LayoutQualifier *> *_layout_list)
         : Type(Kind_QualifiedType), qualifiers(_qualifiers), type(_type)
-        , layout_list(_layout_list) {}
+        , layout_list(finish(_layout_list)) {}
 
     enum
     {
@@ -842,6 +895,92 @@ public: // attributes
     Type *type;
 };
 
+class ParameterDeclaration: public Declaration
+{
+public:
+    enum Qualifier
+    {
+        In,
+        Out,
+        InOut
+    };
+    ParameterDeclaration(Type *_type, Qualifier _qualifier,
+                         const std::string *_name)
+        : Declaration(Kind_ParameterDeclaration), type(_type)
+        , qualifier(_qualifier), name(_name) {}
+
+    virtual ParameterDeclaration *asParameterDeclaration() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Type *type;
+    Qualifier qualifier;
+    const std::string *name;
+};
+
+class VariableDeclaration: public Declaration
+{
+public:
+    VariableDeclaration(Type *_type, const std::string *_name,
+                        Expression *_initializer = 0)
+        : Declaration(Kind_VariableDeclaration), type(_type)
+        , name(_name), initializer(_initializer) {}
+
+    virtual VariableDeclaration *asVariableDeclaration() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+    static Type *declarationType(List<Declaration *> *decls);
+
+public: // attributes
+    Type *type;
+    const std::string *name;
+    Expression *initializer;
+};
+
+class TypeDeclaration: public Declaration
+{
+public:
+    TypeDeclaration(Type *_type)
+        : Declaration(Kind_TypeDeclaration), type(_type) {}
+
+    virtual TypeDeclaration *asTypeDeclaration() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Type *type;
+};
+
+class InvariantDeclaration: public Declaration
+{
+public:
+    InvariantDeclaration(const std::string *_name)
+        : Declaration(Kind_InvariantDeclaration), name(_name) {}
+
+    virtual InvariantDeclaration *asInvariantDeclaration() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    const std::string *name;
+};
+
+class InitDeclaration: public Declaration
+{
+public:
+    InitDeclaration(List<Declaration *> *_decls)
+        : Declaration(Kind_InitDeclaration), decls(finish(_decls)) {}
+
+    virtual InitDeclaration *asInitDeclaration() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    List<Declaration *> *decls;
+};
+
 } // namespace GLSL
 
 #endif // GLSLAST_H
index fc6300a..045eeb7 100644 (file)
@@ -72,6 +72,9 @@ public:
     virtual bool visit(FunctionIdentifier *) { return true; }
     virtual void endVisit(FunctionIdentifier *) {}
 
+    virtual bool visit(DeclarationExpression *) { return true; }
+    virtual void endVisit(DeclarationExpression *) {}
+
     virtual bool visit(ExpressionStatement *) { return true; }
     virtual void endVisit(ExpressionStatement *) {}
 
@@ -102,6 +105,9 @@ public:
     virtual bool visit(CaseLabelStatement *) { return true; }
     virtual void endVisit(CaseLabelStatement *) {}
 
+    virtual bool visit(DeclarationStatement *) { return true; }
+    virtual void endVisit(DeclarationStatement *) {}
+
     virtual bool visit(BasicType *) { return true; }
     virtual void endVisit(BasicType *) {}
 
@@ -122,6 +128,21 @@ public:
 
     virtual bool visit(PrecisionDeclaration *) { return true; }
     virtual void endVisit(PrecisionDeclaration *) {}
+
+    virtual bool visit(ParameterDeclaration *) { return true; }
+    virtual void endVisit(ParameterDeclaration *) {}
+
+    virtual bool visit(VariableDeclaration *) { return true; }
+    virtual void endVisit(VariableDeclaration *) {}
+
+    virtual bool visit(TypeDeclaration *) { return true; }
+    virtual void endVisit(TypeDeclaration *) {}
+
+    virtual bool visit(InvariantDeclaration *) { return true; }
+    virtual void endVisit(InvariantDeclaration *) {}
+
+    virtual bool visit(InitDeclaration *) { return true; }
+    virtual void endVisit(InitDeclaration *) {}
 };
 
 } // namespace GLSL
index 0e79f21..c9940d7 100644 (file)
@@ -1,5 +1,5 @@
 
-#line 374 "./glsl.g"
+#line 378 "./glsl.g"
 
 /**************************************************************************
 **
@@ -159,137 +159,137 @@ TranslationUnit *Parser::parse()
     return 0;
 }
 
-#line 536 "./glsl.g"
+#line 540 "./glsl.g"
 
 void Parser::reduce(int ruleno)
 {
 switch(ruleno) {
 
-#line 545 "./glsl.g"
+#line 549 "./glsl.g"
 
 case 0: {
     ast(1) = makeAstNode<IdentifierExpression>(string(1));
 }   break;
 
-#line 552 "./glsl.g"
+#line 556 "./glsl.g"
 
 case 1: {
     ast(1) = makeAstNode<LiteralExpression>(string(1));
 }   break;
 
-#line 559 "./glsl.g"
+#line 563 "./glsl.g"
 
 case 2: {
     ast(1) = makeAstNode<LiteralExpression>(_engine->identifier("true", 4));
 }   break;
 
-#line 566 "./glsl.g"
+#line 570 "./glsl.g"
 
 case 3: {
     ast(1) = makeAstNode<LiteralExpression>(_engine->identifier("false", 5));
 }   break;
 
-#line 573 "./glsl.g"
+#line 577 "./glsl.g"
 
 case 4: {
     // nothing to do.
 }   break;
 
-#line 580 "./glsl.g"
+#line 584 "./glsl.g"
 
 case 5: {
     ast(1) = ast(2);
 }   break;
 
-#line 587 "./glsl.g"
+#line 591 "./glsl.g"
 
 case 6: {
     // nothing to do.
 }   break;
 
-#line 594 "./glsl.g"
+#line 598 "./glsl.g"
 
 case 7: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_ArrayAccess, expression(1), expression(3));
 }   break;
 
-#line 601 "./glsl.g"
+#line 605 "./glsl.g"
 
 case 8: {
     // nothing to do.
 }   break;
 
-#line 608 "./glsl.g"
+#line 612 "./glsl.g"
 
 case 9: {
     ast(1) = makeAstNode<MemberAccessExpression>(expression(1), string(3));
 }   break;
 
-#line 615 "./glsl.g"
+#line 619 "./glsl.g"
 
 case 10: {
     ast(1) = makeAstNode<UnaryExpression>(AST::Kind_PostIncrement, expression(1));
 }   break;
 
-#line 622 "./glsl.g"
+#line 626 "./glsl.g"
 
 case 11: {
     ast(1) = makeAstNode<UnaryExpression>(AST::Kind_PostDecrement, expression(1));
 }   break;
 
-#line 629 "./glsl.g"
+#line 633 "./glsl.g"
 
 case 12: {
     // nothing to do.
 }   break;
 
-#line 636 "./glsl.g"
+#line 640 "./glsl.g"
 
 case 13: {
     // nothing to do.
 }   break;
 
-#line 643 "./glsl.g"
+#line 647 "./glsl.g"
 
 case 14: {
     ast(1) = makeAstNode<FunctionCallExpression>
         (sym(1).function.id, sym(1).function.arguments);
 }   break;
 
-#line 651 "./glsl.g"
+#line 655 "./glsl.g"
 
 case 15: {
     ast(1) = makeAstNode<FunctionCallExpression>
         (expression(1), sym(3).function.id, sym(3).function.arguments);
 }   break;
 
-#line 659 "./glsl.g"
+#line 663 "./glsl.g"
 
 case 16: {
     // nothing to do.
 }   break;
 
-#line 666 "./glsl.g"
+#line 670 "./glsl.g"
 
 case 17: {
     // nothing to do.
 }   break;
 
-#line 673 "./glsl.g"
+#line 677 "./glsl.g"
 
 case 18: {
     sym(1).function.id = sym(1).function_identifier;
     sym(1).function.arguments = 0;
 }   break;
 
-#line 681 "./glsl.g"
+#line 685 "./glsl.g"
 
 case 19: {
     sym(1).function.id = sym(1).function_identifier;
     sym(1).function.arguments = 0;
 }   break;
 
-#line 689 "./glsl.g"
+#line 693 "./glsl.g"
 
 case 20: {
     sym(1).function.id = sym(1).function_identifier;
@@ -297,7 +297,7 @@ case 20: {
         makeAstNode< List<Expression *> >(expression(2));
 }   break;
 
-#line 698 "./glsl.g"
+#line 702 "./glsl.g"
 
 case 21: {
     sym(1).function.arguments =
@@ -305,607 +305,655 @@ case 21: {
             (sym(1).function.arguments, expression(3));
 }   break;
 
-#line 707 "./glsl.g"
+#line 711 "./glsl.g"
 
 case 22: {
     // nothing to do.
 }   break;
 
-#line 714 "./glsl.g"
+#line 718 "./glsl.g"
 
 case 23: {
     ast(1) = makeAstNode<FunctionIdentifier>(type(1));
 }   break;
 
-#line 721 "./glsl.g"
+#line 725 "./glsl.g"
 
 case 24: {
     ast(1) = makeAstNode<FunctionIdentifier>(string(1));
 }   break;
 
-#line 728 "./glsl.g"
+#line 732 "./glsl.g"
 
 case 25: {
     // nothing to do.
 }   break;
 
-#line 735 "./glsl.g"
+#line 739 "./glsl.g"
 
 case 26: {
     ast(1) = makeAstNode<UnaryExpression>(AST::Kind_PreIncrement, expression(1));
 }   break;
 
-#line 742 "./glsl.g"
+#line 746 "./glsl.g"
 
 case 27: {
     ast(1) = makeAstNode<UnaryExpression>(AST::Kind_PreDecrement, expression(1));
 }   break;
 
-#line 749 "./glsl.g"
+#line 753 "./glsl.g"
 
 case 28: {
     ast(1) = makeAstNode<UnaryExpression>(sym(1).kind, expression(2));
 }   break;
 
-#line 756 "./glsl.g"
+#line 760 "./glsl.g"
 
 case 29: {
     sym(1).kind = AST::Kind_UnaryPlus;
 }   break;
 
-#line 763 "./glsl.g"
+#line 767 "./glsl.g"
 
 case 30: {
     sym(1).kind = AST::Kind_UnaryMinus;
 }   break;
 
-#line 770 "./glsl.g"
+#line 774 "./glsl.g"
 
 case 31: {
     sym(1).kind = AST::Kind_LogicalNot;
 }   break;
 
-#line 777 "./glsl.g"
+#line 781 "./glsl.g"
 
 case 32: {
     sym(1).kind = AST::Kind_BitwiseNot;
 }   break;
 
-#line 784 "./glsl.g"
+#line 788 "./glsl.g"
 
 case 33: {
     // nothing to do.
 }   break;
 
-#line 791 "./glsl.g"
+#line 795 "./glsl.g"
 
 case 34: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Multiply, expression(1), expression(3));
 }   break;
 
-#line 798 "./glsl.g"
+#line 802 "./glsl.g"
 
 case 35: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Divide, expression(1), expression(3));
 }   break;
 
-#line 805 "./glsl.g"
+#line 809 "./glsl.g"
 
 case 36: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Modulus, expression(1), expression(3));
 }   break;
 
-#line 812 "./glsl.g"
+#line 816 "./glsl.g"
 
 case 37: {
     // nothing to do.
 }   break;
 
-#line 819 "./glsl.g"
+#line 823 "./glsl.g"
 
 case 38: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Plus, expression(1), expression(3));
 }   break;
 
-#line 826 "./glsl.g"
+#line 830 "./glsl.g"
 
 case 39: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Minus, expression(1), expression(3));
 }   break;
 
-#line 833 "./glsl.g"
+#line 837 "./glsl.g"
 
 case 40: {
     // nothing to do.
 }   break;
 
-#line 840 "./glsl.g"
+#line 844 "./glsl.g"
 
 case 41: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_ShiftLeft, expression(1), expression(3));
 }   break;
 
-#line 847 "./glsl.g"
+#line 851 "./glsl.g"
 
 case 42: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_ShiftRight, expression(1), expression(3));
 }   break;
 
-#line 854 "./glsl.g"
+#line 858 "./glsl.g"
 
 case 43: {
     // nothing to do.
 }   break;
 
-#line 861 "./glsl.g"
+#line 865 "./glsl.g"
 
 case 44: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_LessThan, expression(1), expression(3));
 }   break;
 
-#line 868 "./glsl.g"
+#line 872 "./glsl.g"
 
 case 45: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_GreaterThan, expression(1), expression(3));
 }   break;
 
-#line 875 "./glsl.g"
+#line 879 "./glsl.g"
 
 case 46: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_LessEqual, expression(1), expression(3));
 }   break;
 
-#line 882 "./glsl.g"
+#line 886 "./glsl.g"
 
 case 47: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_GreaterEqual, expression(1), expression(3));
 }   break;
 
-#line 889 "./glsl.g"
+#line 893 "./glsl.g"
 
 case 48: {
     // nothing to do.
 }   break;
 
-#line 896 "./glsl.g"
+#line 900 "./glsl.g"
 
 case 49: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Equal, expression(1), expression(3));
 }   break;
 
-#line 903 "./glsl.g"
+#line 907 "./glsl.g"
 
 case 50: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_NotEqual, expression(1), expression(3));
 }   break;
 
-#line 910 "./glsl.g"
+#line 914 "./glsl.g"
 
 case 51: {
     // nothing to do.
 }   break;
 
-#line 917 "./glsl.g"
+#line 921 "./glsl.g"
 
 case 52: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_BitwiseAnd, expression(1), expression(3));
 }   break;
 
-#line 924 "./glsl.g"
+#line 928 "./glsl.g"
 
 case 53: {
     // nothing to do.
 }   break;
 
-#line 931 "./glsl.g"
+#line 935 "./glsl.g"
 
 case 54: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_BitwiseOr, expression(1), expression(3));
 }   break;
 
-#line 938 "./glsl.g"
+#line 942 "./glsl.g"
 
 case 55: {
     // nothing to do.
 }   break;
 
-#line 945 "./glsl.g"
+#line 949 "./glsl.g"
 
 case 56: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_BitwiseXor, expression(1), expression(3));
 }   break;
 
-#line 952 "./glsl.g"
+#line 956 "./glsl.g"
 
 case 57: {
     // nothing to do.
 }   break;
 
-#line 959 "./glsl.g"
+#line 963 "./glsl.g"
 
 case 58: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_LogicalAnd, expression(1), expression(3));
 }   break;
 
-#line 966 "./glsl.g"
+#line 970 "./glsl.g"
 
 case 59: {
     // nothing to do.
 }   break;
 
-#line 973 "./glsl.g"
+#line 977 "./glsl.g"
 
 case 60: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_LogicalXor, expression(1), expression(3));
 }   break;
 
-#line 980 "./glsl.g"
+#line 984 "./glsl.g"
 
 case 61: {
     // nothing to do.
 }   break;
 
-#line 987 "./glsl.g"
+#line 991 "./glsl.g"
 
 case 62: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_LogicalOr, expression(1), expression(3));
 }   break;
 
-#line 994 "./glsl.g"
+#line 998 "./glsl.g"
 
 case 63: {
     // nothing to do.
 }   break;
 
-#line 1001 "./glsl.g"
+#line 1005 "./glsl.g"
 
 case 64: {
     ast(1) = makeAstNode<TernaryExpression>(AST::Kind_Conditional, expression(1), expression(3), expression(5));
 }   break;
 
-#line 1008 "./glsl.g"
+#line 1012 "./glsl.g"
 
 case 65: {
     // nothing to do.
 }   break;
 
-#line 1015 "./glsl.g"
+#line 1019 "./glsl.g"
 
 case 66: {
     ast(1) = makeAstNode<AssignmentExpression>(sym(2).kind, expression(1), expression(3));
 }   break;
 
-#line 1022 "./glsl.g"
+#line 1026 "./glsl.g"
 
 case 67: {
     sym(1).kind = AST::Kind_Assign;
 }   break;
 
-#line 1029 "./glsl.g"
+#line 1033 "./glsl.g"
 
 case 68: {
     sym(1).kind = AST::Kind_AssignMultiply;
 }   break;
 
-#line 1036 "./glsl.g"
+#line 1040 "./glsl.g"
 
 case 69: {
     sym(1).kind = AST::Kind_AssignDivide;
 }   break;
 
-#line 1043 "./glsl.g"
+#line 1047 "./glsl.g"
 
 case 70: {
     sym(1).kind = AST::Kind_AssignModulus;
 }   break;
 
-#line 1050 "./glsl.g"
+#line 1054 "./glsl.g"
 
 case 71: {
     sym(1).kind = AST::Kind_AssignPlus;
 }   break;
 
-#line 1057 "./glsl.g"
+#line 1061 "./glsl.g"
 
 case 72: {
     sym(1).kind = AST::Kind_AssignMinus;
 }   break;
 
-#line 1064 "./glsl.g"
+#line 1068 "./glsl.g"
 
 case 73: {
     sym(1).kind = AST::Kind_AssignShiftLeft;
 }   break;
 
-#line 1071 "./glsl.g"
+#line 1075 "./glsl.g"
 
 case 74: {
     sym(1).kind = AST::Kind_AssignShiftRight;
 }   break;
 
-#line 1078 "./glsl.g"
+#line 1082 "./glsl.g"
 
 case 75: {
     sym(1).kind = AST::Kind_AssignAnd;
 }   break;
 
-#line 1085 "./glsl.g"
+#line 1089 "./glsl.g"
 
 case 76: {
     sym(1).kind = AST::Kind_AssignXor;
 }   break;
 
-#line 1092 "./glsl.g"
+#line 1096 "./glsl.g"
 
 case 77: {
     sym(1).kind = AST::Kind_AssignOr;
 }   break;
 
-#line 1099 "./glsl.g"
+#line 1103 "./glsl.g"
 
 case 78: {
     // nothing to do.
 }   break;
 
-#line 1106 "./glsl.g"
+#line 1110 "./glsl.g"
 
 case 79: {
     ast(1) = makeAstNode<BinaryExpression>(AST::Kind_Comma, expression(1), expression(3));
 }   break;
 
-#line 1113 "./glsl.g"
+#line 1117 "./glsl.g"
 
 case 80: {
     // nothing to do.
 }   break;
 
-#line 1120 "./glsl.g"
+#line 1124 "./glsl.g"
 
 case 81: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1127 "./glsl.g"
+#line 1131 "./glsl.g"
 
 case 82: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<InitDeclaration>(sym(1).declaration_list);
 }   break;
 
-#line 1134 "./glsl.g"
+#line 1138 "./glsl.g"
 
 case 83: {
     ast(1) = makeAstNode<PrecisionDeclaration>(sym(2).precision, type(3));
 }   break;
 
-#line 1141 "./glsl.g"
+#line 1145 "./glsl.g"
 
 case 84: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1148 "./glsl.g"
+#line 1152 "./glsl.g"
 
 case 85: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1155 "./glsl.g"
+#line 1159 "./glsl.g"
 
 case 86: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1162 "./glsl.g"
+#line 1166 "./glsl.g"
 
 case 87: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1169 "./glsl.g"
+#line 1173 "./glsl.g"
 
 case 88: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1176 "./glsl.g"
+#line 1180 "./glsl.g"
 
 case 89: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1183 "./glsl.g"
+#line 1187 "./glsl.g"
 
 case 90: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1190 "./glsl.g"
+#line 1194 "./glsl.g"
 
 case 91: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1197 "./glsl.g"
+#line 1201 "./glsl.g"
 
 case 92: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1204 "./glsl.g"
+#line 1208 "./glsl.g"
 
 case 93: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1211 "./glsl.g"
+#line 1215 "./glsl.g"
 
 case 94: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 1218 "./glsl.g"
+#line 1222 "./glsl.g"
 
 case 95: {
-    // ast(1) = new ...AST(...);
+    sym(1).param_declarator.type = type(1);
+    sym(1).param_declarator.name = string(2);
 }   break;
 
-#line 1225 "./glsl.g"
+#line 1230 "./glsl.g"
 
 case 96: {
-    // ast(1) = new ...AST(...);
+    sym(1).param_declarator.type = makeAstNode<ArrayType>(type(1), expression(4));
+    sym(1).param_declarator.name = string(2);
 }   break;
 
-#line 1232 "./glsl.g"
+#line 1238 "./glsl.g"
 
 case 97: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (makeAstNode<QualifiedType>
+            (sym(1).qualifier, sym(3).param_declarator.type,
+             (List<LayoutQualifier *> *)0),
+         ParameterDeclaration::Qualifier(sym(2).qualifier),
+         sym(3).param_declarator.name);
 }   break;
 
-#line 1239 "./glsl.g"
+#line 1250 "./glsl.g"
 
 case 98: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (sym(2).param_declarator.type,
+         ParameterDeclaration::Qualifier(sym(1).qualifier),
+         sym(2).param_declarator.name);
 }   break;
 
-#line 1246 "./glsl.g"
+#line 1260 "./glsl.g"
 
 case 99: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (makeAstNode<QualifiedType>
+            (sym(1).qualifier, type(3), (List<LayoutQualifier *> *)0),
+         ParameterDeclaration::Qualifier(sym(2).qualifier),
+         (const std::string *)0);
 }   break;
 
-#line 1253 "./glsl.g"
+#line 1271 "./glsl.g"
 
 case 100: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<ParameterDeclaration>
+        (type(2), ParameterDeclaration::Qualifier(sym(1).qualifier),
+         (const std::string *)0);
 }   break;
 
-#line 1260 "./glsl.g"
+#line 1280 "./glsl.g"
 
 case 101: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::In;
 }   break;
 
-#line 1267 "./glsl.g"
+#line 1287 "./glsl.g"
 
 case 102: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::In;
 }   break;
 
-#line 1274 "./glsl.g"
+#line 1294 "./glsl.g"
 
 case 103: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::Out;
 }   break;
 
-#line 1281 "./glsl.g"
+#line 1301 "./glsl.g"
 
 case 104: {
-    // ast(1) = new ...AST(...);
+    sym(1).qualifier = ParameterDeclaration::InOut;
 }   break;
 
-#line 1288 "./glsl.g"
+#line 1308 "./glsl.g"
 
 case 105: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 
-#line 1295 "./glsl.g"
+#line 1315 "./glsl.g"
 
 case 106: {
-    // ast(1) = new ...AST(...);
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+        (sym(1).declaration);
 }   break;
 
-#line 1302 "./glsl.g"
+#line 1323 "./glsl.g"
 
 case 107: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1309 "./glsl.g"
+#line 1333 "./glsl.g"
 
 case 108: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type);
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1316 "./glsl.g"
+#line 1344 "./glsl.g"
 
 case 109: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type, expression(5));
+    Declaration *decl = makeAstNode<VariableDeclaration>(type, string(3));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1323 "./glsl.g"
+#line 1355 "./glsl.g"
 
 case 110: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type);
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(7));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1330 "./glsl.g"
+#line 1367 "./glsl.g"
 
 case 111: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    type = makeAstNode<ArrayType>(type, expression(5));
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(8));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1337 "./glsl.g"
+#line 1379 "./glsl.g"
 
 case 112: {
-    // ast(1) = new ...AST(...);
+    Type *type = VariableDeclaration::declarationType(sym(1).declaration_list);
+    Declaration *decl = makeAstNode<VariableDeclaration>
+            (type, string(3), expression(5));
+    sym(1).declaration_list = makeAstNode< List<Declaration *> >
+            (sym(1).declaration_list, decl);
 }   break;
 
-#line 1344 "./glsl.g"
+#line 1390 "./glsl.g"
 
 case 113: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<TypeDeclaration>(type(1));
 }   break;
 
-#line 1351 "./glsl.g"
+#line 1397 "./glsl.g"
 
 case 114: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>(type(1), string(2));
 }   break;
 
-#line 1358 "./glsl.g"
+#line 1404 "./glsl.g"
 
 case 115: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1)), string(2));
 }   break;
 
-#line 1365 "./glsl.g"
+#line 1412 "./glsl.g"
 
 case 116: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1), expression(4)), string(2));
 }   break;
 
-#line 1372 "./glsl.g"
+#line 1420 "./glsl.g"
 
 case 117: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1)), string(2), expression(6));
 }   break;
 
-#line 1379 "./glsl.g"
+#line 1428 "./glsl.g"
 
 case 118: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (makeAstNode<ArrayType>(type(1), expression(4)),
+         string(2), expression(7));
 }   break;
 
-#line 1386 "./glsl.g"
+#line 1437 "./glsl.g"
 
 case 119: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<VariableDeclaration>
+        (type(1), string(2), expression(4));
 }   break;
 
-#line 1393 "./glsl.g"
+#line 1445 "./glsl.g"
 
 case 120: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<InvariantDeclaration>(string(2));
 }   break;
 
-#line 1400 "./glsl.g"
+#line 1452 "./glsl.g"
 
 case 121: {
     ast(1) = makeAstNode<QualifiedType>(0, type(1), (List<LayoutQualifier *> *)0);
 }   break;
 
-#line 1407 "./glsl.g"
+#line 1459 "./glsl.g"
 
 case 122: {
     ast(1) = makeAstNode<QualifiedType>
@@ -913,207 +961,207 @@ case 122: {
          sym(1).type_qualifier.layout_list);
 }   break;
 
-#line 1416 "./glsl.g"
+#line 1468 "./glsl.g"
 
 case 123: {
     sym(1).qualifier = QualifiedType::Invariant;
 }   break;
 
-#line 1423 "./glsl.g"
+#line 1475 "./glsl.g"
 
 case 124: {
     sym(1).qualifier = QualifiedType::Smooth;
 }   break;
 
-#line 1430 "./glsl.g"
+#line 1482 "./glsl.g"
 
 case 125: {
     sym(1).qualifier = QualifiedType::Flat;
 }   break;
 
-#line 1437 "./glsl.g"
+#line 1489 "./glsl.g"
 
 case 126: {
     sym(1).qualifier = QualifiedType::NoPerspective;
 }   break;
 
-#line 1444 "./glsl.g"
+#line 1496 "./glsl.g"
 
 case 127: {
     sym(1) = sym(3);
 }   break;
 
-#line 1451 "./glsl.g"
+#line 1503 "./glsl.g"
 
 case 128: {
     sym(1).layout_list = makeAstNode< List<LayoutQualifier *> >(sym(1).layout);
 }   break;
 
-#line 1458 "./glsl.g"
+#line 1510 "./glsl.g"
 
 case 129: {
     sym(1).layout_list = makeAstNode< List<LayoutQualifier *> >(sym(1).layout_list, sym(3).layout);
 }   break;
 
-#line 1465 "./glsl.g"
+#line 1517 "./glsl.g"
 
 case 130: {
     sym(1).layout = makeAstNode<LayoutQualifier>(string(1), (const std::string *)0);
 }   break;
 
-#line 1472 "./glsl.g"
+#line 1524 "./glsl.g"
 
 case 131: {
     sym(1).layout = makeAstNode<LayoutQualifier>(string(1), string(3));
 }   break;
 
-#line 1479 "./glsl.g"
+#line 1531 "./glsl.g"
 
 case 132: {
     sym(1).qualifier = QualifiedType::Const;
 }   break;
 
-#line 1486 "./glsl.g"
+#line 1538 "./glsl.g"
 
 case 133: {
     sym(1).type_qualifier.qualifier = sym(1).qualifier;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1494 "./glsl.g"
+#line 1546 "./glsl.g"
 
 case 134: {
     sym(1).type_qualifier.layout_list = sym(1).layout_list;
     sym(1).type_qualifier.qualifier = 0;
 }   break;
 
-#line 1502 "./glsl.g"
+#line 1554 "./glsl.g"
 
 case 135: {
     sym(1).type_qualifier.layout_list = sym(1).layout_list;
     sym(1).type_qualifier.qualifier = sym(2).qualifier;
 }   break;
 
-#line 1510 "./glsl.g"
+#line 1562 "./glsl.g"
 
 case 136: {
     sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1518 "./glsl.g"
+#line 1570 "./glsl.g"
 
 case 137: {
     sym(1).type_qualifier.qualifier = sym(1).qualifier;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1526 "./glsl.g"
+#line 1578 "./glsl.g"
 
 case 138: {
     sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1534 "./glsl.g"
+#line 1586 "./glsl.g"
 
 case 139: {
     sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier | sym(3).qualifier;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1542 "./glsl.g"
+#line 1594 "./glsl.g"
 
 case 140: {
     sym(1).type_qualifier.qualifier = QualifiedType::Invariant;
     sym(1).type_qualifier.layout_list = 0;
 }   break;
 
-#line 1550 "./glsl.g"
+#line 1602 "./glsl.g"
 
 case 141: {
     sym(1).qualifier = QualifiedType::Const;
 }   break;
 
-#line 1557 "./glsl.g"
+#line 1609 "./glsl.g"
 
 case 142: {
     sym(1).qualifier = QualifiedType::Attribute;
 }   break;
 
-#line 1564 "./glsl.g"
+#line 1616 "./glsl.g"
 
 case 143: {
     sym(1).qualifier = QualifiedType::Varying;
 }   break;
 
-#line 1571 "./glsl.g"
+#line 1623 "./glsl.g"
 
 case 144: {
     sym(1).qualifier = QualifiedType::CentroidVarying;
 }   break;
 
-#line 1578 "./glsl.g"
+#line 1630 "./glsl.g"
 
 case 145: {
     sym(1).qualifier = QualifiedType::In;
 }   break;
 
-#line 1585 "./glsl.g"
+#line 1637 "./glsl.g"
 
 case 146: {
     sym(1).qualifier = QualifiedType::Out;
 }   break;
 
-#line 1592 "./glsl.g"
+#line 1644 "./glsl.g"
 
 case 147: {
     sym(1).qualifier = QualifiedType::CentroidIn;
 }   break;
 
-#line 1599 "./glsl.g"
+#line 1651 "./glsl.g"
 
 case 148: {
     sym(1).qualifier = QualifiedType::CentroidOut;
 }   break;
 
-#line 1606 "./glsl.g"
+#line 1658 "./glsl.g"
 
 case 149: {
     sym(1).qualifier = QualifiedType::PatchIn;
 }   break;
 
-#line 1613 "./glsl.g"
+#line 1665 "./glsl.g"
 
 case 150: {
     sym(1).qualifier = QualifiedType::PatchOut;
 }   break;
 
-#line 1620 "./glsl.g"
+#line 1672 "./glsl.g"
 
 case 151: {
     sym(1).qualifier = QualifiedType::SampleIn;
 }   break;
 
-#line 1627 "./glsl.g"
+#line 1679 "./glsl.g"
 
 case 152: {
     sym(1).qualifier = QualifiedType::SampleOut;
 }   break;
 
-#line 1634 "./glsl.g"
+#line 1686 "./glsl.g"
 
 case 153: {
     sym(1).qualifier = QualifiedType::Uniform;
 }   break;
 
-#line 1641 "./glsl.g"
+#line 1693 "./glsl.g"
 
 case 154: {
     // nothing to do.
 }   break;
 
-#line 1648 "./glsl.g"
+#line 1700 "./glsl.g"
 
 case 155: {
     if (!type(2)->setPrecision(sym(1).precision)) {
@@ -1122,595 +1170,595 @@ case 155: {
     ast(1) = type(2);
 }   break;
 
-#line 1658 "./glsl.g"
+#line 1710 "./glsl.g"
 
 case 156: {
     // nothing to do.
 }   break;
 
-#line 1665 "./glsl.g"
+#line 1717 "./glsl.g"
 
 case 157: {
     ast(1) = makeAstNode<ArrayType>(type(1));
 }   break;
 
-#line 1672 "./glsl.g"
+#line 1724 "./glsl.g"
 
 case 158: {
     ast(1) = makeAstNode<ArrayType>(type(1), expression(3));
 }   break;
 
-#line 1679 "./glsl.g"
+#line 1731 "./glsl.g"
 
 case 159: {
     ast(1) = makeBasicType(T_VOID, Type::Void);
 }   break;
 
-#line 1686 "./glsl.g"
+#line 1738 "./glsl.g"
 
 case 160: {
     ast(1) = makeBasicType(T_FLOAT, Type::Primitive);
 }   break;
 
-#line 1693 "./glsl.g"
+#line 1745 "./glsl.g"
 
 case 161: {
     ast(1) = makeBasicType(T_DOUBLE, Type::Primitive);
 }   break;
 
-#line 1700 "./glsl.g"
+#line 1752 "./glsl.g"
 
 case 162: {
     ast(1) = makeBasicType(T_INT, Type::Primitive);
 }   break;
 
-#line 1707 "./glsl.g"
+#line 1759 "./glsl.g"
 
 case 163: {
     ast(1) = makeBasicType(T_UINT, Type::Primitive);
 }   break;
 
-#line 1714 "./glsl.g"
+#line 1766 "./glsl.g"
 
 case 164: {
     ast(1) = makeBasicType(T_BOOL, Type::Primitive);
 }   break;
 
-#line 1721 "./glsl.g"
+#line 1773 "./glsl.g"
 
 case 165: {
     ast(1) = makeBasicType(T_VEC2, Type::Vector2);
 }   break;
 
-#line 1728 "./glsl.g"
+#line 1780 "./glsl.g"
 
 case 166: {
     ast(1) = makeBasicType(T_VEC3, Type::Vector3);
 }   break;
 
-#line 1735 "./glsl.g"
+#line 1787 "./glsl.g"
 
 case 167: {
     ast(1) = makeBasicType(T_VEC4, Type::Vector4);
 }   break;
 
-#line 1742 "./glsl.g"
+#line 1794 "./glsl.g"
 
 case 168: {
     ast(1) = makeBasicType(T_DVEC2, Type::Vector2);
 }   break;
 
-#line 1749 "./glsl.g"
+#line 1801 "./glsl.g"
 
 case 169: {
     ast(1) = makeBasicType(T_DVEC3, Type::Vector3);
 }   break;
 
-#line 1756 "./glsl.g"
+#line 1808 "./glsl.g"
 
 case 170: {
     ast(1) = makeBasicType(T_DVEC4, Type::Vector4);
 }   break;
 
-#line 1763 "./glsl.g"
+#line 1815 "./glsl.g"
 
 case 171: {
     ast(1) = makeBasicType(T_BVEC2, Type::Vector2);
 }   break;
 
-#line 1770 "./glsl.g"
+#line 1822 "./glsl.g"
 
 case 172: {
     ast(1) = makeBasicType(T_BVEC3, Type::Vector3);
 }   break;
 
-#line 1777 "./glsl.g"
+#line 1829 "./glsl.g"
 
 case 173: {
     ast(1) = makeBasicType(T_BVEC4, Type::Vector4);
 }   break;
 
-#line 1784 "./glsl.g"
+#line 1836 "./glsl.g"
 
 case 174: {
     ast(1) = makeBasicType(T_IVEC2, Type::Vector2);
 }   break;
 
-#line 1791 "./glsl.g"
+#line 1843 "./glsl.g"
 
 case 175: {
     ast(1) = makeBasicType(T_IVEC3, Type::Vector3);
 }   break;
 
-#line 1798 "./glsl.g"
+#line 1850 "./glsl.g"
 
 case 176: {
     ast(1) = makeBasicType(T_IVEC4, Type::Vector4);
 }   break;
 
-#line 1805 "./glsl.g"
+#line 1857 "./glsl.g"
 
 case 177: {
     ast(1) = makeBasicType(T_UVEC2, Type::Vector2);
 }   break;
 
-#line 1812 "./glsl.g"
+#line 1864 "./glsl.g"
 
 case 178: {
     ast(1) = makeBasicType(T_UVEC3, Type::Vector3);
 }   break;
 
-#line 1819 "./glsl.g"
+#line 1871 "./glsl.g"
 
 case 179: {
     ast(1) = makeBasicType(T_UVEC4, Type::Vector4);
 }   break;
 
-#line 1826 "./glsl.g"
+#line 1878 "./glsl.g"
 
 case 180: {
     ast(1) = makeBasicType(T_MAT2, Type::Matrix);
 }   break;
 
-#line 1833 "./glsl.g"
+#line 1885 "./glsl.g"
 
 case 181: {
     ast(1) = makeBasicType(T_MAT3, Type::Matrix);
 }   break;
 
-#line 1840 "./glsl.g"
+#line 1892 "./glsl.g"
 
 case 182: {
     ast(1) = makeBasicType(T_MAT4, Type::Matrix);
 }   break;
 
-#line 1847 "./glsl.g"
+#line 1899 "./glsl.g"
 
 case 183: {
     ast(1) = makeBasicType(T_MAT2X2, Type::Matrix);
 }   break;
 
-#line 1854 "./glsl.g"
+#line 1906 "./glsl.g"
 
 case 184: {
     ast(1) = makeBasicType(T_MAT2X3, Type::Matrix);
 }   break;
 
-#line 1861 "./glsl.g"
+#line 1913 "./glsl.g"
 
 case 185: {
     ast(1) = makeBasicType(T_MAT2X4, Type::Matrix);
 }   break;
 
-#line 1868 "./glsl.g"
+#line 1920 "./glsl.g"
 
 case 186: {
     ast(1) = makeBasicType(T_MAT3X2, Type::Matrix);
 }   break;
 
-#line 1875 "./glsl.g"
+#line 1927 "./glsl.g"
 
 case 187: {
     ast(1) = makeBasicType(T_MAT3X3, Type::Matrix);
 }   break;
 
-#line 1882 "./glsl.g"
+#line 1934 "./glsl.g"
 
 case 188: {
     ast(1) = makeBasicType(T_MAT3X4, Type::Matrix);
 }   break;
 
-#line 1889 "./glsl.g"
+#line 1941 "./glsl.g"
 
 case 189: {
     ast(1) = makeBasicType(T_MAT4X2, Type::Matrix);
 }   break;
 
-#line 1896 "./glsl.g"
+#line 1948 "./glsl.g"
 
 case 190: {
     ast(1) = makeBasicType(T_MAT4X3, Type::Matrix);
 }   break;
 
-#line 1903 "./glsl.g"
+#line 1955 "./glsl.g"
 
 case 191: {
     ast(1) = makeBasicType(T_MAT4X4, Type::Matrix);
 }   break;
 
-#line 1910 "./glsl.g"
+#line 1962 "./glsl.g"
 
 case 192: {
     ast(1) = makeBasicType(T_DMAT2, Type::Matrix);
 }   break;
 
-#line 1917 "./glsl.g"
+#line 1969 "./glsl.g"
 
 case 193: {
     ast(1) = makeBasicType(T_DMAT3, Type::Matrix);
 }   break;
 
-#line 1924 "./glsl.g"
+#line 1976 "./glsl.g"
 
 case 194: {
     ast(1) = makeBasicType(T_DMAT4, Type::Matrix);
 }   break;
 
-#line 1931 "./glsl.g"
+#line 1983 "./glsl.g"
 
 case 195: {
     ast(1) = makeBasicType(T_DMAT2X2, Type::Matrix);
 }   break;
 
-#line 1938 "./glsl.g"
+#line 1990 "./glsl.g"
 
 case 196: {
     ast(1) = makeBasicType(T_DMAT2X3, Type::Matrix);
 }   break;
 
-#line 1945 "./glsl.g"
+#line 1997 "./glsl.g"
 
 case 197: {
     ast(1) = makeBasicType(T_DMAT2X4, Type::Matrix);
 }   break;
 
-#line 1952 "./glsl.g"
+#line 2004 "./glsl.g"
 
 case 198: {
     ast(1) = makeBasicType(T_DMAT3X2, Type::Matrix);
 }   break;
 
-#line 1959 "./glsl.g"
+#line 2011 "./glsl.g"
 
 case 199: {
     ast(1) = makeBasicType(T_DMAT3X3, Type::Matrix);
 }   break;
 
-#line 1966 "./glsl.g"
+#line 2018 "./glsl.g"
 
 case 200: {
     ast(1) = makeBasicType(T_DMAT3X4, Type::Matrix);
 }   break;
 
-#line 1973 "./glsl.g"
+#line 2025 "./glsl.g"
 
 case 201: {
     ast(1) = makeBasicType(T_DMAT4X2, Type::Matrix);
 }   break;
 
-#line 1980 "./glsl.g"
+#line 2032 "./glsl.g"
 
 case 202: {
     ast(1) = makeBasicType(T_DMAT4X3, Type::Matrix);
 }   break;
 
-#line 1987 "./glsl.g"
+#line 2039 "./glsl.g"
 
 case 203: {
     ast(1) = makeBasicType(T_DMAT4X4, Type::Matrix);
 }   break;
 
-#line 1994 "./glsl.g"
+#line 2046 "./glsl.g"
 
 case 204: {
     ast(1) = makeBasicType(T_SAMPLER1D, Type::Sampler1D);
 }   break;
 
-#line 2001 "./glsl.g"
+#line 2053 "./glsl.g"
 
 case 205: {
     ast(1) = makeBasicType(T_SAMPLER2D, Type::Sampler2D);
 }   break;
 
-#line 2008 "./glsl.g"
+#line 2060 "./glsl.g"
 
 case 206: {
     ast(1) = makeBasicType(T_SAMPLER3D, Type::Sampler3D);
 }   break;
 
-#line 2015 "./glsl.g"
+#line 2067 "./glsl.g"
 
 case 207: {
     ast(1) = makeBasicType(T_SAMPLERCUBE, Type::SamplerCube);
 }   break;
 
-#line 2022 "./glsl.g"
+#line 2074 "./glsl.g"
 
 case 208: {
     ast(1) = makeBasicType(T_SAMPLER1DSHADOW, Type::Sampler1DShadow);
 }   break;
 
-#line 2029 "./glsl.g"
+#line 2081 "./glsl.g"
 
 case 209: {
     ast(1) = makeBasicType(T_SAMPLER2DSHADOW, Type::Sampler2DShadow);
 }   break;
 
-#line 2036 "./glsl.g"
+#line 2088 "./glsl.g"
 
 case 210: {
     ast(1) = makeBasicType(T_SAMPLERCUBESHADOW, Type::SamplerCubeShadow);
 }   break;
 
-#line 2043 "./glsl.g"
+#line 2095 "./glsl.g"
 
 case 211: {
     ast(1) = makeBasicType(T_SAMPLER1DARRAY, Type::Sampler1DArray);
 }   break;
 
-#line 2050 "./glsl.g"
+#line 2102 "./glsl.g"
 
 case 212: {
     ast(1) = makeBasicType(T_SAMPLER2DARRAY, Type::Sampler2DArray);
 }   break;
 
-#line 2057 "./glsl.g"
+#line 2109 "./glsl.g"
 
 case 213: {
     ast(1) = makeBasicType(T_SAMPLER1DARRAYSHADOW, Type::Sampler1DArrayShadow);
 }   break;
 
-#line 2064 "./glsl.g"
+#line 2116 "./glsl.g"
 
 case 214: {
     ast(1) = makeBasicType(T_SAMPLER2DARRAYSHADOW, Type::Sampler2DArrayShadow);
 }   break;
 
-#line 2071 "./glsl.g"
+#line 2123 "./glsl.g"
 
 case 215: {
     ast(1) = makeBasicType(T_SAMPLERCUBEARRAY, Type::SamplerCubeShadow);
 }   break;
 
-#line 2078 "./glsl.g"
+#line 2130 "./glsl.g"
 
 case 216: {
     ast(1) = makeBasicType(T_SAMPLERCUBEARRAYSHADOW, Type::SamplerCubeArrayShadow);
 }   break;
 
-#line 2085 "./glsl.g"
+#line 2137 "./glsl.g"
 
 case 217: {
     ast(1) = makeBasicType(T_ISAMPLER1D, Type::Sampler1D);
 }   break;
 
-#line 2092 "./glsl.g"
+#line 2144 "./glsl.g"
 
 case 218: {
     ast(1) = makeBasicType(T_ISAMPLER2D, Type::Sampler2D);
 }   break;
 
-#line 2099 "./glsl.g"
+#line 2151 "./glsl.g"
 
 case 219: {
     ast(1) = makeBasicType(T_ISAMPLER3D, Type::Sampler3D);
 }   break;
 
-#line 2106 "./glsl.g"
+#line 2158 "./glsl.g"
 
 case 220: {
     ast(1) = makeBasicType(T_ISAMPLERCUBE, Type::SamplerCube);
 }   break;
 
-#line 2113 "./glsl.g"
+#line 2165 "./glsl.g"
 
 case 221: {
     ast(1) = makeBasicType(T_ISAMPLER1DARRAY, Type::Sampler1DArray);
 }   break;
 
-#line 2120 "./glsl.g"
+#line 2172 "./glsl.g"
 
 case 222: {
     ast(1) = makeBasicType(T_ISAMPLER2DARRAY, Type::Sampler2DArray);
 }   break;
 
-#line 2127 "./glsl.g"
+#line 2179 "./glsl.g"
 
 case 223: {
     ast(1) = makeBasicType(T_ISAMPLERCUBEARRAY, Type::SamplerCubeArray);
 }   break;
 
-#line 2134 "./glsl.g"
+#line 2186 "./glsl.g"
 
 case 224: {
     ast(1) = makeBasicType(T_USAMPLER1D, Type::Sampler1D);
 }   break;
 
-#line 2141 "./glsl.g"
+#line 2193 "./glsl.g"
 
 case 225: {
     ast(1) = makeBasicType(T_USAMPLER2D, Type::Sampler2D);
 }   break;
 
-#line 2148 "./glsl.g"
+#line 2200 "./glsl.g"
 
 case 226: {
     ast(1) = makeBasicType(T_USAMPLER3D, Type::Sampler3D);
 }   break;
 
-#line 2155 "./glsl.g"
+#line 2207 "./glsl.g"
 
 case 227: {
     ast(1) = makeBasicType(T_USAMPLERCUBE, Type::SamplerCube);
 }   break;
 
-#line 2162 "./glsl.g"
+#line 2214 "./glsl.g"
 
 case 228: {
     ast(1) = makeBasicType(T_USAMPLER1DARRAY, Type::Sampler1DArray);
 }   break;
 
-#line 2169 "./glsl.g"
+#line 2221 "./glsl.g"
 
 case 229: {
     ast(1) = makeBasicType(T_USAMPLER2DARRAY, Type::Sampler2DArray);
 }   break;
 
-#line 2176 "./glsl.g"
+#line 2228 "./glsl.g"
 
 case 230: {
     ast(1) = makeBasicType(T_USAMPLERCUBEARRAY, Type::SamplerCubeArray);
 }   break;
 
-#line 2183 "./glsl.g"
+#line 2235 "./glsl.g"
 
 case 231: {
     ast(1) = makeBasicType(T_SAMPLER2DRECT, Type::Sampler2DRect);
 }   break;
 
-#line 2190 "./glsl.g"
+#line 2242 "./glsl.g"
 
 case 232: {
     ast(1) = makeBasicType(T_SAMPLER2DRECTSHADOW, Type::Sampler2DRectShadow);
 }   break;
 
-#line 2197 "./glsl.g"
+#line 2249 "./glsl.g"
 
 case 233: {
     ast(1) = makeBasicType(T_ISAMPLER2DRECT, Type::Sampler2DRect);
 }   break;
 
-#line 2204 "./glsl.g"
+#line 2256 "./glsl.g"
 
 case 234: {
     ast(1) = makeBasicType(T_USAMPLER2DRECT, Type::Sampler2DRect);
 }   break;
 
-#line 2211 "./glsl.g"
+#line 2263 "./glsl.g"
 
 case 235: {
     ast(1) = makeBasicType(T_SAMPLERBUFFER, Type::SamplerBuffer);
 }   break;
 
-#line 2218 "./glsl.g"
+#line 2270 "./glsl.g"
 
 case 236: {
     ast(1) = makeBasicType(T_ISAMPLERBUFFER, Type::SamplerBuffer);
 }   break;
 
-#line 2225 "./glsl.g"
+#line 2277 "./glsl.g"
 
 case 237: {
     ast(1) = makeBasicType(T_USAMPLERBUFFER, Type::SamplerBuffer);
 }   break;
 
-#line 2232 "./glsl.g"
+#line 2284 "./glsl.g"
 
 case 238: {
     ast(1) = makeBasicType(T_SAMPLER2DMS, Type::Sampler2DMS);
 }   break;
 
-#line 2239 "./glsl.g"
+#line 2291 "./glsl.g"
 
 case 239: {
     ast(1) = makeBasicType(T_ISAMPLER2DMS, Type::Sampler2DMS);
 }   break;
 
-#line 2246 "./glsl.g"
+#line 2298 "./glsl.g"
 
 case 240: {
     ast(1) = makeBasicType(T_USAMPLER2DMS, Type::Sampler2DMS);
 }   break;
 
-#line 2253 "./glsl.g"
+#line 2305 "./glsl.g"
 
 case 241: {
     ast(1) = makeBasicType(T_SAMPLER2DMSARRAY, Type::Sampler2DMSArray);
 }   break;
 
-#line 2260 "./glsl.g"
+#line 2312 "./glsl.g"
 
 case 242: {
     ast(1) = makeBasicType(T_ISAMPLER2DMSARRAY, Type::Sampler2DMSArray);
 }   break;
 
-#line 2267 "./glsl.g"
+#line 2319 "./glsl.g"
 
 case 243: {
     ast(1) = makeBasicType(T_USAMPLER2DMSARRAY, Type::Sampler2DMSArray);
 }   break;
 
-#line 2274 "./glsl.g"
+#line 2326 "./glsl.g"
 
 case 244: {
     // nothing to do.
 }   break;
 
-#line 2281 "./glsl.g"
+#line 2333 "./glsl.g"
 
 case 245: {
     ast(1) = makeAstNode<NamedType>(string(1));
 }   break;
 
-#line 2288 "./glsl.g"
+#line 2340 "./glsl.g"
 
 case 246: {
     sym(1).precision = Type::Highp;
 }   break;
 
-#line 2295 "./glsl.g"
+#line 2347 "./glsl.g"
 
 case 247: {
     sym(1).precision = Type::Mediump;
 }   break;
 
-#line 2302 "./glsl.g"
+#line 2354 "./glsl.g"
 
 case 248: {
     sym(1).precision = Type::Lowp;
 }   break;
 
-#line 2309 "./glsl.g"
+#line 2361 "./glsl.g"
 
 case 249: {
     ast(1) = makeAstNode<StructType>(string(2), sym(4).field_list);
 }   break;
 
-#line 2316 "./glsl.g"
+#line 2368 "./glsl.g"
 
 case 250: {
     ast(1) = makeAstNode<StructType>(sym(3).field_list);
 }   break;
 
-#line 2323 "./glsl.g"
+#line 2375 "./glsl.g"
 
 case 251: {
     // nothing to do.
 }   break;
 
-#line 2330 "./glsl.g"
+#line 2382 "./glsl.g"
 
 case 252: {
     sym(1).field_list = appendLists(sym(1).field_list, sym(2).field_list);
 }   break;
 
-#line 2337 "./glsl.g"
+#line 2389 "./glsl.g"
 
 case 253: {
     sym(1).field_list = StructType::fixInnerTypes(type(1), sym(2).field_list);
 }   break;
 
-#line 2344 "./glsl.g"
+#line 2396 "./glsl.g"
 
 case 254: {
     sym(1).field_list = StructType::fixInnerTypes
@@ -1719,320 +1767,321 @@ case 254: {
              sym(1).type_qualifier.layout_list), sym(3).field_list);
 }   break;
 
-#line 2354 "./glsl.g"
+#line 2406 "./glsl.g"
 
 case 255: {
     // nothing to do.
     sym(1).field_list = makeAstNode< List<StructType::Field *> >(sym(1).field);
 }   break;
 
-#line 2362 "./glsl.g"
+#line 2414 "./glsl.g"
 
 case 256: {
     sym(1).field_list = makeAstNode< List<StructType::Field *> >(sym(1).field_list, sym(3).field);
 }   break;
 
-#line 2369 "./glsl.g"
+#line 2421 "./glsl.g"
 
 case 257: {
     sym(1).field = makeAstNode<StructType::Field>(string(1));
 }   break;
 
-#line 2376 "./glsl.g"
+#line 2428 "./glsl.g"
 
 case 258: {
     sym(1).field = makeAstNode<StructType::Field>
         (string(1), makeAstNode<ArrayType>((Type *)0));
 }   break;
 
-#line 2384 "./glsl.g"
+#line 2436 "./glsl.g"
 
 case 259: {
     sym(1).field = makeAstNode<StructType::Field>
         (string(1), makeAstNode<ArrayType>((Type *)0, expression(3)));
 }   break;
 
-#line 2392 "./glsl.g"
+#line 2444 "./glsl.g"
 
 case 260: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 
-#line 2399 "./glsl.g"
+#line 2451 "./glsl.g"
 
 case 261: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<DeclarationStatement>(sym(1).declaration_list);
 }   break;
 
-#line 2406 "./glsl.g"
+#line 2458 "./glsl.g"
 
 case 262: {
     // nothing to do.
 }   break;
 
-#line 2413 "./glsl.g"
+#line 2465 "./glsl.g"
 
 case 263: {
     // nothing to do.
 }   break;
 
-#line 2420 "./glsl.g"
+#line 2472 "./glsl.g"
 
 case 264: {
     // nothing to do.
 }   break;
 
-#line 2427 "./glsl.g"
+#line 2479 "./glsl.g"
 
 case 265: {
     // nothing to do.
 }   break;
 
-#line 2434 "./glsl.g"
+#line 2486 "./glsl.g"
 
 case 266: {
     // nothing to do.
 }   break;
 
-#line 2441 "./glsl.g"
+#line 2493 "./glsl.g"
 
 case 267: {
     // nothing to do.
 }   break;
 
-#line 2448 "./glsl.g"
+#line 2500 "./glsl.g"
 
 case 268: {
     // nothing to do.
 }   break;
 
-#line 2455 "./glsl.g"
+#line 2507 "./glsl.g"
 
 case 269: {
     // nothing to do.
 }   break;
 
-#line 2462 "./glsl.g"
+#line 2514 "./glsl.g"
 
 case 270: {
     // nothing to do.
 }   break;
 
-#line 2469 "./glsl.g"
+#line 2521 "./glsl.g"
 
 case 271: {
     ast(1) = makeAstNode<CompoundStatement>();
 }   break;
 
-#line 2476 "./glsl.g"
+#line 2528 "./glsl.g"
 
 case 272: {
     ast(1) = makeAstNode<CompoundStatement>(sym(2).statement_list);
 }   break;
 
-#line 2483 "./glsl.g"
+#line 2535 "./glsl.g"
 
 case 273: {
     // nothing to do.
 }   break;
 
-#line 2490 "./glsl.g"
+#line 2542 "./glsl.g"
 
 case 274: {
     // nothing to do.
 }   break;
 
-#line 2497 "./glsl.g"
+#line 2549 "./glsl.g"
 
 case 275: {
     ast(1) = makeAstNode<CompoundStatement>();
 }   break;
 
-#line 2504 "./glsl.g"
+#line 2556 "./glsl.g"
 
 case 276: {
     ast(1) = makeAstNode<CompoundStatement>(sym(2).statement_list);
 }   break;
 
-#line 2511 "./glsl.g"
+#line 2563 "./glsl.g"
 
 case 277: {
     sym(1).statement_list = makeAstNode< List<Statement *> >(sym(1).statement);
 }   break;
 
-#line 2518 "./glsl.g"
+#line 2570 "./glsl.g"
 
 case 278: {
     sym(1).statement_list = makeAstNode< List<Statement *> >(sym(1).statement_list, sym(2).statement);
 }   break;
 
-#line 2525 "./glsl.g"
+#line 2577 "./glsl.g"
 
 case 279: {
     ast(1) = makeAstNode<CompoundStatement>();  // Empty statement
 }   break;
 
-#line 2532 "./glsl.g"
+#line 2584 "./glsl.g"
 
 case 280: {
     ast(1) = makeAstNode<ExpressionStatement>(expression(1));
 }   break;
 
-#line 2539 "./glsl.g"
+#line 2591 "./glsl.g"
 
 case 281: {
     ast(1) = makeAstNode<IfStatement>(expression(3), sym(5).ifstmt.thenClause, sym(5).ifstmt.elseClause);
 }   break;
 
-#line 2546 "./glsl.g"
+#line 2598 "./glsl.g"
 
 case 282: {
     sym(1).ifstmt.thenClause = statement(1);
     sym(1).ifstmt.elseClause = statement(3);
 }   break;
 
-#line 2554 "./glsl.g"
+#line 2606 "./glsl.g"
 
 case 283: {
     sym(1).ifstmt.thenClause = statement(1);
     sym(1).ifstmt.elseClause = 0;
 }   break;
 
-#line 2562 "./glsl.g"
+#line 2614 "./glsl.g"
 
 case 284: {
     // nothing to do.
 }   break;
 
-#line 2569 "./glsl.g"
+#line 2621 "./glsl.g"
 
 case 285: {
-    // ast(1) = new ...AST(...);
+    ast(1) = makeAstNode<DeclarationExpression>
+        (type(1), string(2), expression(4));
 }   break;
 
-#line 2576 "./glsl.g"
+#line 2629 "./glsl.g"
 
 case 286: {
     ast(1) = makeAstNode<SwitchStatement>(expression(3), statement(6));
 }   break;
 
-#line 2583 "./glsl.g"
+#line 2636 "./glsl.g"
 
 case 287: {
     ast(1) = makeAstNode<CompoundStatement>();
 }   break;
 
-#line 2590 "./glsl.g"
+#line 2643 "./glsl.g"
 
 case 288: {
     ast(1) = makeAstNode<CompoundStatement>(sym(1).statement_list);
 }   break;
 
-#line 2597 "./glsl.g"
+#line 2650 "./glsl.g"
 
 case 289: {
     ast(1) = makeAstNode<CaseLabelStatement>(expression(2));
 }   break;
 
-#line 2604 "./glsl.g"
+#line 2657 "./glsl.g"
 
 case 290: {
     ast(1) = makeAstNode<CaseLabelStatement>();
 }   break;
 
-#line 2611 "./glsl.g"
+#line 2664 "./glsl.g"
 
 case 291: {
     ast(1) = makeAstNode<WhileStatement>(expression(3), statement(5));
 }   break;
 
-#line 2618 "./glsl.g"
+#line 2671 "./glsl.g"
 
 case 292: {
     ast(1) = makeAstNode<DoStatement>(statement(2), expression(5));
 }   break;
 
-#line 2625 "./glsl.g"
+#line 2678 "./glsl.g"
 
 case 293: {
     ast(1) = makeAstNode<ForStatement>(statement(3), sym(4).forstmt.condition, sym(4).forstmt.increment, statement(6));
 }   break;
 
-#line 2632 "./glsl.g"
+#line 2685 "./glsl.g"
 
 case 294: {
     // nothing to do.
 }   break;
 
-#line 2639 "./glsl.g"
+#line 2692 "./glsl.g"
 
 case 295: {
     // nothing to do.
 }   break;
 
-#line 2646 "./glsl.g"
+#line 2699 "./glsl.g"
 
 case 296: {
     // nothing to do.
 }   break;
 
-#line 2653 "./glsl.g"
+#line 2706 "./glsl.g"
 
 case 297: {
     // nothing to do.
 }   break;
 
-#line 2660 "./glsl.g"
+#line 2713 "./glsl.g"
 
 case 298: {
     sym(1).forstmt.condition = expression(1);
     sym(1).forstmt.increment = 0;
 }   break;
 
-#line 2668 "./glsl.g"
+#line 2721 "./glsl.g"
 
 case 299: {
     sym(1).forstmt.condition = expression(1);
     sym(1).forstmt.increment = expression(3);
 }   break;
 
-#line 2676 "./glsl.g"
+#line 2729 "./glsl.g"
 
 case 300: {
     ast(1) = makeAstNode<JumpStatement>(AST::Kind_Continue);
 }   break;
 
-#line 2683 "./glsl.g"
+#line 2736 "./glsl.g"
 
 case 301: {
     ast(1) = makeAstNode<JumpStatement>(AST::Kind_Break);
 }   break;
 
-#line 2690 "./glsl.g"
+#line 2743 "./glsl.g"
 
 case 302: {
     ast(1) = makeAstNode<ReturnStatement>();
 }   break;
 
-#line 2697 "./glsl.g"
+#line 2750 "./glsl.g"
 
 case 303: {
     ast(1) = makeAstNode<ReturnStatement>(expression(2));
 }   break;
 
-#line 2704 "./glsl.g"
+#line 2757 "./glsl.g"
 
 case 304: {
     ast(1) = makeAstNode<JumpStatement>(AST::Kind_Discard);
 }   break;
 
-#line 2711 "./glsl.g"
+#line 2764 "./glsl.g"
 
 case 305: {
     ast(1) = makeAstNode<TranslationUnit>(sym(1).declaration_list);
 }   break;
 
-#line 2718 "./glsl.g"
+#line 2771 "./glsl.g"
 
 case 306: {
     if (sym(1).declaration) {
@@ -2043,7 +2092,7 @@ case 306: {
     }
 }   break;
 
-#line 2730 "./glsl.g"
+#line 2783 "./glsl.g"
 
 case 307: {
     if (sym(1).declaration_list && sym(2).declaration) {
@@ -2061,37 +2110,37 @@ case 307: {
     }
 }   break;
 
-#line 2749 "./glsl.g"
+#line 2802 "./glsl.g"
 
 case 308: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2756 "./glsl.g"
+#line 2809 "./glsl.g"
 
 case 309: {
-    // ast(1) = new ...AST(...);
+    // nothing to do.
 }   break;
 
-#line 2763 "./glsl.g"
+#line 2816 "./glsl.g"
 
 case 310: {
     ast(1) = 0;
 }   break;
 
-#line 2770 "./glsl.g"
+#line 2823 "./glsl.g"
 
 case 311: {
     // ast(1) = new ...AST(...);
 }   break;
 
-#line 2777 "./glsl.g"
+#line 2830 "./glsl.g"
 
 case 312: {
     ast(1) = 0;
 }   break;
 
-#line 2785 "./glsl.g"
+#line 2838 "./glsl.g"
 
 } // end switch
 } // end Parser::reduce()
index 05a9771..1e93ba5 100644 (file)
@@ -79,6 +79,10 @@ public:
             int qualifier;
             List<LayoutQualifier *> *layout_list;
         } type_qualifier;
+        struct {
+            Type *type;
+            const std::string *name;
+        } param_declarator;
         // ### ast nodes...
     };