The changes in
57c1139 prevented copies happening even when they should,
so the shared section got inserted into shader stages by reference. This
caused some funny business with the variable resolver and unused variable
locator.
Containers of nodes must have RefPtrs inside them, since insertions will
create some temporary copies of the element and with NodePtr that would
trigger copying the node as well. So the cloning of nodes is performed
when the container itself is copied.
namespace GL {
namespace ProgramSyntax {
namespace GL {
namespace ProgramSyntax {
+template<typename C>
+NodeContainer<C>::NodeContainer(const NodeContainer &c):
+ C(c)
+{
+ for(typename C::iterator i=this->begin(); i!=this->end(); ++i)
+ *i = (*i)->clone();
+}
+
+
Block::Block():
use_braces(false)
{ }
Block::Block():
use_braces(false)
{ }
virtual void visit(NodeVisitor &) = 0;
};
virtual void visit(NodeVisitor &) = 0;
};
+template<typename T>
+class NodePtr: public RefPtr<T>
+{
+public:
+ NodePtr() { }
+ NodePtr(T *p): RefPtr<T>(p) { }
+ NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
+
+ template<typename U>
+ NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
+
+ template<typename U>
+ NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
+};
+
+template<typename C>
+class NodeContainer: public C
+{
+public:
+ NodeContainer() { }
+ NodeContainer(const NodeContainer &);
+};
+
+template<typename T>
+class NodeList: public NodeContainer<std::list<RefPtr<T> > >
+{ };
+
+template<typename T>
+class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
+{ };
+
struct StructDeclaration;
struct VariableDeclaration;
struct FunctionDeclaration;
struct Block: Node
{
struct StructDeclaration;
struct VariableDeclaration;
struct FunctionDeclaration;
struct Block: Node
{
- std::list<RefPtr<Node> > body;
bool use_braces;
std::map<std::string, StructDeclaration *> types;
std::map<std::string, VariableDeclaration *> variables;
bool use_braces;
std::map<std::string, StructDeclaration *> types;
std::map<std::string, VariableDeclaration *> variables;
struct ParenthesizedExpression: Expression
{
struct ParenthesizedExpression: Expression
{
- RefPtr<Expression> expression;
+ NodePtr<Expression> expression;
virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
virtual void visit(NodeVisitor &);
virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
virtual void visit(NodeVisitor &);
struct MemberAccess: Expression
{
struct MemberAccess: Expression
{
- RefPtr<Expression> left;
+ NodePtr<Expression> left;
std::string member;
VariableDeclaration *declaration;
std::string member;
VariableDeclaration *declaration;
struct UnaryExpression: Expression
{
std::string oper;
struct UnaryExpression: Expression
{
std::string oper;
- RefPtr<Expression> expression;
+ NodePtr<Expression> expression;
bool prefix;
UnaryExpression();
bool prefix;
UnaryExpression();
struct BinaryExpression: Expression
{
struct BinaryExpression: Expression
{
- RefPtr<Expression> left;
+ NodePtr<Expression> left;
- RefPtr<Expression> right;
+ NodePtr<Expression> right;
std::string after;
virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
std::string after;
virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
std::string name;
FunctionDeclaration *declaration;
bool constructor;
std::string name;
FunctionDeclaration *declaration;
bool constructor;
- std::vector<RefPtr<Expression> > arguments;
+ NodeArray<Expression> arguments;
struct ExpressionStatement: Node
{
struct ExpressionStatement: Node
{
- RefPtr<Expression> expression;
+ NodePtr<Expression> expression;
virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
virtual void visit(NodeVisitor &);
virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
virtual void visit(NodeVisitor &);
StructDeclaration *type_declaration;
std::string name;
bool array;
StructDeclaration *type_declaration;
std::string name;
bool array;
- RefPtr<Expression> array_size;
- RefPtr<Expression> init_expression;
+ NodePtr<Expression> array_size;
+ NodePtr<Expression> init_expression;
VariableDeclaration *linked_declaration;
VariableDeclaration *linked_declaration;
+ NodePtr<Layout> layout;
{
std::string return_type;
std::string name;
{
std::string return_type;
std::string name;
- std::vector<RefPtr<VariableDeclaration> > parameters;
+ NodeArray<VariableDeclaration> parameters;
FunctionDeclaration *definition;
Block body;
FunctionDeclaration *definition;
Block body;
struct Conditional: Node
{
struct Conditional: Node
{
- RefPtr<Expression> condition;
+ NodePtr<Expression> condition;
Block body;
Block else_body;
Block body;
Block else_body;
- RefPtr<Node> init_statement;
- RefPtr<Expression> condition;
- RefPtr<Expression> loop_expression;
+ NodePtr<Node> init_statement;
+ NodePtr<Expression> condition;
+ NodePtr<Expression> loop_expression;
Block body;
virtual Iteration *clone() const { return new Iteration(*this); }
Block body;
virtual Iteration *clone() const { return new Iteration(*this); }
struct Passthrough: Node
{
struct Passthrough: Node
{
- RefPtr<Expression> subscript;
+ NodePtr<Expression> subscript;
virtual Passthrough *clone() const { return new Passthrough(*this); }
virtual void visit(NodeVisitor &);
virtual Passthrough *clone() const { return new Passthrough(*this); }
virtual void visit(NodeVisitor &);
- RefPtr<Expression> expression;
+ NodePtr<Expression> expression;
virtual Return *clone() const { return new Return(*this); }
virtual void visit(NodeVisitor &);
virtual Return *clone() const { return new Return(*this); }
virtual void visit(NodeVisitor &);