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