From 79c49c6b6155857ed0ebe85eb07a996788a6190b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 2 Dec 2016 22:17:50 +0200 Subject: [PATCH] Ensure that program syntax nodes get deep-copied properly 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 | 9 ++++++ source/programsyntax.h | 67 +++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/source/programsyntax.cpp b/source/programsyntax.cpp index e67784fe..4438c16e 100644 --- a/source/programsyntax.cpp +++ b/source/programsyntax.cpp @@ -6,6 +6,15 @@ namespace Msp { namespace GL { namespace ProgramSyntax { +template +NodeContainer::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) { } diff --git a/source/programsyntax.h b/source/programsyntax.h index 9a0cc6ea..14e5d8e7 100644 --- a/source/programsyntax.h +++ b/source/programsyntax.h @@ -25,13 +25,44 @@ public: virtual void visit(NodeVisitor &) = 0; }; +template +class NodePtr: public RefPtr +{ +public: + NodePtr() { } + NodePtr(T *p): RefPtr(p) { } + NodePtr(const NodePtr &p): RefPtr(p ? p->clone() : 0) { } + + template + NodePtr(const RefPtr &p): RefPtr(p) { } + + template + NodePtr(const NodePtr &p): RefPtr(p ? p->clone() : 0) { } +}; + +template +class NodeContainer: public C +{ +public: + NodeContainer() { } + NodeContainer(const NodeContainer &); +}; + +template +class NodeList: public NodeContainer > > +{ }; + +template +class NodeArray: public NodeContainer > > +{ }; + struct StructDeclaration; struct VariableDeclaration; struct FunctionDeclaration; struct Block: Node { - std::list > body; + NodeList body; bool use_braces; std::map types; std::map variables; @@ -57,7 +88,7 @@ struct Literal: Expression struct ParenthesizedExpression: Expression { - RefPtr expression; + NodePtr expression; virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); } virtual void visit(NodeVisitor &); @@ -76,7 +107,7 @@ struct VariableReference: Expression struct MemberAccess: Expression { - RefPtr left; + NodePtr left; std::string member; VariableDeclaration *declaration; @@ -87,7 +118,7 @@ struct MemberAccess: Expression struct UnaryExpression: Expression { std::string oper; - RefPtr expression; + NodePtr expression; bool prefix; UnaryExpression(); @@ -98,9 +129,9 @@ struct UnaryExpression: Expression struct BinaryExpression: Expression { - RefPtr left; + NodePtr left; std::string oper; - RefPtr right; + NodePtr 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 > arguments; + NodeArray arguments; FunctionCall(); @@ -133,7 +164,7 @@ struct FunctionCall: Expression struct ExpressionStatement: Node { - RefPtr expression; + NodePtr 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 array_size; - RefPtr init_expression; + NodePtr array_size; + NodePtr init_expression; VariableDeclaration *linked_declaration; - RefPtr layout; + NodePtr layout; VariableDeclaration(); @@ -219,7 +250,7 @@ struct FunctionDeclaration: Node { std::string return_type; std::string name; - std::vector > parameters; + NodeArray parameters; FunctionDeclaration *definition; Block body; @@ -232,7 +263,7 @@ struct FunctionDeclaration: Node struct Conditional: Node { - RefPtr condition; + NodePtr condition; Block body; Block else_body; @@ -242,9 +273,9 @@ struct Conditional: Node struct Iteration: Node { - RefPtr init_statement; - RefPtr condition; - RefPtr loop_expression; + NodePtr init_statement; + NodePtr condition; + NodePtr loop_expression; Block body; virtual Iteration *clone() const { return new Iteration(*this); } @@ -253,7 +284,7 @@ struct Iteration: Node struct Passthrough: Node { - RefPtr subscript; + NodePtr 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; + NodePtr expression; virtual Return *clone() const { return new Return(*this); } virtual void visit(NodeVisitor &); -- 2.43.0