]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/parser.cpp
Recognize the #line directive in the GLSL parser
[libs/gl.git] / source / glsl / parser.cpp
index eee6212930f5dccabdac77b4a32467f91fb89727..7044a8c32f13452ca39df5f4a445cbaee5031ee6 100644 (file)
@@ -17,7 +17,9 @@ Parser::Parser():
 {
        tokenizer.signal_preprocess.connect(sigc::mem_fun(&preprocessor, &Preprocessor::preprocess));
        preprocessor.signal_version.connect(sigc::mem_fun(this, &Parser::set_required_version));
+       preprocessor.signal_source.connect(sigc::mem_fun(this, &Parser::source_reference));
        preprocessor.signal_stage_change.connect(sigc::mem_fun(this, &Parser::stage_change));
+       preprocessor.signal_line.connect(sigc::mem_fun(this, &Parser::line_change));
 }
 
 Parser::~Parser()
@@ -50,8 +52,9 @@ void Parser::parse_source(const string &name, unsigned index)
        delete module;
        module = new Module;
        cur_stage = &module->shared;
+       base_index = index;
        source_index = index;
-       module->source_map.set_name(source_index, name);
+       source_reference(1, name);
        tokenizer.begin(name, source);
        while(RefPtr<Statement> statement = parse_global_declaration())
                cur_stage->content.body.push_back(statement);
@@ -62,6 +65,14 @@ void Parser::set_required_version(const Version &ver)
        cur_stage->required_version = ver;
 }
 
+void Parser::source_reference(unsigned index, const string &name)
+{
+       if(index<1)
+               throw invalid_shader_source(tokenizer.get_location(), "Invalid source reference");
+
+       module->source_map.set_name(base_index+index-1, name);
+}
+
 void Parser::stage_change(Stage::Type stage)
 {
        if(!allow_stage_change)
@@ -76,6 +87,21 @@ void Parser::stage_change(Stage::Type stage)
        cur_stage = &module->stages.back();
 }
 
+void Parser::line_change(int index, unsigned line)
+{
+       if(index>0)
+               source_index = base_index+index-1;
+       else if(index==0)
+               source_index = 0;
+       else
+               index = source_index;
+
+       string name = module->source_map.get_name(index);
+       if(name.empty())
+               name = format("<%d>", index);
+       tokenizer.set_location(Location(name, line));
+}
+
 string Parser::expect_type()
 {
        string token = tokenizer.parse_token();