diff --git a/src/libs/glsl/glsl.h b/src/libs/glsl/glsl.h index cdfbcdc3c5d81eb6af68dc26e3ba76a2e4a8639a..e63ab44e89586958d3abac16455c9301c391f5e5 100644 --- a/src/libs/glsl/glsl.h +++ b/src/libs/glsl/glsl.h @@ -76,6 +76,7 @@ class OverloadSet; class Namespace; class AST; +class TranslationUnitAST; template <typename T> class List; } diff --git a/src/libs/glsl/glslsemantic.cpp b/src/libs/glsl/glslsemantic.cpp index ea4e81c60b4a84460c08ecd2f5d423d8aa4d6a8b..1be3c486a738df3c89e9d4c7d5f02431950a59e0 100644 --- a/src/libs/glsl/glslsemantic.cpp +++ b/src/libs/glsl/glslsemantic.cpp @@ -36,8 +36,8 @@ using namespace GLSL; -Semantic::Semantic(Engine *engine) - : _engine(engine) +Semantic::Semantic() + : _engine(0) , _scope(0) , _type(0) { @@ -47,6 +47,13 @@ Semantic::~Semantic() { } +Engine *Semantic::switchEngine(Engine *engine) +{ + Engine *previousEngine = _engine; + _engine = engine; + return previousEngine; +} + Scope *Semantic::switchScope(Scope *scope) { Scope *previousScope = _scope; @@ -82,9 +89,9 @@ void Semantic::declaration(DeclarationAST *ast) accept(ast); } -Scope *Semantic::translationUnit(TranslationUnitAST *ast) +void Semantic::translationUnit(TranslationUnitAST *ast, Scope *globalScope, Engine *engine) { - Namespace *globalScope = _engine->newNamespace(); + Engine *previousEngine = switchEngine(engine); Scope *previousScope = switchScope(globalScope); if (ast) { for (List<DeclarationAST *> *it = ast->declarations; it; it = it->next) { @@ -92,7 +99,8 @@ Scope *Semantic::translationUnit(TranslationUnitAST *ast) declaration(decl); } } - return switchScope(previousScope); + (void) switchScope(previousScope); + (void) switchEngine(previousEngine); } Semantic::ExprResult Semantic::functionIdentifier(FunctionIdentifierAST *ast) @@ -106,7 +114,7 @@ Semantic::ExprResult Semantic::functionIdentifier(FunctionIdentifierAST *ast) else _engine->error(ast->lineno, QString("`%1' cannot be used as a function").arg(*ast->name)); } else { - // ### _engine->error(ast->lineno, QString("`%1' was not declared in this scope").arg(*ast->name)); + _engine->error(ast->lineno, QString("`%1' was not declared in this scope").arg(*ast->name)); } } else if (ast->type) { const Type *ty = type(ast->type); diff --git a/src/libs/glsl/glslsemantic.h b/src/libs/glsl/glslsemantic.h index 78574d9ea7f89b918fdc9f396f93d4ac573981da..19e298dd086077c57ff3041a668ed51786b3ac9e 100644 --- a/src/libs/glsl/glslsemantic.h +++ b/src/libs/glsl/glslsemantic.h @@ -36,7 +36,7 @@ namespace GLSL { class GLSL_EXPORT Semantic: protected Visitor { public: - Semantic(Engine *engine); + Semantic(); virtual ~Semantic(); struct ExprResult { @@ -50,18 +50,20 @@ public: bool isConstant; }; + void translationUnit(TranslationUnitAST *ast, Scope *globalScope, Engine *engine); + +protected: + Engine *switchEngine(Engine *engine); + Scope *switchScope(Scope *scope); + ExprResult expression(ExpressionAST *ast); void statement(StatementAST *ast); const Type *type(TypeAST *ast); void declaration(DeclarationAST *ast); - Scope *translationUnit(TranslationUnitAST *ast); ExprResult functionIdentifier(FunctionIdentifierAST *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); diff --git a/src/libs/glsl/tests/main.cpp b/src/libs/glsl/tests/main.cpp index ff0df7ea45349025b779509a9a7e8b46635216ec..8c4e74dab383e237aae9858df0ec3346f42d2a80 100644 --- a/src/libs/glsl/tests/main.cpp +++ b/src/libs/glsl/tests/main.cpp @@ -4,6 +4,8 @@ #include <glsllexer.h> #include <glslastdump.h> #include <glslsemantic.h> +#include <glslsymbols.h> +#include <glsltypes.h> #include <QtCore/QTextStream> @@ -82,8 +84,9 @@ int main(int argc, char *argv[]) ASTDump dump(qout); dump(ast); - Semantic sem(&engine); - sem.translationUnit(ast); + Semantic sem; + Scope *globalScope = engine.newNamespace(); + sem.translationUnit(ast, globalScope, &engine); delete source; delete ast; diff --git a/src/plugins/glsleditor/glsleditor.cpp b/src/plugins/glsleditor/glsleditor.cpp index cc0e8b4cba97943dfc773d43b32d5a485a786e4d..7d8fcc51ae3b4f5c6a3b498c4bac9123a82be0c8 100644 --- a/src/plugins/glsleditor/glsleditor.cpp +++ b/src/plugins/glsleditor/glsleditor.cpp @@ -39,6 +39,7 @@ #include <glsl/glslparser.h> #include <glsl/glslengine.h> #include <glsl/glslsemantic.h> +#include <glsl/glslsymbols.h> #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actioncontainer.h> @@ -270,9 +271,14 @@ void GLSLTextEditor::updateDocumentNow() Parser parser(&engine, preprocessedCode.constData(), preprocessedCode.size(), variant); TranslationUnitAST *ast = parser.parse(); - Semantic sem(&engine); - Scope *globalScope = sem.translationUnit(ast); - Q_UNUSED(globalScope); + GLSLEditorPlugin *plugin = GLSLEditorPlugin::instance(); + + Semantic sem; + Scope *globalScope = engine.newNamespace(); + sem.translationUnit(plugin->shaderInit()->ast, globalScope, plugin->shaderInit()->engine); + sem.translationUnit(plugin->vertexShaderInit()->ast, globalScope, plugin->vertexShaderInit()->engine); + sem.translationUnit(plugin->fragmentShaderInit()->ast, globalScope, plugin->fragmentShaderInit()->engine); + sem.translationUnit(ast, globalScope, &engine); QTextCharFormat errorFormat; errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); diff --git a/src/plugins/glsleditor/glsleditorplugin.cpp b/src/plugins/glsleditor/glsleditorplugin.cpp index 9caf26ddf00624ff8d06bc59ae3f20d83c142084..20c0886e12b7eba5e18cccbc359ff04200ea6336 100644 --- a/src/plugins/glsleditor/glsleditorplugin.cpp +++ b/src/plugins/glsleditor/glsleditorplugin.cpp @@ -55,6 +55,10 @@ #include <texteditor/completionsupport.h> #include <utils/qtcassert.h> +#include <glsl/glslengine.h> +#include <glsl/glslparser.h> +#include <glsl/glsllexer.h> + #include <QtCore/QtPlugin> #include <QtCore/QDebug> #include <QtCore/QSettings> @@ -70,6 +74,11 @@ using namespace GLSLEditor::Constants; GLSLEditorPlugin *GLSLEditorPlugin::m_instance = 0; +GLSLEditorPlugin::InitFile::~InitFile() +{ + delete engine; +} + GLSLEditorPlugin::GLSLEditorPlugin() : m_editor(0), m_actionHandler(0) @@ -102,9 +111,10 @@ bool GLSLEditorPlugin::initialize(const QStringList & /*arguments*/, QString *er if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/glsleditor/GLSLEditor.mimetypes.xml"), error_message)) return false; - m_glsl_120_frag = glslFile(QLatin1String("glsl_120.frag")); - m_glsl_120_vert = glslFile(QLatin1String("glsl_120.vert")); - m_glsl_120_common = glslFile(QLatin1String("glsl_120_common.glsl")); + parseGlslFile(QLatin1String("glsl_120.frag"), &m_glsl_120_frag); + parseGlslFile(QLatin1String("glsl_120.vert"), &m_glsl_120_vert); + parseGlslFile(QLatin1String("glsl_120_common.glsl"), &m_glsl_120_common); + // m_modelManager = new ModelManager(this); // addAutoReleasedObject(m_modelManager); @@ -239,19 +249,31 @@ QByteArray GLSLEditorPlugin::glslFile(const QString &fileName) return QByteArray(); } -QByteArray GLSLEditorPlugin::fragmentShaderInit() const +void GLSLEditorPlugin::parseGlslFile(const QString &fileName, InitFile *initFile) +{ + const int variant = GLSL::Lexer::Variant_GLSL_Qt | // ### hardcoded + GLSL::Lexer::Variant_VertexShader | + GLSL::Lexer::Variant_FragmentShader; + + const QByteArray code = glslFile(fileName); + initFile->engine = new GLSL::Engine(); + GLSL::Parser parser(initFile->engine, code.constData(), code.size(), variant); + initFile->ast = parser.parse(); +} + +const GLSLEditorPlugin::InitFile *GLSLEditorPlugin::fragmentShaderInit() const { - return m_glsl_120_frag; + return &m_glsl_120_frag; } -QByteArray GLSLEditorPlugin::vertexShaderInit() const +const GLSLEditorPlugin::InitFile *GLSLEditorPlugin::vertexShaderInit() const { - return m_glsl_120_vert; + return &m_glsl_120_vert; } -QByteArray GLSLEditorPlugin::shaderInit() const +const GLSLEditorPlugin::InitFile *GLSLEditorPlugin::shaderInit() const { - return m_glsl_120_common; + return &m_glsl_120_common; } Q_EXPORT_PLUGIN(GLSLEditorPlugin) diff --git a/src/plugins/glsleditor/glsleditorplugin.h b/src/plugins/glsleditor/glsleditorplugin.h index 32806fd0beedc53b1302f48ca97e8ad1aa4f9b3a..fc222ed14323d3e47c29fdeab94c819131a8ec23 100644 --- a/src/plugins/glsleditor/glsleditorplugin.h +++ b/src/plugins/glsleditor/glsleditorplugin.h @@ -33,6 +33,7 @@ #include <extensionsystem/iplugin.h> #include <coreplugin/icontext.h> #include <QtCore/QPointer> +#include <glsl/glsl.h> QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QTimer) @@ -83,12 +84,23 @@ public: void initializeEditor(GLSLEditor::GLSLTextEditor *editor); - QByteArray fragmentShaderInit() const; - QByteArray vertexShaderInit() const; - QByteArray shaderInit() const; + struct InitFile { + GLSL::Engine *engine; + GLSL::TranslationUnitAST *ast; + + InitFile(GLSL::Engine *engine = 0, GLSL::TranslationUnitAST *ast = 0) + : engine(engine), ast(ast) {} + + ~InitFile(); + }; + + const InitFile *fragmentShaderInit() const; + const InitFile *vertexShaderInit() const; + const InitFile *shaderInit() const; private: QByteArray glslFile(const QString &fileName); + void parseGlslFile(const QString &fileName, InitFile *initFile); Core::Command *addToolAction(QAction *a, Core::ActionManager *am, Core::Context &context, const QString &name, Core::ActionContainer *c1, const QString &keySequence); @@ -99,9 +111,10 @@ private: TextEditor::TextEditorActionHandler *m_actionHandler; QPointer<TextEditor::ITextEditable> m_currentTextEditable; - QByteArray m_glsl_120_frag; - QByteArray m_glsl_120_vert; - QByteArray m_glsl_120_common; + + InitFile m_glsl_120_frag; + InitFile m_glsl_120_vert; + InitFile m_glsl_120_common; }; } // namespace Internal