]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/compiler.cpp
Assign a result type to all expressions
[libs/gl.git] / source / glsl / compiler.cpp
index 803862cb45787974a21a50628d9495009eb2fbca..66a487fbccd4b7a63f2575295ecc03fcbfcddf5a 100644 (file)
@@ -1,5 +1,6 @@
 #include <msp/core/algorithm.h>
 #include <msp/strings/format.h>
+#include <msp/strings/utils.h>
 #include "builtin.h"
 #include "compatibility.h"
 #include "compiler.h"
@@ -85,7 +86,7 @@ void Compiler::compile(Mode mode)
                throw invalid_shader_source(get_diagnostics());
 
        unsigned n = 0;
-       for(list<Stage>::iterator i=module->stages.begin(); (i!=module->stages.end() && n<10000); ++n)
+       for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++n)
        {
                OptimizeResult result = optimize(*i);
                if(result==REDO_PREVIOUS)
@@ -165,7 +166,7 @@ string Compiler::get_diagnostics() const
        string combined;
        for(list<Stage>::const_iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
                for(vector<Diagnostic>::const_iterator j=i->diagnostics.begin(); j!=i->diagnostics.end(); ++j)
-                       combined += format("%s:%d: %s\n", module->source_map.get_name(j->source), j->line, j->message);
+                       append(combined, "\n", format("%s:%d: %s", module->source_map.get_name(j->source), j->line, j->message));
        return combined;
 }
 
@@ -205,13 +206,6 @@ void Compiler::append_stage(Stage &stage)
                target = &*i;
        }
 
-       if(target->content.body.empty())
-       {
-               Stage *builtins = get_builtins(stage.type);
-               if(builtins && builtins!=&stage)
-                       append_stage(*builtins);
-       }
-
        if(stage.required_features.glsl_version>target->required_features.glsl_version)
                target->required_features.glsl_version = stage.required_features.glsl_version;
        for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
@@ -238,17 +232,25 @@ void Compiler::generate(Stage &stage, Mode mode)
        stage.required_features.gl_api = features.gl_api;
        if(module->shared.required_features.glsl_version>stage.required_features.glsl_version)
                stage.required_features.glsl_version = module->shared.required_features.glsl_version;
+
        inject_block(stage.content, module->shared.content);
+       if(const Stage *builtins = get_builtins(stage.type))
+               inject_block(stage.content, builtins->content);
+       if(const Stage *builtins = get_builtins(Stage::SHARED))
+               inject_block(stage.content, builtins->content);
 
        // Initial resolving pass
        BlockHierarchyResolver().apply(stage);
+       TypeResolver().apply(stage);
        FunctionResolver().apply(stage);
        VariableResolver().apply(stage);
 
        /* All variables local to a stage have been resolved.  Resolve non-local
        variables through interfaces. */
        InterfaceGenerator().apply(stage);
+       TypeResolver().apply(stage);
        VariableResolver().apply(stage);
+       ExpressionResolver().apply(stage);
 
        FunctionResolver().apply(stage);
        ConstantSpecializer().apply(stage, (mode==PROGRAM && specialized ? &spec_values : 0));
@@ -258,7 +260,10 @@ void Compiler::generate(Stage &stage, Mode mode)
 
 bool Compiler::validate(Stage &stage)
 {
+       TypeValidator().apply(stage);
        DeclarationValidator().apply(stage);
+       ReferenceValidator().apply(stage);
+       ExpressionValidator().apply(stage);
 
        for(vector<Diagnostic>::const_iterator i=stage.diagnostics.begin(); i!=stage.diagnostics.end(); ++i)
                if(i->severity==Diagnostic::ERR)
@@ -275,14 +280,17 @@ Compiler::OptimizeResult Compiler::optimize(Stage &stage)
        any_inlined |= ExpressionInliner().apply(stage);
        if(any_inlined)
        {
+               TypeResolver().apply(stage);
                VariableResolver().apply(stage);
                FunctionResolver().apply(stage);
+               ExpressionResolver().apply(stage);
        }
 
        /* Removing variables or functions may cause things from the previous stage
        to become unused. */
        bool any_removed = UnusedVariableRemover().apply(stage);
        any_removed |= UnusedFunctionRemover().apply(stage);
+       any_removed |= UnusedTypeRemover().apply(stage);
 
        return any_removed ? REDO_PREVIOUS : any_inlined ? REDO_STAGE : NEXT_STAGE;
 }