From a159fe302af38ab3880c11317e382d1b04d80ace Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 24 Apr 2021 01:34:14 +0300 Subject: [PATCH] Improve handling of types in GLSL parser Types defined in imported modules are now recognized. --- source/glsl/parser.cpp | 48 +++++++++++++++++++++++++++++++++--------- source/glsl/parser.h | 4 +++- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index cbfa593a..e2a6e1fb 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -55,19 +56,18 @@ void Parser::parse_source(const string &name, int index) if(index>=0) source_reference(1, name); - // TODO Need to somehow get type names from imports if(const Stage *builtin = get_builtins(Stage::SHARED)) { for(map::const_iterator i=builtin->types.begin(); i!=builtin->types.end(); ++i) - declared_types.insert(i->first); + global_types.insert(i->first); } else { - declared_types.insert("void"); - declared_types.insert("bool"); - declared_types.insert("int"); - declared_types.insert("uint"); - declared_types.insert("float"); + global_types.insert("void"); + global_types.insert("bool"); + global_types.insert("int"); + global_types.insert("uint"); + global_types.insert("float"); } tokenizer.begin(source, name); @@ -105,6 +105,17 @@ void Parser::stage_change(Stage::Type stage) if(cur_stage->type!=Stage::SHARED) module->stages.back().previous = cur_stage; cur_stage = &module->stages.back(); + + stage_types.clear(); + for(vector::const_iterator i=imported_modules.begin(); i!=imported_modules.end(); ++i) + { + list::const_iterator j = find_member((*i)->stages, stage, &Stage::type); + if(j!=(*i)->stages.end()) + { + for(map::const_iterator k=j->types.begin(); k!=j->types.end(); ++k) + stage_types.insert(k->first); + } + } } void Parser::line_change(int index, unsigned line) @@ -185,7 +196,7 @@ bool Parser::is_qualifier(const string &token) bool Parser::is_type(const string &token) { - return declared_types.count(token); + return global_types.count(token) || stage_types.count(token); } bool Parser::is_identifier(const string &token) @@ -361,6 +372,15 @@ RefPtr Parser::parse_import() RefPtr import = create_node(); import->module = expect_identifier(); tokenizer.expect(";"); + + if(mod_cache) + { + const Module &imported_mod = mod_cache->get_module(import->module); + imported_modules.push_back(&imported_mod); + for(map::const_iterator i=imported_mod.shared.types.begin(); i!=imported_mod.shared.types.end(); ++i) + global_types.insert(i->first); + } + return import; } @@ -604,7 +624,11 @@ RefPtr Parser::parse_type_declaration() type = parse_basic_type_declaration(); tokenizer.expect(";"); - declared_types.insert(type->name); + cur_stage->types[type->name] = type.get(); + if(cur_stage->type==Stage::SHARED) + global_types.insert(type->name); + else + stage_types.insert(type->name); return type; } @@ -694,7 +718,11 @@ RefPtr Parser::parse_struct_declaration() parse_block(strct->members, true, &Parser::parse_variable_declaration); tokenizer.expect(";"); - declared_types.insert(strct->name); + cur_stage->types[strct->name] = strct.get(); + if(cur_stage->type==Stage::SHARED) + global_types.insert(strct->name); + else + stage_types.insert(strct->name); return strct; } diff --git a/source/glsl/parser.h b/source/glsl/parser.h index e087f27f..a935356e 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -25,8 +25,10 @@ private: Preprocessor preprocessor; bool allow_stage_change; Module *module; + std::vector imported_modules; Stage *cur_stage; - std::set declared_types; + std::set global_types; + std::set stage_types; std::vector errors; public: -- 2.43.0