#include "builtin.h"
-#include "generate.h"
#include "parser.h"
using namespace std;
initialized = true;
Parser parser;
- Module *module = new Module(parser.parse(builtins_src, "<builtin>"));
- for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
- {
- VariableResolver().apply(*i);
- for(map<string, VariableDeclaration *>::iterator j=i->content.variables.begin(); j!=i->content.variables.end(); ++j)
- j->second->linked_declaration = j->second;
- }
+ Module *module = new Module(parser.parse(builtins_src, "<builtin>", BUILTIN_SOURCE));
builtins_module = module;
}
#include <msp/core/algorithm.h>
#include <msp/gl/extensions/ext_gpu_shader4.h>
#include <msp/strings/format.h>
+#include "builtin.h"
#include "compatibility.h"
#include "compiler.h"
#include "debug.h"
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)
if(!var.precision.empty())
decl += format("%s ", var.precision);
decl += format("%s %s", var.type, var.name);
- if(var.linked_declaration)
+ if(var.source==BUILTIN_SOURCE)
+ decl += " (builtin)";
+ else if(var.linked_declaration)
decl += " (linked)";
append(decl);
head += format(" %s", block.instance_name);
if(block.array)
head += "[]";
- if(block.linked_block)
+ if(block.source==BUILTIN_SOURCE)
+ head += " (builtin)";
+ else if(block.linked_block)
head += " (linked)";
annotated_branch(head, block.members);
}
void DumpTree::visit(FunctionDeclaration &func)
{
string text = format("%%%d %s %s", get_label(func), func.return_type, func.name);
- if(!func.definition)
+ if(func.source==BUILTIN_SOURCE)
+ text += " (builtin)";
+ else if(!func.definition)
text += " (undefined)";
append(text);
begin_sub();
VariableResolver::VariableResolver():
stage(0),
- builtins(0),
members(0),
record_target(false),
assignment_target(0),
stage = &s;
s.types.clear();
s.interface_blocks.clear();
- Stage *builtin_stage = get_builtins(s.type);
- builtins = (builtin_stage ? &builtin_stage->content : 0);
s.content.visit(*this);
}
-Block *VariableResolver::next_block(Block &block)
-{
- return block.parent ? block.parent : &block!=builtins ? builtins : 0;
-}
-
void VariableResolver::enter(Block &block)
{
block.variables.clear();
{
var.declaration = 0;
members = 0;
- for(Block *block=current_block; (!var.declaration && block); block=next_block(*block))
+ for(Block *block=current_block; (!var.declaration && block); block=block->parent)
{
map<string, VariableDeclaration *>::iterator i = block->variables.find(var.name);
if(i!=block->variables.end())
void VariableResolver::visit(InterfaceBlockReference &iface)
{
iface.declaration = 0;
- for(Block *block=current_block; block; block=next_block(*block))
+ for(Block *block=current_block; block; block=block->parent)
{
map<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find(iface.name);
if(i!=stage->interface_blocks.end())
{
private:
Stage *stage;
- Block *builtins;
std::map<std::string, VariableDeclaration *> *members;
RefPtr<InterfaceBlockReference> iface_ref;
std::string block_interface;
void apply(Stage &);
private:
- Block *next_block(Block &);
-
virtual void enter(Block &);
virtual void visit(VariableReference &);
virtual void visit(InterfaceBlockReference &);
SetForScope<unsigned> set(indent, indent+(indent>0 || use_braces));
string spaces(indent*2, ' ');
+ bool first = true;
for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
{
- if(i!=block.body.begin())
+ if((*i)->source==BUILTIN_SOURCE)
+ continue;
+ if(!first)
append('\n');
+ first = false;
set_source((*i)->source, (*i)->line);
append(spaces);
(*i)->visit(*this);
delete module;
}
-Module &Parser::parse(const string &s, const string &n, unsigned i)
+Module &Parser::parse(const string &s, const string &n, int i)
{
source = s;
parse_source(n, i);
return *module;
}
-Module &Parser::parse(IO::Base &io, const string &n, unsigned i)
+Module &Parser::parse(IO::Base &io, const string &n, int i)
{
source = string();
while(!io.eof())
return *module;
}
-void Parser::parse_source(const string &name, unsigned index)
+void Parser::parse_source(const string &name, int index)
{
delete module;
module = new Module;
cur_stage = &module->shared;
base_index = index;
source_index = index;
- source_reference(1, name);
+ if(index>=0)
+ source_reference(1, name);
tokenizer.begin(name, source);
allow_stage_change = true;
while(!tokenizer.peek_token().empty())
void Parser::source_reference(unsigned index, const string &name)
{
- if(index<1)
+ if(index<1 || base_index<0)
throw invalid_shader_source(tokenizer.get_location(), "Invalid source reference");
module->source_map.set_name(base_index+index-1, name);
{
private:
std::string source;
- unsigned base_index;
- unsigned source_index;
+ int base_index;
+ int source_index;
Tokenizer tokenizer;
Preprocessor preprocessor;
bool allow_stage_change;
Parser();
~Parser();
- Module &parse(const std::string &, const std::string &, unsigned = 0);
- Module &parse(IO::Base &, const std::string &, unsigned = 0);
+ Module &parse(const std::string &, const std::string &, int);
+ Module &parse(IO::Base &, const std::string &, int);
private:
- void parse_source(const std::string &, unsigned);
+ void parse_source(const std::string &, int);
void set_required_version(const Version &);
void source_reference(unsigned, const std::string &);
void stage_change(Stage::Type);
Statement::Statement():
- source(0),
+ source(GENERATED_SOURCE),
line(1)
{ }
static const Operator operators[];
};
+enum
+{
+ BUILTIN_SOURCE = -1,
+ GENERATED_SOURCE = 0
+};
+
struct NodeVisitor;
struct Node
struct Statement: Node
{
- unsigned source;
+ int source;
unsigned line;
Statement();