From 77df7e7c2dcde3c014c2a26d1e8186f8f1bf60a6 Mon Sep 17 00:00:00 2001
From: Rhys Weatherley <rhys.weatherley@nokia.com>
Date: Thu, 11 Nov 2010 11:29:29 +1000
Subject: [PATCH] AST nodes for GLSL parser

---
 src/libs/glsl/glsl-lib.pri       |   6 +-
 src/libs/glsl/glslast.cpp        | 493 +++++++++++++++++++++++-
 src/libs/glsl/glslast.h          | 617 ++++++++++++++++++++++++++++++-
 src/libs/glsl/glslastvisitor.cpp |  40 ++
 src/libs/glsl/glslastvisitor.h   | 123 ++++++
 5 files changed, 1271 insertions(+), 8 deletions(-)
 create mode 100644 src/libs/glsl/glslastvisitor.cpp
 create mode 100644 src/libs/glsl/glslastvisitor.h

diff --git a/src/libs/glsl/glsl-lib.pri b/src/libs/glsl/glsl-lib.pri
index 0422945a868..be00cc8e751 100644
--- a/src/libs/glsl/glsl-lib.pri
+++ b/src/libs/glsl/glsl-lib.pri
@@ -1,6 +1,8 @@
-HEADERS += $$PWD/glsl.h $$PWD/glsllexer.h $$PWD/glslparser.h glslparsertable_p.h $$PWD/glslast.h
+HEADERS += $$PWD/glsl.h $$PWD/glsllexer.h $$PWD/glslparser.h glslparsertable_p.h $$PWD/glslast.h \
+    $$PWD/glslastvisitor.h
 SOURCES += $$PWD/glslkeywords.cpp $$PWD/glslparser.cpp $$PWD/glslparsertable.cpp \
-    $$PWD/glsllexer.cpp $$PWD/glslast.cpp $$PWD/glsldump.cpp $$PWD/glsldelete.cpp
+    $$PWD/glsllexer.cpp $$PWD/glslast.cpp $$PWD/glsldump.cpp $$PWD/glsldelete.cpp \
+        $$PWD/glslastvisitor.cpp
 
 OTHER_FILES = $$PWD/specs/glsl.g.in \
     $$PWD/specs/grammar.txt
diff --git a/src/libs/glsl/glslast.cpp b/src/libs/glsl/glslast.cpp
index c873ea655a5..eeca6bd40b7 100644
--- a/src/libs/glsl/glslast.cpp
+++ b/src/libs/glsl/glslast.cpp
@@ -27,14 +27,503 @@
 **
 **************************************************************************/
 #include "glslast.h"
+#include "glslastvisitor.h"
+#include "glslparsertable_p.h"
 
 using namespace GLSL;
 
-AST::AST()
+AST::~AST()
 {
 }
 
