]> git.tdb.fi Git - libs/gl.git/commitdiff
Ensure that program syntax nodes get deep-copied properly
authorMikko Rasa <tdb@tdb.fi>
Fri, 2 Dec 2016 20:17:50 +0000 (22:17 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 2 Dec 2016 20:17:50 +0000 (22:17 +0200)
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.

source/programsyntax.cpp
source/programsyntax.h

index e67784fe8626a24522b43db5e203cb78354108bc..4438c16ed03cb7bd7a3c5c94e86fe01d98235e25 100644 (file)
@@ -6,6 +6,15 @@ namespace Msp {
 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)
 { }
index 9a0cc6ea3f4bc8c867a2d381494b816b937495eb..14e5d8e786cb679e36c448cf5ca68b1dfe387fd3 100644 (file)
@@ -25,13 +25,44 @@ public:
        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
 {
-       std::list<RefPtr<Node> > body;
+       NodeList<Node> body;
        bool use_braces;
        std::map<std::string, StructDeclaration *> types;
        std::map<std::string, VariableDeclaration *> variables;
@@ -57,7 +88,7 @@ struct Literal: Expression
 
 struct ParenthesizedExpression: Expression
 {
-       RefPtr<Expression> expression;
+       NodePtr<Expression> expression;
 
        virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
        virtual void visit(NodeVisitor &);
@@ -76,7 +107,7 @@ struct VariableReference: Expression
 
 struct MemberAccess: Expression
 {
-       RefPtr<Expression> left;
+       NodePtr<Expression> left;
        std::string member;
        VariableDeclaration *declaration;
 
@@ -87,7 +118,7 @@ struct MemberAccess: Expression
 struct UnaryExpression: Expression
 {
        std::string oper;
-       RefPtr<Expression> expression;
+       NodePtr<Expression> expression;
        bool prefix;
 
        UnaryExpression();
@@ -98,9 +129,9 @@ struct UnaryExpression: Expression
 
 struct BinaryExpression: Expression
 {
-       RefPtr<Expression> left;
+       NodePtr<Expression> left;
        std::string oper;
-       RefPtr<Expression> right;
+       NodePtr<Expression> right;
        std::string after;
 
        virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
@@ -123,7 +154,7 @@ struct FunctionCall: Expression
        std::string name;
        FunctionDeclaration *declaration;
        bool constructor;
-       std::vector<RefPtr<Expression> > arguments;
+       NodeArray<Expression> arguments;
 
        FunctionCall();
 
@@ -133,7 +164,7 @@ struct FunctionCall: Expression
 
 struct ExpressionStatement: Node
 {
-       RefPtr<Expression> expression;
+       NodePtr<Expression> expression;
 
        virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
        virtual void visit(NodeVisitor &);
@@ -190,10 +221,10 @@ struct VariableDeclaration: Node
        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;
-       RefPtr<Layout> layout;
+       NodePtr<Layout> layout;
 
        VariableDeclaration();
 
@@ -219,7 +250,7 @@ struct FunctionDeclaration: Node
 {
        std::string return_type;
        std::string name;
-       std::vector<RefPtr<VariableDeclaration> > parameters;
+       NodeArray<VariableDeclaration> parameters;
        FunctionDeclaration *definition;
        Block body;
 
@@ -232,7 +263,7 @@ struct FunctionDeclaration: Node
 
 struct Conditional: Node
 {
-       RefPtr<Expression> condition;
+       NodePtr<Expression> condition;
        Block body;
        Block else_body;
 
@@ -242,9 +273,9 @@ struct Conditional: Node
 
 struct Iteration: Node
 {
-       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); }
@@ -253,7 +284,7 @@ struct Iteration: Node
 
 struct Passthrough: Node
 {
-       RefPtr<Expression> subscript;
+       NodePtr<Expression> subscript;
 
        virtual Passthrough *clone() const { return new Passthrough(*this); }
        virtual void visit(NodeVisitor &);
@@ -261,7 +292,7 @@ struct Passthrough: Node
 
 struct Return: Node
 {
-       RefPtr<Expression> expression;
+       NodePtr<Expression> expression;
 
        virtual Return *clone() const { return new Return(*this); }
        virtual void visit(NodeVisitor &);