diff --git a/src/libs/glsl/glsl.h b/src/libs/glsl/glsl.h index de6a151153a..1916fc33f7c 100644 --- a/src/libs/glsl/glsl.h +++ b/src/libs/glsl/glsl.h @@ -62,6 +62,8 @@ class VectorType; class MatrixType; // symbols +class Symbol; +class Scope; class Struct; class Function; class Argument; diff --git a/src/libs/glsl/glslengine.cpp b/src/libs/glsl/glslengine.cpp index 0c19ec9e788..5d8157823dd 100644 --- a/src/libs/glsl/glslengine.cpp +++ b/src/libs/glsl/glslengine.cpp @@ -28,6 +28,8 @@ **************************************************************************/ #include "glslengine.h" +#include "glslsymbols.h" +#include "glsltypes.h" using namespace GLSL; @@ -82,6 +84,7 @@ Engine::Engine() Engine::~Engine() { + qDeleteAll(_symbols); } const QString *Engine::identifier(const QString &s) @@ -181,3 +184,42 @@ bool GLSL::DiagnosticMessage::isWarning() const { return _kind == Warning; } + +Struct *Engine::newStruct(Scope *scope) +{ + Struct *s = new Struct(scope); + _symbols.append(s); + return s; +} + +Block *Engine::newBlock(Scope *scope) +{ + Block *s = new Block(scope); + _symbols.append(s); + return s; +} + +Function *Engine::newFunction(Scope *scope) +{ + Function *s = new Function(scope); + _symbols.append(s); + return s; +} + +Argument *Engine::newArgument(Function *function, const QString &name, const Type *type) +{ + Argument *a = new Argument(function); + a->setName(name); + a->setType(type); + _symbols.append(a); + return a; +} + +Variable *Engine::newVariable(Scope *scope, const QString &name, const Type *type) +{ + Variable *var = new Variable(scope); + var->setName(name); + var->setType(type); + _symbols.append(var); + return var; +} diff --git a/src/libs/glsl/glslengine.h b/src/libs/glsl/glslengine.h index 9ad8f464a22..b89a07ba6bd 100644 --- a/src/libs/glsl/glslengine.h +++ b/src/libs/glsl/glslengine.h @@ -98,6 +98,7 @@ public: const QString *identifier(const char *s, int n); QSet identifiers() const; + // types const UndefinedType *undefinedType(); const VoidType *voidType(); const BoolType *boolType(); @@ -108,6 +109,13 @@ public: const VectorType *vectorType(const Type *elementType, int dimension); const MatrixType *matrixType(const Type *elementType, int columns, int rows); + // symbols + Struct *newStruct(Scope *scope = 0); + Block *newBlock(Scope *scope = 0); + Function *newFunction(Scope *scope = 0); + Argument *newArgument(Function *function, const QString &name, const Type *type); + Variable *newVariable(Scope *scope, const QString &name, const Type *type); + MemoryPool *pool(); QList diagnosticMessages() const; @@ -120,6 +128,7 @@ private: TypeTable _matrixTypes; MemoryPool _pool; QList _diagnosticMessages; + QList _symbols; }; } // namespace GLSL diff --git a/src/libs/glsl/glslsemantic.cpp b/src/libs/glsl/glslsemantic.cpp index 3750893bdaf..f86a5ee9775 100644 --- a/src/libs/glsl/glslsemantic.cpp +++ b/src/libs/glsl/glslsemantic.cpp @@ -30,6 +30,8 @@ #include "glslsemantic.h" #include "glslengine.h" #include "glslparser.h" +#include "glslsymbols.h" +#include "glsltypes.h" #include using namespace GLSL; @@ -37,6 +39,7 @@ using namespace GLSL; Semantic::Semantic(Engine *engine) : _engine(engine) , _type(0) + , _scope(0) { } @@ -44,6 +47,13 @@ Semantic::~Semantic() { } +Scope *Semantic::switchScope(Scope *scope) +{ + Scope *previousScope = _scope; + _scope = scope; + return previousScope; +} + void Semantic::expression(ExpressionAST *ast) { accept(ast); @@ -68,9 +78,15 @@ void Semantic::declaration(DeclarationAST *ast) accept(ast); } -void Semantic::translationUnit(TranslationUnitAST *ast) +Scope *Semantic::translationUnit(TranslationUnitAST *ast) { - accept(ast); + Block *globalScope = _engine->newBlock(); + Scope *previousScope = switchScope(globalScope); + for (List *it = ast->declarations; it; it = it->next) { + DeclarationAST *decl = it->value; + declaration(decl); + } + return switchScope(previousScope); } void Semantic::functionIdentifier(FunctionIdentifierAST *ast) @@ -78,17 +94,30 @@ void Semantic::functionIdentifier(FunctionIdentifierAST *ast) accept(ast); } -void Semantic::field(StructTypeAST::Field *ast) +Symbol *Semantic::field(StructTypeAST::Field *ast) { - accept(ast); + // ast->name + const Type *ty = type(ast->type); + QString name; + if (ast->name) + name = *ast->name; + return _engine->newVariable(_scope, name, ty); +} + +void Semantic::parameterDeclaration(ParameterDeclarationAST *ast, Function *fun) +{ + const Type *ty = type(ast->type); + QString name; + if (ast->name) + name = *ast->name; + Argument *arg = _engine->newArgument(fun, name, ty); + fun->addArgument(arg); } bool Semantic::visit(TranslationUnitAST *ast) { - for (List *it = ast->declarations; it; it = it->next) { - DeclarationAST *decl = it->value; - declaration(decl); - } + Q_UNUSED(ast); + Q_ASSERT(!"unreachable"); return false; } @@ -102,9 +131,8 @@ bool Semantic::visit(FunctionIdentifierAST *ast) bool Semantic::visit(StructTypeAST::Field *ast) { - // ast->name - const Type *ty = type(ast->type); - Q_UNUSED(ty); + Q_UNUSED(ast); + Q_ASSERT(!"unreachable"); return false; } @@ -462,11 +490,16 @@ bool Semantic::visit(ArrayTypeAST *ast) bool Semantic::visit(StructTypeAST *ast) { - // ast->name + Struct *s = _engine->newStruct(_scope); + if (ast->name) + s->setName(*ast->name); + Scope *previousScope = switchScope(s); for (List *it = ast->fields; it; it = it->next) { StructTypeAST::Field *f = it->value; - field(f); + if (Symbol *member = field(f)) + s->add(member); } + (void) switchScope(previousScope); return false; } @@ -493,8 +526,8 @@ bool Semantic::visit(PrecisionDeclarationAST *ast) bool Semantic::visit(ParameterDeclarationAST *ast) { - const Type *ty = type(ast->type); - Q_UNUSED(ty); + Q_UNUSED(ast); + Q_ASSERT(!"unreachable"); return false; } @@ -537,13 +570,23 @@ bool Semantic::visit(InitDeclarationAST *ast) bool Semantic::visit(FunctionDeclarationAST *ast) { - const Type *returnType = type(ast->returnType); - Q_UNUSED(returnType); + Function *fun = _engine->newFunction(_scope); + if (ast->name) + fun->setName(*ast->name); + + fun->setReturnType(type(ast->returnType)); + for (List *it = ast->params; it; it = it->next) { ParameterDeclarationAST *decl = it->value; - declaration(decl); + parameterDeclaration(decl, fun); } + + if (Scope *enclosingScope = fun->scope()) + enclosingScope->add(fun); + + Scope *previousScope = switchScope(fun); statement(ast->body); + (void) switchScope(previousScope); return false; } diff --git a/src/libs/glsl/glslsemantic.h b/src/libs/glsl/glslsemantic.h index fdbcdc3978a..ce653816349 100644 --- a/src/libs/glsl/glslsemantic.h +++ b/src/libs/glsl/glslsemantic.h @@ -43,11 +43,14 @@ public: void statement(StatementAST *ast); const Type *type(TypeAST *ast); void declaration(DeclarationAST *ast); - void translationUnit(TranslationUnitAST *ast); + Scope *translationUnit(TranslationUnitAST *ast); void functionIdentifier(FunctionIdentifierAST *ast); - void field(StructTypeAST::Field *ast); + Symbol *field(StructTypeAST::Field *ast); + void parameterDeclaration(ParameterDeclarationAST *ast, Function *fun); protected: + Scope *switchScope(Scope *scope); + virtual bool visit(TranslationUnitAST *ast); virtual bool visit(FunctionIdentifierAST *ast); virtual bool visit(StructTypeAST::Field *ast); @@ -96,6 +99,7 @@ protected: private: Engine *_engine; const Type *_type; + Scope *_scope; }; } // namespace GLSL diff --git a/src/libs/glsl/glslsymbol.cpp b/src/libs/glsl/glslsymbol.cpp index fc429d8f218..754af642155 100644 --- a/src/libs/glsl/glslsymbol.cpp +++ b/src/libs/glsl/glslsymbol.cpp @@ -50,6 +50,16 @@ void Symbol::setScope(Scope *scope) _scope = scope; } +QString Symbol::name() const +{ + return _name; +} + +void Symbol::setName(const QString &name) +{ + _name = name; +} + Scope::Scope(Scope *enclosingScope) : Symbol(enclosingScope) { diff --git a/src/libs/glsl/glslsymbol.h b/src/libs/glsl/glslsymbol.h index e8393f14e48..d4eee75e6f1 100644 --- a/src/libs/glsl/glslsymbol.h +++ b/src/libs/glsl/glslsymbol.h @@ -31,6 +31,7 @@ #define GLSLSYMBOL_H #include "glsl.h" +#include namespace GLSL { @@ -46,6 +47,9 @@ public: Scope *scope() const; void setScope(Scope *scope); + QString name() const; + void setName(const QString &name); + virtual Scope *asScope() { return 0; } virtual Struct *asStruct() { return 0; } virtual Function *asFunction() { return 0; } @@ -57,6 +61,7 @@ public: private: Scope *_scope; + QString _name; }; class GLSL_EXPORT Scope: public Symbol @@ -65,6 +70,8 @@ public: Scope(Scope *sscope = 0); Symbol *lookup(const QString &name) const; + + virtual void add(Symbol *symbol) = 0; virtual Symbol *find(const QString &name) const = 0; virtual Scope *asScope() { return this; } diff --git a/src/libs/glsl/glslsymbols.cpp b/src/libs/glsl/glslsymbols.cpp index c70dd2a7afb..4562ba12560 100644 --- a/src/libs/glsl/glslsymbols.cpp +++ b/src/libs/glsl/glslsymbols.cpp @@ -39,16 +39,6 @@ Argument::Argument(Function *scope) { } -QString Argument::name() const -{ - return _name; -} - -void Argument::setName(const QString &name) -{ - _name = name; -} - const Type *Argument::type() const { return _type; @@ -64,9 +54,9 @@ Block::Block(Scope *enclosingScope) { } -void Block::addMember(const QString &name, Symbol *symbol) +void Block::add(Symbol *symbol) { - _members.insert(name, symbol); + _members.insert(symbol->name(), symbol); } const Type *Block::type() const @@ -86,16 +76,6 @@ Variable::Variable(Scope *scope) { } -QString Variable::name() const -{ - return _name; -} - -void Variable::setName(const QString &name) -{ - _name = name; -} - const Type *Variable::type() const { return _type; diff --git a/src/libs/glsl/glslsymbols.h b/src/libs/glsl/glslsymbols.h index 47d175a711d..21f0a4c6863 100644 --- a/src/libs/glsl/glslsymbols.h +++ b/src/libs/glsl/glslsymbols.h @@ -42,16 +42,12 @@ class GLSL_EXPORT Argument: public Symbol public: Argument(Function *scope); - QString name() const; - void setName(const QString &name); - virtual const Type *type() const; void setType(const Type *type); virtual Argument *asArgument() { return this; } private: - QString _name; const Type *_type; }; @@ -60,16 +56,12 @@ class GLSL_EXPORT Variable: public Symbol public: Variable(Scope *scope); - QString name() const; - void setName(const QString &name); - virtual const Type *type() const; void setType(const Type *type); virtual Variable *asVariable() { return this; } private: - QString _name; const Type *_type; }; @@ -78,7 +70,7 @@ class GLSL_EXPORT Block: public Scope public: Block(Scope *enclosingScope = 0); - void addMember(const QString &name, Symbol *symbol); + void add(Symbol *symbol); virtual Block *asBlock() { return this; } diff --git a/src/libs/glsl/glsltypes.cpp b/src/libs/glsl/glsltypes.cpp index 1045f62b201..3f7fd7b0f42 100644 --- a/src/libs/glsl/glsltypes.cpp +++ b/src/libs/glsl/glsltypes.cpp @@ -195,8 +195,18 @@ bool MatrixType::isLessThan(const Type *other) const return false; } -Struct::Struct(Scope *scope) : Symbol(scope) +void Struct::add(Symbol *member) { + _members.append(member); +} + +Symbol *Struct::find(const QString &name) const +{ + foreach (Symbol *s, _members) { + if (s->name() == name) + return s; + } + return 0; } bool Struct::isEqualTo(const Type *other) const @@ -211,21 +221,6 @@ bool Struct::isLessThan(const Type *other) const return false; } -Function::Function(Scope *scope) : Scope(scope) -{ -} - -QString Function::name() const -{ - return _name; - -} - -void Function::setName(const QString &name) -{ - _name = name; -} - const Type *Function::returnType() const { return _returnType; diff --git a/src/libs/glsl/glsltypes.h b/src/libs/glsl/glsltypes.h index a930a8a3e7f..459b03181a5 100644 --- a/src/libs/glsl/glsltypes.h +++ b/src/libs/glsl/glsltypes.h @@ -136,10 +136,14 @@ private: int _rows; }; -class GLSL_EXPORT Struct: public Type, public Symbol +class GLSL_EXPORT Struct: public Type, public Scope { public: - Struct(Scope *scope = 0); + Struct(Scope *scope = 0) + : Scope(scope) {} + + virtual void add(Symbol *member); + virtual Symbol *find(const QString &name) const; // as Type virtual const Struct *asStructType() const { return this; } @@ -148,15 +152,17 @@ public: // as Symbol virtual Struct *asStruct() { return this; } // as Symbol + virtual const Type *type() const { return this; } + +private: + QVector _members; }; class GLSL_EXPORT Function: public Type, public Scope { public: - Function(Scope *scope = 0); - - QString name() const; - void setName(const QString &name); + Function(Scope *scope = 0) + : Scope(scope) {} const Type *returnType() const; void setReturnType(const Type *returnType); @@ -177,8 +183,14 @@ public: virtual Symbol *find(const QString &name) const; + virtual void add(Symbol *symbol) { + if (! symbol) + return; + else if (Argument *arg = symbol->asArgument()) + addArgument(arg); + } + private: - QString _name; const Type *_returnType; QVector _arguments; };