-AST::~AST()
+void AST::accept(Visitor *visitor)
+{
+    if (visitor->preVisit(this))
+        accept0(visitor);
+    visitor->postVisit(this);
+}
+
+void AST::accept(AST *ast, Visitor *visitor)
+{
+    if (ast)
+        ast->accept(visitor);
+}
+
+Statement *AST::makeCompound(Statement *left, Statement *right)
+{
+    if (!left)
+        return right;
+    else if (!right)
+        return left;
+    CompoundStatement *compound = left->asCompoundStatement();
+    if (compound) {
+        compound->statements.push_back(right);
+    } else {
+        compound = new CompoundStatement();
+        compound->statements.push_back(left);
+        compound->statements.push_back(right);
+    }
+    return compound;
+}
+
+void Operand::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+void Operator::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        for (_Base::iterator it = begin(); it != end(); ++it)
+            accept(*it, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+IdentifierExpression::~IdentifierExpression()
+{
+}
+
+void IdentifierExpression::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+LiteralExpression::~LiteralExpression()
+{
+}
+
+void LiteralExpression::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+BinaryExpression::~BinaryExpression()
+{
+    delete left;
+    delete right;
+}
+
+void BinaryExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(left, visitor);
+        accept(right, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+UnaryExpression::~UnaryExpression()
+{
+    delete expr;
+}
+
+void UnaryExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(expr, visitor);
+    visitor->endVisit(this);
+}
+
+TernaryExpression::~TernaryExpression()
+{
+    delete first;
+    delete second;
+    delete third;
+}
+
+void TernaryExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(first, visitor);
+        accept(second, visitor);
+        accept(third, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+AssignmentExpression::~AssignmentExpression()
+{
+    delete variable;
+    delete value;
+}
+
+void AssignmentExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(variable, visitor);
+        accept(value, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+MemberAccessExpression::~MemberAccessExpression()
+{
+    delete expr;
+}
+
+void MemberAccessExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(expr, visitor);
+    visitor->endVisit(this);
+}
+
+FunctionCallExpression::~FunctionCallExpression()
+{
+    delete expr;
+    for (std::vector<Expression *>::iterator it = arguments.begin(); it != arguments.end(); ++it)
+        delete *it;
+}
+
+void FunctionCallExpression::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(expr, visitor);
+        for (std::vector<Expression *>::iterator it = arguments.begin(); it != arguments.end(); ++it)
+            accept(*it, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+ExpressionStatement::~ExpressionStatement()
+{
+    delete expr;
+}
+
+void ExpressionStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(expr, visitor);
+    visitor->endVisit(this);
+}
+
+CompoundStatement::~CompoundStatement()
+{
+    for (std::vector<Statement *>::iterator it = statements.begin(); it != statements.end(); ++it)
+        delete *it;
+}
+
+void CompoundStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        for (std::vector<Statement *>::iterator it = statements.begin(); it != statements.end(); ++it)
+            accept(*it, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+IfStatement::~IfStatement()
+{
+    delete condition;
+    delete thenClause;
+    delete elseClause;
+}
+
+void IfStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(condition, visitor);
+        accept(thenClause, visitor);
+        accept(elseClause, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+WhileStatement::~WhileStatement()
+{
+    delete condition;
+    delete body;
+}
+
+void WhileStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(condition, visitor);
+        accept(body, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+DoStatement::~DoStatement()
+{
+    delete body;
+    delete condition;
+}
+
+void DoStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(body, visitor);
+        accept(condition, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+ForStatement::~ForStatement()
+{
+    delete init;
+    delete condition;
+    delete increment;
+    delete body;
+}
+
+void ForStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(init, visitor);
+        accept(condition, visitor);
+        accept(increment, visitor);
+        accept(body, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+JumpStatement::~JumpStatement()
 {
 }
 
+void JumpStatement::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+ReturnStatement::~ReturnStatement()
+{
+    delete expr;
+}
+
+void ReturnStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(expr, visitor);
+    visitor->endVisit(this);
+}
+
+SwitchStatement::~SwitchStatement()
+{
+    delete expr;
+    delete body;
+}
+
+void SwitchStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(expr, visitor);
+        accept(body, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+CaseLabelStatement::~CaseLabelStatement()
+{
+    delete expr;
+}
+
+void CaseLabelStatement::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(expr, visitor);
+    visitor->endVisit(this);
+}
+
+Type *Type::clone(Type *type)
+{
+    if (!type)
+        return 0;
+    Type *c = type->clone();
+    c->lineno = type->lineno;
+    return c;
+}
+
+BasicType::BasicType(int _token)
+    : Type(Kind_BasicType), token(_token)
+{
+    switch (token) {
+    case GLSLParserTable::T_VOID:
+    case GLSLParserTable::T_BOOL:
+    case GLSLParserTable::T_BVEC2:
+    case GLSLParserTable::T_BVEC3:
+    case GLSLParserTable::T_BVEC4:
+        prec = PrecNotValid;
+        break;
+    default:
+        prec = PrecUnspecified;
+        break;
+    }
+}
+
+BasicType::~BasicType()
+{
+}
+
+void BasicType::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+Type::Precision BasicType::precision() const
+{
+    return prec;
+}
+
+bool BasicType::setPrecision(Precision precision)
+{
+    if (prec == PrecNotValid)
+        return false;
+    prec = precision;
+    return true;
+}
+
+Type *BasicType::clone() const
+{
+    return new BasicType(token, prec);
+}
+
+NamedType::~NamedType()
+{
+}
+
+void NamedType::accept0(Visitor *visitor)
+{
+    visitor->visit(this);
+    visitor->endVisit(this);
+}
+
+Type::Precision NamedType::precision() const
+{
+    // Named types are typically structs, which cannot have their precision set.
+    return PrecNotValid;
+}
+
+bool NamedType::setPrecision(Precision)
+{
+    return false;
+}
+
+Type *NamedType::clone() const
+{
+    return new NamedType(name);
+}
+
+ArrayType::~ArrayType()
+{
+    delete elementType;
+    delete size;
+}
+
+void ArrayType::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(elementType, visitor);
+        accept(size, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+Type::Precision ArrayType::precision() const
+{
+    return elementType ? elementType->precision() : PrecNotValid;
+}
+
+bool ArrayType::setPrecision(Precision precision)
+{
+    if (elementType)
+        return elementType->setPrecision(precision);
+    else
+        return false;
+}
+
+Type *ArrayType::clone() const
+{
+    if (kind == Kind_ArrayType)
+        return new ArrayType(Type::clone(elementType), size);
+    else
+        return new ArrayType(Type::clone(elementType));
+}
+
+StructType::~StructType()
+{
+    for (std::vector<Field *>::iterator it = fields.begin(); it != fields.end(); ++it)
+        delete *it;
+}
+
+void StructType::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this)) {
+        for (std::vector<Field *>::iterator it = fields.begin(); it != fields.end(); ++it)
+            accept(*it, visitor);
+    }
+    visitor->endVisit(this);
+}
+
+Type::Precision StructType::precision() const
+{
+    return PrecNotValid;
+}
+
+bool StructType::setPrecision(Precision)
+{
+    // Structs cannot have a precision set.
+    return false;
+}
+
+Type *StructType::clone() const
+{
+    StructType *stype;
+    if (kind == Kind_AnonymousStructType)
+        stype = new StructType();
+    else
+        stype = new StructType(name);
+    for (std::vector<Field *>::const_iterator it = fields.begin(); it != fields.end(); ++it) {
+        stype->fields.push_back
+            (new Field((*it)->name, Type::clone((*it)->type)));
+    }
+    return stype;
+}
+
+StructType::Field::~Field()
+{
+    delete type;
+}
+
+void StructType::Field::accept0(Visitor *visitor)
+{
+    if (visitor->visit(this))
+        accept(type, visitor);
+    visitor->endVisit(this);
+}
+
+void StructType::Field::setInnerType(Type *innerType)
+{
+    if (!innerType)
+        return;
+    Type **parent = &type;
+    Type *inner = type;
+    while (inner != 0) {
+        ArrayType *array = inner->asArrayType();
+        if (!array)
+            break;
+        parent = &(array->elementType);
+        inner = array->elementType;
+    }
+    *parent = Type::clone(innerType);
+}
+
+void StructType::fixInnerTypes(Type *innerType, std::vector<Field *> &fields)
+{
+    for (size_t index = 0; index < fields.size(); ++index)
+        fields[index]->setInnerType(innerType);
+    delete innerType;   // No longer needed - cloned into all fields.
+}
+
+void StructType::addFields(const std::vector<Field *> &list)
+{
+    for (size_t index = 0; index < list.size(); ++index)
+        fields.push_back(list[index]);
+}
diff --git a/src/libs/glsl/glslast.h b/src/libs/glsl/glslast.h
index e273055cf39..cf6cbdce8af 100644
--- a/src/libs/glsl/glslast.h
+++ b/src/libs/glsl/glslast.h
@@ -29,25 +29,183 @@
 #ifndef GLSLAST_H
 #define GLSLAST_H
 
+#include "glsl.h"
 #include <vector>
+#include <string>
 
 namespace GLSL {
 
 class AST;
 class Operand;
 class Operator;
+class Expression;
+class IdentifierExpression;
+class LiteralExpression;
+class BinaryExpression;
+class UnaryExpression;
+class TernaryExpression;
+class AssignmentExpression;
+class MemberAccessExpression;
+class FunctionCallExpression;
+class Statement;
+class ExpressionStatement;
+class CompoundStatement;
+class IfStatement;
+class WhileStatement;
+class DoStatement;
+class ForStatement;
+class JumpStatement;
+class ReturnStatement;
+class SwitchStatement;
+class CaseLabelStatement;
+class Type;
+class BasicType;
+class NamedType;
+class ArrayType;
+class StructType;
+class Visitor;
 
-class AST
+class GLSL_EXPORT AST
 {
 public:
-    AST();
+    enum Kind {
+        Kind_Undefined,
+
+        // Primary expressions
+        Kind_Identifier,
+        Kind_Literal,
+
+        // Unary expressions
+        Kind_PreIncrement,
+        Kind_PostIncrement,
+        Kind_PreDecrement,
+        Kind_PostDecrement,
+        Kind_UnaryPlus,
+        Kind_UnaryMinus,
+        Kind_LogicalNot,
+        Kind_BitwiseNot,
+
+        // Binary expressions
+        Kind_Plus,
+        Kind_Minus,
+        Kind_Multiply,
+        Kind_Divide,
+        Kind_Modulus,
+        Kind_ShiftLeft,
+        Kind_ShiftRight,
+        Kind_Equal,
+        Kind_NotEqual,
+        Kind_LessThan,
+        Kind_LessEqual,
+        Kind_GreaterThan,
+        Kind_GreaterEqual,
+        Kind_LogicalAnd,
+        Kind_LogicalOr,
+        Kind_BitwiseAnd,
+        Kind_BitwiseOr,
+        Kind_BitwiseXor,
+        Kind_Comma,
+        Kind_ArrayAccess,
+
+        // Other expressions
+        Kind_Conditional,
+        Kind_MemberAccess,
+        Kind_FunctionCall,
+        Kind_MemberFunctionCall,
+
+        // Assignment expressions
+        Kind_Assign,
+        Kind_AssignPlus,
+        Kind_AssignMinus,
+        Kind_AssignMultiply,
+        Kind_AssignDivide,
+        Kind_AssignModulus,
+        Kind_AssignShiftLeft,
+        Kind_AssignShiftRight,
+        Kind_AssignAnd,
+        Kind_AssignOr,
+        Kind_AssignXor,
+
+        // Statements
+        Kind_ExpressionStatement,
+        Kind_CompoundStatement,
+        Kind_If,
+        Kind_While,
+        Kind_Do,
+        Kind_For,
+        Kind_Break,
+        Kind_Continue,
+        Kind_Discard,
+        Kind_Return,
+        Kind_ReturnExpression,
+        Kind_Switch,
+        Kind_CaseLabel,
+        Kind_DefaultLabel,
+
+        // Declarations
+
+        // Types
+        Kind_BasicType,
+        Kind_NamedType,
+        Kind_ArrayType,
+        Kind_OpenArrayType,
+        Kind_StructType,
+        Kind_AnonymousStructType,
+        Kind_StructField
+    };
+
+    AST() : kind(Kind_Undefined), lineno(0) {}
     virtual ~AST();
 
     virtual Operand *asOperand() { return 0; }
     virtual Operator *asOperator() { return 0; }
+
+    virtual Expression *asExpression() { return 0; }
+    virtual IdentifierExpression *asIdentifierExpression() { return 0; }
+    virtual LiteralExpression *asLiteralExpression() { return 0; }
+    virtual BinaryExpression *asBinaryExpression() { return 0; }
+    virtual UnaryExpression *asUnaryExpression() { return 0; }
+    virtual TernaryExpression *asTernaryExpression() { return 0; }
+    virtual AssignmentExpression *asAssignmentExpression() { return 0; }
+    virtual MemberAccessExpression *asMemberAccessExpression() { return 0; }
+    virtual FunctionCallExpression *asFunctionCallExpression() { return 0; }
+
+    virtual Statement *asStatement() { return 0; }
+    virtual ExpressionStatement *asExpressionStatement() { return 0; }
+    virtual CompoundStatement *asCompoundStatement() { return 0; }
+    virtual IfStatement *asIfStatement() { return 0; }
+    virtual WhileStatement *asWhileStatement() { return 0; }
+    virtual DoStatement *asDoStatement() { return 0; }
+    virtual ForStatement *asForStatement() { return 0; }
+    virtual JumpStatement *asJumpStatement() { return 0; }
+    virtual ReturnStatement *asReturnStatement() { return 0; }
+    virtual SwitchStatement *asSwitchStatement() { return 0; }
+    virtual CaseLabelStatement *asCaseLabelStatement() { return 0; }
+
+    virtual Type *asType() { return 0; }
+    virtual BasicType *asBasicType() { return 0; }
+    virtual NamedType *asNamedType() { return 0; }
+    virtual ArrayType *asArrayType() { return 0; }
+    virtual StructType *asStructType() { return 0; }
+
+    void accept(Visitor *visitor);
+    static void accept(AST *ast, Visitor *visitor);
+
+    virtual void accept0(Visitor *visitor) = 0;
+
+    // Efficiently make a compound statement out of "left" and "right",
+    // removing left-recursion in the process.
+    static Statement *makeCompound(Statement *left, Statement *right);
+
+protected:
+    AST(Kind _kind) : kind(_kind), lineno(0) {}
+
+public: // attributes
+    int kind;
+    int lineno;
 };
 
-class Operand: public AST
+class GLSL_EXPORT Operand: public AST
 {
 public:
     Operand(int location)
@@ -55,11 +213,13 @@ public:
 
     virtual Operand *asOperand() { return this; }
 
+    virtual void accept0(Visitor *visitor);
+
 public: // attributes
     int location;
 };
 
-class Operator: public AST, public std::vector<AST *>
+class GLSL_EXPORT Operator: public AST, public std::vector<AST *>
 {
     typedef std::vector<AST *> _Base;
 
@@ -70,10 +230,459 @@ public:
 
     virtual Operator *asOperator() { return this; }
 
+    virtual void accept0(Visitor *visitor);
+
 public: // attributes
     int ruleno;
 };
 
+class GLSL_EXPORT Expression: public AST
+{
+protected:
+    Expression(Kind _kind) { kind = _kind; }
+
+public:
+    virtual Expression *asExpression() { return this; }
+};
+
+class GLSL_EXPORT IdentifierExpression: public Expression
+{
+public:
+    IdentifierExpression(const std::string &_name)
+        : Expression(Kind_Identifier), name(_name) {}
+    ~IdentifierExpression();
+
+    virtual IdentifierExpression *asIdentifierExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    std::string name;
+};
+
+class GLSL_EXPORT LiteralExpression: public Expression
+{
+public:
+    LiteralExpression(const std::string &_value)
+        : Expression(Kind_Literal), value(_value) {}
+    ~LiteralExpression();
+
+    virtual LiteralExpression *asLiteralExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    std::string value;
+};
+
+class GLSL_EXPORT BinaryExpression: public Expression
+{
+public:
+    BinaryExpression(Kind _kind, Expression *_left, Expression *_right)
+        : Expression(_kind), left(_left), right(_right) {}
+    ~BinaryExpression();
+
+    virtual BinaryExpression *asBinaryExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *left;
+    Expression *right;
+};
+
+class GLSL_EXPORT UnaryExpression: public Expression
+{
+public:
+    UnaryExpression(Kind _kind, Expression *_expr)
+        : Expression(_kind), expr(_expr) {}
+    ~UnaryExpression();
+
+    virtual UnaryExpression *asUnaryExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+};
+
+class GLSL_EXPORT TernaryExpression: public Expression
+{
+public:
+    TernaryExpression(Kind _kind, Expression *_first, Expression *_second, Expression *_third)
+        : Expression(_kind), first(_first), second(_second), third(_third) {}
+    ~TernaryExpression();
+
+    virtual TernaryExpression *asTernaryExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *first;
+    Expression *second;
+    Expression *third;
+};
+
+class GLSL_EXPORT AssignmentExpression: public Expression
+{
+public:
+    AssignmentExpression(Kind _kind, Expression *_variable, Expression *_value)
+        : Expression(_kind), variable(_variable), value(_value) {}
+    ~AssignmentExpression();
+
+    virtual AssignmentExpression *asAssignmentExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *variable;
+    Expression *value;
+};
+
+class GLSL_EXPORT MemberAccessExpression: public Expression
+{
+public:
+    MemberAccessExpression(Expression *_expr, const std::string &_field)
+        : Expression(Kind_MemberAccess), expr(_expr), field(_field) {}
+    ~MemberAccessExpression();
+
+    virtual MemberAccessExpression *asMemberAccessExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+    std::string field;
+};
+
+class GLSL_EXPORT FunctionCallExpression: public Expression
+{
+public:
+    FunctionCallExpression(const std::string &_name)
+        : Expression(Kind_FunctionCall), expr(0), name(_name) {}
+    FunctionCallExpression(Expression *_expr, const std::string &_name)
+        : Expression(Kind_MemberFunctionCall), expr(_expr), name(_name) {}
+    ~FunctionCallExpression();
+
+    void addArgument(Expression *expr) { arguments.push_back(expr); }
+
+    virtual FunctionCallExpression *asFunctionCallExpression() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+    std::string name;
+    std::vector<Expression *> arguments;
+};
+
+class GLSL_EXPORT Statement: public AST
+{
+protected:
+    Statement(Kind _kind) : AST(_kind) {}
+
+public:
+    virtual Statement *asStatement() { return this; }
+};
+
+class GLSL_EXPORT ExpressionStatement: public Statement
+{
+public:
+    ExpressionStatement(Expression *_expr)
+        : Statement(Kind_ExpressionStatement), expr(_expr) {}
+    ~ExpressionStatement();
+
+    virtual ExpressionStatement *asExpressionStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+};
+
+class GLSL_EXPORT CompoundStatement: public Statement
+{
+public:
+    CompoundStatement() : Statement(Kind_CompoundStatement) {}
+    ~CompoundStatement();
+
+    virtual CompoundStatement *asCompoundStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    std::vector<Statement *> statements;
+};
+
+class GLSL_EXPORT IfStatement: public Statement
+{
+public:
+    IfStatement(Expression *_condition, Statement *_thenClause, Statement *_elseClause)
+        : Statement(Kind_If), condition(_condition)
+        , thenClause(_thenClause), elseClause(_elseClause) {}
+    ~IfStatement();
+
+    virtual IfStatement *asIfStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *condition;
+    Statement *thenClause;
+    Statement *elseClause;
+};
+
+class GLSL_EXPORT WhileStatement: public Statement
+{
+public:
+    WhileStatement(Expression *_condition, Statement *_body)
+        : Statement(Kind_While), condition(_condition), body(_body) {}
+    ~WhileStatement();
+
+    virtual WhileStatement *asWhileStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *condition;
+    Statement *body;
+};
+
+class GLSL_EXPORT DoStatement: public Statement
+{
+public:
+    DoStatement(Statement *_body, Expression *_condition)
+        : Statement(Kind_Do), body(_body), condition(_condition) {}
+    ~DoStatement();
+
+    virtual DoStatement *asDoStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Statement *body;
+    Expression *condition;
+};
+
+class GLSL_EXPORT ForStatement: public Statement
+{
+public:
+    ForStatement(Statement *_init, Expression *_condition, Expression *_increment, Statement *_body)
+        : Statement(Kind_For), init(_init), condition(_condition), increment(_increment), body(_body) {}
+    ~ForStatement();
+
+    virtual ForStatement *asForStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Statement *init;
+    Expression *condition;
+    Expression *increment;
+    Statement *body;
+};
+
+class GLSL_EXPORT JumpStatement: public Statement
+{
+public:
+    JumpStatement(Kind _kind) : Statement(_kind) {}
+    ~JumpStatement();
+
+    virtual JumpStatement *asJumpStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+};
+
+class GLSL_EXPORT ReturnStatement: public Statement
+{
+public:
+    ReturnStatement() : Statement(Kind_Return), expr(0) {}
+    ReturnStatement(Expression *_expr)
+        : Statement(Kind_ReturnExpression), expr(_expr) {}
+    ~ReturnStatement();
+
+    virtual ReturnStatement *asReturnStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+};
+
+class GLSL_EXPORT SwitchStatement: public Statement
+{
+public:
+    SwitchStatement(Expression *_expr, Statement *_body)
+        : Statement(Kind_Switch), expr(_expr), body(_body) {}
+    ~SwitchStatement();
+
+    virtual SwitchStatement *asSwitchStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+    Statement *body;
+};
+
+class GLSL_EXPORT CaseLabelStatement: public Statement
+{
+public:
+    CaseLabelStatement() : Statement(Kind_DefaultLabel), expr(0) {}
+    CaseLabelStatement(Expression *_expr)
+        : Statement(Kind_CaseLabel), expr(_expr) {}
+    ~CaseLabelStatement();
+
+    virtual CaseLabelStatement *asCaseLabelStatement() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+public: // attributes
+    Expression *expr;
+};
+
+class GLSL_EXPORT Type: public AST
+{
+protected:
+    Type(Kind _kind) : AST(_kind) {}
+
+public:
+    enum Precision
+    {
+        PrecNotValid,       // Precision not valid (e.g. structs and samplers).
+        PrecUnspecified,    // Precision not known, but can be validly set.
+        Lowp,
+        Mediump,
+        Highp
+    };
+
+    virtual Type *asType() { return this; }
+
+    virtual Precision precision() const = 0;
+
+    // Set the precision for the innermost basic type.  Returns false if it
+    // is not valid to set a precision (e.g. structs, samplers, etc).
+    virtual bool setPrecision(Precision precision) = 0;
+
+    virtual Type *clone() const = 0;
+    static Type *clone(Type *type);
+};
+
+class GLSL_EXPORT BasicType: public Type
+{
+public:
+    // Pass the parser's token code: T_VOID, T_VEC4, etc.
+    BasicType(int _token);
+    BasicType(int _token, Precision _prec)
+        : Type(Kind_BasicType), prec(_prec), token(_token) {}
+    ~BasicType();
+
+    virtual BasicType *asBasicType() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+    virtual Precision precision() const;
+    virtual bool setPrecision(Precision precision);
+
+    virtual Type *clone() const;
+
+public: // attributes
+    Precision prec;
+    int token;
+};
+
+class GLSL_EXPORT NamedType: public Type
+{
+public:
+    NamedType(const std::string &_name) : Type(Kind_NamedType), name(_name) {}
+    ~NamedType();
+
+    virtual NamedType *asNamedType() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+    virtual Precision precision() const;
+    virtual bool setPrecision(Precision precision);
+
+    virtual Type *clone() const;
+
+public: // attributes
+    std::string name;
+};
+
+class GLSL_EXPORT ArrayType: public Type
+{
+public:
+    ArrayType(Type *_elementType)
+        : Type(Kind_OpenArrayType), elementType(_elementType), size(0) {}
+    ArrayType(Type *_elementType, Expression *_size)
+        : Type(Kind_ArrayType), elementType(_elementType), size(_size) {}
+    ~ArrayType();
+
+    virtual ArrayType *asArrayType() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+    virtual Precision precision() const;
+    virtual bool setPrecision(Precision precision);
+
+    virtual Type *clone() const;
+
+public: // attributes
+    Type *elementType;
+    Expression *size;
+};
+
+class GLSL_EXPORT StructType: public Type
+{
+public:
+    StructType() : Type(Kind_AnonymousStructType) {}
+    StructType(const std::string &_name)
+        : Type(Kind_StructType), name(_name) {}
+    ~StructType();
+
+    virtual StructType *asStructType() { return this; }
+
+    virtual void accept0(Visitor *visitor);
+
+    virtual Precision precision() const;
+    virtual bool setPrecision(Precision precision);
+
+    virtual Type *clone() const;
+
+    class Field: public AST
+    {
+    public:
+        Field(const std::string &_name)
+            : AST(Kind_StructField), name(_name), type(0) {}
+
+        // Takes the outer shell of an array type with the innermost
+        // element type set to null.  The fixInnerTypes() method will
+        // set the innermost element type to a meaningful value.
+        Field(const std::string &_name, Type *_type)
+            : AST(Kind_StructField), name(_name), type(_type) {}
+
+        ~Field();
+
+        virtual void accept0(Visitor *visitor);
+
+        void setInnerType(Type *innerType);
+
+        std::string name;
+        Type *type;
+    };
+
+    // Fix the inner types of a field list.  The "innerType" will
+    // be cloned into all the fields and then deleted.
+    static void fixInnerTypes(Type *innerType, std::vector<Field *> &fields);
+
+    void addFields(const std::vector<Field *> &list);
+
+public: // attributes
+    std::string name;
+    std::vector<Field *> fields;
+};
+
 } // namespace GLSL
 
 #endif // GLSLAST_H
diff --git a/src/libs/glsl/glslastvisitor.cpp b/src/libs/glsl/glslastvisitor.cpp
new file mode 100644
index 00000000000..da22d0c299d
--- /dev/null
+++ b/src/libs/glsl/glslastvisitor.cpp
@@ -0,0 +1,40 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "glslastvisitor.h"
+
+using namespace GLSL;
+
+Visitor::Visitor()
+{
+}
+
+Visitor::~Visitor()
+{
+}
diff --git a/src/libs/glsl/glslastvisitor.h b/src/libs/glsl/glslastvisitor.h
new file mode 100644
index 00000000000..b0ae8c64c60
--- /dev/null
+++ b/src/libs/glsl/glslastvisitor.h
@@ -0,0 +1,123 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#ifndef GLSLASTVISITOR_H
+#define GLSLASTVISITOR_H
+
+#include "glslast.h"
+
+namespace GLSL {
+
+class GLSL_EXPORT Visitor
+{
+public:
+    Visitor();
+    virtual ~Visitor();
+
+    virtual bool preVisit(AST *) { return true; }
+    virtual void postVisit(AST *) {}
+
+    virtual bool visit(Operand *) { return true; }
+    virtual void endVisit(Operand *) {}
+
+    virtual bool visit(Operator *) { return true; }
+    virtual void endVisit(Operator *) {}
+
+    virtual bool visit(IdentifierExpression *) { return true; }
+    virtual void endVisit(IdentifierExpression *) {}
+
+    virtual bool visit(LiteralExpression *) { return true; }
+    virtual void endVisit(LiteralExpression *) {}
+
+    virtual bool visit(BinaryExpression *) { return true; }
+    virtual void endVisit(BinaryExpression *) {}
+
+    virtual bool visit(UnaryExpression *) { return true; }
+    virtual void endVisit(UnaryExpression *) {}
+
+    virtual bool visit(TernaryExpression *) { return true; }
+    virtual void endVisit(TernaryExpression *) {}
+
+    virtual bool visit(AssignmentExpression *) { return true; }
+    virtual void endVisit(AssignmentExpression *) {}
+
+    virtual bool visit(MemberAccessExpression *) { return true; }
+    virtual void endVisit(MemberAccessExpression *) {}
+
+    virtual bool visit(FunctionCallExpression *) { return true; }
+    virtual void endVisit(FunctionCallExpression *) {}
+
+    virtual bool visit(ExpressionStatement *) { return true; }
+    virtual void endVisit(ExpressionStatement *) {}
+
+    virtual bool visit(CompoundStatement *) { return true; }
+    virtual void endVisit(CompoundStatement *) {}
+
+    virtual bool visit(IfStatement *) { return true; }
+    virtual void endVisit(IfStatement *) {}
+
+    virtual bool visit(WhileStatement *) { return true; }
+    virtual void endVisit(WhileStatement *) {}
+
+    virtual bool visit(DoStatement *) { return true; }
+    virtual void endVisit(DoStatement *) {}
+
+    virtual bool visit(ForStatement *) { return true; }
+    virtual void endVisit(ForStatement *) {}
+
+    virtual bool visit(JumpStatement *) { return true; }
+    virtual void endVisit(JumpStatement *) {}
+
+    virtual bool visit(ReturnStatement *) { return true; }
+    virtual void endVisit(ReturnStatement *) {}
+
+    virtual bool visit(SwitchStatement *) { return true; }
+    virtual void endVisit(SwitchStatement *) {}
+
+    virtual bool visit(CaseLabelStatement *) { return true; }
+    virtual void endVisit(CaseLabelStatement *) {}
+
+    virtual bool visit(BasicType *) { return true; }
+    virtual void endVisit(BasicType *) {}
+
+    virtual bool visit(NamedType *) { return true; }
+    virtual void endVisit(NamedType *) {}
+
+    virtual bool visit(ArrayType *) { return true; }
+    virtual void endVisit(ArrayType *) {}
+
+    virtual bool visit(StructType *) { return true; }
+    virtual void endVisit(StructType *) {}
+
+    virtual bool visit(StructType::Field *) { return true; }
+    virtual void endVisit(StructType::Field *) {}
+};
+
+} // namespace GLSL
+
+#endif // GLSLASTVISITOR_H
-- 
GitLab