From 8c4d64c71df5c4dcab1838d81412d7a7244ada58 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 16 Mar 2021 19:53:04 +0200 Subject: [PATCH] Forbid certain operations in SL::Compiler if compilation isn't done In particular, Formatter can't deal with unresolved declarations. --- source/glsl/compiler.cpp | 13 +++++++++++++ source/glsl/compiler.h | 1 + tools/glslcompiler.cpp | 9 ++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index e9933e2f..8a18fdf4 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -24,12 +24,14 @@ namespace SL { Compiler::Compiler(): features(Features::from_context()), module(0), + compiled(false), specialized(false) { } Compiler::Compiler(const Features &f): features(f), module(0), + compiled(false), specialized(false) { } @@ -96,10 +98,15 @@ void Compiler::compile(Mode mode) } for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) finalize(*i, mode); + + compiled = true; } string Compiler::get_combined_glsl() const { + if(!compiled) + throw invalid_operation("Compiler::get_combined_glsl"); + string glsl; unsigned source_count = module->source_map.get_count(); @@ -126,6 +133,8 @@ vector Compiler::get_stages() const string Compiler::get_stage_glsl(Stage::Type stage_type) const { + if(!compiled) + throw invalid_operation("Compiler::get_stage_glsl"); for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) if(i->type==stage_type) return Formatter().apply(*i); @@ -134,6 +143,8 @@ string Compiler::get_stage_glsl(Stage::Type stage_type) const const map &Compiler::get_vertex_attributes() const { + if(!compiled) + throw invalid_operation("Compiler::get_vertex_attributes"); for(list::const_iterator i=module->stages.begin(); i!=module->stages.end(); ++i) if(i->type==Stage::VERTEX) return i->locations; @@ -142,6 +153,8 @@ const map &Compiler::get_vertex_attributes() const const map &Compiler::get_fragment_outputs() const { + if(!compiled) + throw invalid_operation("Compiler::get_fragment_outputs"); for(list::const_iterator i=module->stages.begin(); i!=module->stages.end(); ++i) if(i->type==Stage::FRAGMENT) return i->locations; diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index a515a326..0ae2ed41 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -41,6 +41,7 @@ private: Features features; Module *module; std::vector imported_names; + bool compiled; bool specialized; std::map spec_values; diff --git a/tools/glslcompiler.cpp b/tools/glslcompiler.cpp index b7b8097e..4a166ba6 100644 --- a/tools/glslcompiler.cpp +++ b/tools/glslcompiler.cpp @@ -36,12 +36,19 @@ GlslCompiler::GlslCompiler(int argc, char **argv): GetOpt getopt; getopt.add_option('c', "combined", combined, GetOpt::NO_ARG).set_help("Output combined GLSL"); getopt.add_option('a', "dump-ast", dump_ast, GetOpt::NO_ARG).set_help("Dump AST for debugging"); - getopt.add_option('p', "parse_only", parse_only, GetOpt::NO_ARG).set_help("Only parse the loaded source, don't compile"); + getopt.add_option('p', "parse_only", parse_only, GetOpt::NO_ARG).set_help("Only parse the loaded source (implies -a)"); getopt.add_option('e', "specialize", spec_values_in, GetOpt::REQUIRED_ARG).set_help("Set specialization constant", "NAME:VALUE"); getopt.add_option('s', "stage", stage_str, GetOpt::REQUIRED_ARG).set_help("Output GLSL for STAGE", "STAGE"); getopt.add_argument("source", source_fn, GetOpt::REQUIRED_ARG).set_help("GLSL file to compile"); getopt(argc, argv); + if(parse_only) + { + if(!stage_str.empty()) + throw usage_error("-s can't be used with -p"); + dump_ast = true; + } + if(stage_str=="vertex") stage = GL::SL::Stage::VERTEX; else if(stage_str=="geometry") -- 2.45.2