]> git.tdb.fi Git - libs/gl.git/commitdiff
Upgrade NodePtr to RefPtr
authorMikko Rasa <tdb@tdb.fi>
Thu, 1 Dec 2016 11:29:29 +0000 (13:29 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 1 Dec 2016 11:29:29 +0000 (13:29 +0200)
Allows Nodes to be moved from one Block to another without copying them.
When targeting GLSL 1.30 LegacyConverter has a sequence where it flattens
an interface block and later checks the type of those variables through
their declaration pointer.  This caused memory errors because the
original nodes were destroyed in the flatten operation.

source/programcompiler.cpp
source/programcompiler.h
source/programparser.cpp
source/programparser.h
source/programsyntax.cpp
source/programsyntax.h

index a68c8b96d7c9c40dc94a3bde6211f867652cd2db..86ea8da93d7e6866590a563c150555393903cafe 100644 (file)
@@ -184,8 +184,8 @@ bool ProgramCompiler::optimize(Stage &stage)
 
 void ProgramCompiler::inject_block(Block &target, const Block &source)
 {
-       list<NodePtr<Node> >::iterator insert_point = target.body.begin();
-       for(list<NodePtr<Node> >::const_iterator i=source.body.begin(); i!=source.body.end(); ++i)
+       list<RefPtr<Node> >::iterator insert_point = target.body.begin();
+       for(list<RefPtr<Node> >::const_iterator i=source.body.begin(); i!=source.body.end(); ++i)
                target.body.insert(insert_point, (*i)->clone());
 }
 
@@ -281,7 +281,7 @@ void ProgramCompiler::Formatter::visit(Assignment &assign)
 void ProgramCompiler::Formatter::visit(FunctionCall &call)
 {
        formatted += format("%s(", call.name);
-       for(vector<NodePtr<Expression> >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
+       for(vector<RefPtr<Expression> >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
        {
                if(i!=call.arguments.begin())
                        formatted += ", ";
@@ -308,7 +308,7 @@ void ProgramCompiler::Formatter::visit(Block &block)
 
        SetForScope<unsigned> set(indent, indent+(indent>0 || use_braces));
        string spaces(indent*2, ' ');
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
        {
                if(i!=block.body.begin())
                        formatted += '\n';
@@ -394,7 +394,7 @@ void ProgramCompiler::Formatter::visit(InterfaceBlock &iface)
 void ProgramCompiler::Formatter::visit(FunctionDeclaration &func)
 {
        formatted += format("%s %s(", func.return_type, func.name);
-       for(vector<NodePtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+       for(vector<RefPtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
        {
                if(i!=func.parameters.begin())
                        formatted += ", ";
@@ -462,7 +462,7 @@ void ProgramCompiler::DeclarationCombiner::visit(Block &block)
                return;
 
        SetForScope<bool> set(toplevel, false);
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
        {
                remove_node = false;
                (*i)->visit(*this);
@@ -676,15 +676,13 @@ ProgramCompiler::BlockModifier::BlockModifier():
 
 void ProgramCompiler::BlockModifier::flatten_block(Block &block)
 {
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
-               insert_nodes.push_back((*i)->clone());
+       insert_nodes.insert(insert_nodes.end(), block.body.begin(), block.body.end());
        remove_node = true;
 }
 
-void ProgramCompiler::BlockModifier::apply_and_increment(Block &block, list<NodePtr<Node> >::iterator &i)
+void ProgramCompiler::BlockModifier::apply_and_increment(Block &block, list<RefPtr<Node> >::iterator &i)
 {
-       for(list<Node *>::iterator j=insert_nodes.begin(); j!=insert_nodes.end(); ++j)
-               block.body.insert(i, *j);
+       block.body.insert(i, insert_nodes.begin(), insert_nodes.end());
        insert_nodes.clear();
 
        if(remove_node)
@@ -696,7 +694,7 @@ void ProgramCompiler::BlockModifier::apply_and_increment(Block &block, list<Node
 
 void ProgramCompiler::BlockModifier::visit(Block &block)
 {
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
        {
                (*i)->visit(*this);
                apply_and_increment(block, i);
@@ -730,15 +728,15 @@ void ProgramCompiler::InterfaceGenerator::apply(Stage &s)
 void ProgramCompiler::InterfaceGenerator::visit(Block &block)
 {
        SetForScope<unsigned> set(scope_level, scope_level+1);
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
        {
                (*i)->visit(*this);
 
                if(scope_level==1)
                {
-                       for(map<string, VariableDeclaration *>::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j)
+                       for(map<string, RefPtr<VariableDeclaration> >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j)
                        {
-                               list<NodePtr<Node> >::iterator k = block.body.insert(i, j->second);
+                               list<RefPtr<Node> >::iterator k = block.body.insert(i, j->second);
                                (*k)->visit(*this);
                        }
                        iface_declarations.clear();
@@ -847,9 +845,9 @@ void ProgramCompiler::InterfaceGenerator::visit(Passthrough &pass)
 
        for(map<string, VariableDeclaration *>::const_iterator i=stage->in_variables.begin(); i!=stage->in_variables.end(); ++i)
                pass_vars.push_back(i->second);
-       for(map<string, VariableDeclaration *>::const_iterator i=iface_declarations.begin(); i!=iface_declarations.end(); ++i)
+       for(map<string, RefPtr<VariableDeclaration> >::const_iterator i=iface_declarations.begin(); i!=iface_declarations.end(); ++i)
                if(i->second->interface=="in")
-                       pass_vars.push_back(i->second);
+                       pass_vars.push_back(i->second.get());
 
        if(stage->previous)
        {
@@ -1032,7 +1030,7 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Assignment &assign)
 void ProgramCompiler::ConstantConditionEliminator::visit(VariableDeclaration &var)
 {
        if(var.constant || scope_level>1)
-               variable_values[&var] = &*var.init_expression;
+               variable_values[&var] = var.init_expression.get();
 }
 
 void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond)
@@ -1180,7 +1178,7 @@ void ProgramCompiler::UnusedVariableLocator::visit(FunctionDeclaration &func)
 {
        assignments.push_back(BlockAssignmentMap());
 
-       for(vector<NodePtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+       for(vector<RefPtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
                (*i)->visit(*this);
        func.body.visit(*this);
 
@@ -1286,10 +1284,10 @@ ProgramCompiler::NodeRemover::NodeRemover(const set<Node *> &r):
 
 void ProgramCompiler::NodeRemover::visit(Block &block)
 {
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
        {
                (*i)->visit(*this);
-               if(to_remove.count(&**i))
+               if(to_remove.count(i->get()))
                        block.body.erase(i++);
                else
                        ++i;
@@ -1306,7 +1304,7 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var)
                if(var.linked_declaration)
                        var.linked_declaration->linked_declaration = 0;
        }
-       else if(var.init_expression && to_remove.count(&*var.init_expression))
+       else if(var.init_expression && to_remove.count(var.init_expression.get()))
                var.init_expression = 0;
 }
 
@@ -1347,7 +1345,7 @@ void ProgramCompiler::LegacyConverter::visit(FunctionCall &call)
 {
        if(call.name=="texture" && !call.declaration && !check_version(Version(1, 30)))
        {
-               vector<NodePtr<Expression> >::iterator i = call.arguments.begin();
+               vector<RefPtr<Expression> >::iterator i = call.arguments.begin();
                if(i!=call.arguments.end())
                {
                        (*i)->visit(*this);
index 8d7d1ad13b9c62b2b4dc0941c08c1a3cdb9fd6aa..398bb214d10568800d69e757dec8eadad82efda5 100644 (file)
@@ -121,12 +121,12 @@ private:
        struct BlockModifier: Visitor
        {
                bool remove_node;
-               std::list<ProgramSyntax::Node *> insert_nodes;
+               std::list<RefPtr<ProgramSyntax::Node> > insert_nodes;
 
                BlockModifier();
 
                void flatten_block(ProgramSyntax::Block &);
-               void apply_and_increment(ProgramSyntax::Block &, std::list<ProgramSyntax::NodePtr<ProgramSyntax::Node> >::iterator &);
+               void apply_and_increment(ProgramSyntax::Block &, std::list<RefPtr<ProgramSyntax::Node> >::iterator &);
                virtual void visit(ProgramSyntax::Block &);
        };
 
@@ -135,7 +135,7 @@ private:
                std::string in_prefix;
                std::string out_prefix;
                unsigned scope_level;
-               std::map<std::string, ProgramSyntax::VariableDeclaration *> iface_declarations;
+               std::map<std::string, RefPtr<ProgramSyntax::VariableDeclaration> > iface_declarations;
 
                InterfaceGenerator();
 
index 596ed0456b8e789ec2bd5ac636790a7d97bc8c4c..da3ee0b99f5c383b5f9475676dd2d7b3eeb8c3ff 100644 (file)
@@ -95,7 +95,7 @@ void ProgramParser::parse_source()
        iter = source.begin();
        while(1)
        {
-               while(Node *statement = parse_global_declaration())
+               while(RefPtr<Node> statement = parse_global_declaration())
                        cur_stage->content.body.push_back(statement);
 
                parse_token();
@@ -329,7 +329,7 @@ bool ProgramParser::is_identifier(const string &token)
        return re.match(token);
 }
 
-Node *ProgramParser::parse_global_declaration()
+RefPtr<Node> ProgramParser::parse_global_declaration()
 {
        string token = peek_token();
        if(token=="import")
@@ -344,12 +344,12 @@ Node *ProgramParser::parse_global_declaration()
                        iface_lo->layout.qualifiers = layout->qualifiers;
                        iface_lo->interface = parse_token();
                        expect(";");
-                       return iface_lo.release();
+                       return iface_lo;
                }
                else
                {
-                       VariableDeclaration *var = parse_variable_declaration();
-                       var->layout = layout.release();
+                       RefPtr<VariableDeclaration> var = parse_variable_declaration();
+                       var->layout = layout;
                        return var;
                }
        }
@@ -377,7 +377,7 @@ Node *ProgramParser::parse_global_declaration()
                throw runtime_error(format("Syntax error at '%s': expected a global declaration", token));
 }
 
-Node *ProgramParser::parse_statement()
+RefPtr<Node> ProgramParser::parse_statement()
 {
        string token = peek_token();
        if(token=="if")
@@ -396,13 +396,13 @@ Node *ProgramParser::parse_statement()
                expr->expression = parse_expression();
                expect(";");
 
-               return expr.release();
+               return expr;
        }
        else
                throw runtime_error(format("Syntax error at '%s': expected a statement", token));
 }
 
-Import *ProgramParser::parse_import()
+RefPtr<Import> ProgramParser::parse_import()
 {
        if(cur_stage->type!=SHARED)
                throw runtime_error("Imports are only allowed in the shared section");
@@ -411,10 +411,10 @@ Import *ProgramParser::parse_import()
        RefPtr<Import> import = new Import;
        import->module = parse_token();
        expect(";");
-       return import.release();
+       return import;
 }
 
-Layout *ProgramParser::parse_layout()
+RefPtr<Layout> ProgramParser::parse_layout()
 {
        expect("layout");
        expect("(");
@@ -439,7 +439,7 @@ Layout *ProgramParser::parse_layout()
        }
        expect(")");
 
-       return layout.release();
+       return layout;
 }
 
 void ProgramParser::parse_block(Block &block, bool require_braces)
@@ -462,7 +462,7 @@ void ProgramParser::parse_block(Block &block, bool require_braces)
                expect("}");
 }
 
-Expression *ProgramParser::parse_expression(unsigned precedence)
+RefPtr<Expression> ProgramParser::parse_expression(unsigned precedence)
 {
        RefPtr<Expression> left;
        VariableReference *left_var = 0;
@@ -478,7 +478,7 @@ Expression *ProgramParser::parse_expression(unsigned precedence)
                if(token==";" || token==")" || token=="]" || token=="," || (oper && precedence && oper->precedence>=precedence))
                {
                        if(left)
-                               return left.release();
+                               return left;
                        else
                                throw runtime_error(format("Parse error at '%s': expected an expression", token));
                }
@@ -488,12 +488,12 @@ Expression *ProgramParser::parse_expression(unsigned precedence)
                        {
                                if(!left_var)
                                        throw runtime_error(format("Parse error at '%s': function name must be an identifier", token));
-                               left = parse_function_call(left_var);
+                               left = parse_function_call(*left_var);
                        }
                        else if(token==".")
                        {
                                RefPtr<MemberAccess> memacc = new MemberAccess;
-                               memacc->left = left.release();
+                               memacc->left = left;
                                parse_token();
                                memacc->member = expect_identifier();
                                left = memacc;
@@ -503,11 +503,11 @@ Expression *ProgramParser::parse_expression(unsigned precedence)
                                RefPtr<UnaryExpression> unary = new UnaryExpression;
                                unary->oper = parse_token();
                                unary->prefix = false;
-                               unary->expression = left.release();
+                               unary->expression = left;
                                left = unary;
                        }
                        else if(oper && oper->type==BINARY)
-                               left = parse_binary(left.release(), oper);
+                               left = parse_binary(left, oper);
                        else
                                throw runtime_error(format("Parse error at '%s': expected an operator", token));
                        left_var = 0;
@@ -549,7 +549,7 @@ Expression *ProgramParser::parse_expression(unsigned precedence)
        }
 }
 
-BinaryExpression *ProgramParser::parse_binary(Expression *left, const Operator *oper)
+RefPtr<BinaryExpression> ProgramParser::parse_binary(const RefPtr<Expression> &left, const Operator *oper)
 {
        RefPtr<BinaryExpression> binary = (oper->precedence==16 ? new Assignment : new BinaryExpression);
        binary->left = left;
@@ -562,13 +562,13 @@ BinaryExpression *ProgramParser::parse_binary(Expression *left, const Operator *
        }
        else
                binary->right = parse_expression(oper->precedence+(oper->assoc==RIGHT_TO_LEFT));
-       return binary.release();
+       return binary;
 }
 
-FunctionCall *ProgramParser::parse_function_call(VariableReference *var)
+RefPtr<FunctionCall> ProgramParser::parse_function_call(const VariableReference &var)
 {
        RefPtr<FunctionCall> call = new FunctionCall;
-       call->name = var->name;
+       call->name = var.name;
        call->constructor = is_type(call->name);
        expect("(");
        while(peek_token()!=")")
@@ -578,10 +578,10 @@ FunctionCall *ProgramParser::parse_function_call(VariableReference *var)
                call->arguments.push_back(parse_expression());
        }
        expect(")");
-       return call.release();
+       return call;
 }
 
-StructDeclaration *ProgramParser::parse_struct_declaration()
+RefPtr<StructDeclaration> ProgramParser::parse_struct_declaration()
 {
        expect("struct");
        RefPtr<StructDeclaration> strct = new StructDeclaration;
@@ -591,10 +591,10 @@ StructDeclaration *ProgramParser::parse_struct_declaration()
        expect(";");
 
        declared_types.insert(strct->name);
-       return strct.release();
+       return strct;
 }
 
-VariableDeclaration *ProgramParser::parse_variable_declaration()
+RefPtr<VariableDeclaration> ProgramParser::parse_variable_declaration()
 {
        RefPtr<VariableDeclaration> var = new VariableDeclaration;
 
@@ -632,10 +632,10 @@ VariableDeclaration *ProgramParser::parse_variable_declaration()
                var->init_expression = parse_expression();
 
        expect(";");
-       return var.release();
+       return var;
 }
 
-FunctionDeclaration *ProgramParser::parse_function_declaration()
+RefPtr<FunctionDeclaration> ProgramParser::parse_function_declaration()
 {
        RefPtr<FunctionDeclaration> func = new FunctionDeclaration;
 
@@ -650,7 +650,7 @@ FunctionDeclaration *ProgramParser::parse_function_declaration()
                RefPtr<VariableDeclaration> var = new VariableDeclaration;
                var->type = expect_type();
                var->name = expect_identifier();
-               func->parameters.push_back(var.release());
+               func->parameters.push_back(var);
        }
        expect(")");
 
@@ -665,10 +665,10 @@ FunctionDeclaration *ProgramParser::parse_function_declaration()
        else
                throw runtime_error(format("Parse error at '%s': expected '{' or ';'", token));
 
-       return func.release();
+       return func;
 }
 
-InterfaceBlock *ProgramParser::parse_interface_block()
+RefPtr<InterfaceBlock> ProgramParser::parse_interface_block()
 {
        RefPtr<InterfaceBlock> iface = new InterfaceBlock;
 
@@ -689,10 +689,10 @@ InterfaceBlock *ProgramParser::parse_interface_block()
                expect(";");
        }
 
-       return iface.release();
+       return iface;
 }
 
-Conditional *ProgramParser::parse_conditional()
+RefPtr<Conditional> ProgramParser::parse_conditional()
 {
        expect("if");
        expect("(");
@@ -709,10 +709,10 @@ Conditional *ProgramParser::parse_conditional()
                parse_block(cond->else_body, false);
        }
 
-       return cond.release();
+       return cond;
 }
 
-Iteration *ProgramParser::parse_iteration()
+RefPtr<Iteration> ProgramParser::parse_iteration()
 {
        expect("for");
        expect("(");
@@ -725,7 +725,7 @@ Iteration *ProgramParser::parse_iteration()
                RefPtr<ExpressionStatement> expr = new ExpressionStatement;
                expr->expression = parse_expression();
                expect(";");
-               loop->init_statement = expr.release();
+               loop->init_statement = expr;
        }
        loop->condition = parse_expression();
        expect(";");
@@ -734,10 +734,10 @@ Iteration *ProgramParser::parse_iteration()
 
        parse_block(loop->body, false);
 
-       return loop.release();
+       return loop;
 }
 
-Passthrough *ProgramParser::parse_passthrough()
+RefPtr<Passthrough> ProgramParser::parse_passthrough()
 {
        expect("passthrough");
        RefPtr<Passthrough> pass = new Passthrough;
@@ -748,17 +748,17 @@ Passthrough *ProgramParser::parse_passthrough()
                expect("]");
        }
        expect(";");
-       return pass.release();
+       return pass;
 }
 
-Return *ProgramParser::parse_return()
+RefPtr<Return> ProgramParser::parse_return()
 {
        expect("return");
        RefPtr<Return> ret = new Return;
        if(peek_token()!=";")
                ret->expression = parse_expression();
        expect(";");
-       return ret.release();
+       return ret;
 }
 
 } // namespace GL
index 4e8e38f0fcd48fb0c5033ffae76bad2add532783..0a46c09ece6202e18c71625afd916b8680f4806a 100644 (file)
@@ -74,22 +74,22 @@ private:
        bool is_type(const std::string &);
        bool is_identifier(const std::string &);
 
-       ProgramSyntax::Node *parse_global_declaration();
-       ProgramSyntax::Node *parse_statement();
-       ProgramSyntax::Import *parse_import();
-       ProgramSyntax::Layout *parse_layout();
+       RefPtr<ProgramSyntax::Node> parse_global_declaration();
+       RefPtr<ProgramSyntax::Node> parse_statement();
+       RefPtr<ProgramSyntax::Import> parse_import();
+       RefPtr<ProgramSyntax::Layout> parse_layout();
        void parse_block(ProgramSyntax::Block &, bool);
-       ProgramSyntax::Expression *parse_expression(unsigned = 0);
-       ProgramSyntax::BinaryExpression *parse_binary(ProgramSyntax::Expression *, const Operator *);
-       ProgramSyntax::FunctionCall *parse_function_call(ProgramSyntax::VariableReference *);
-       ProgramSyntax::StructDeclaration *parse_struct_declaration();
-       ProgramSyntax::VariableDeclaration *parse_variable_declaration();
-       ProgramSyntax::FunctionDeclaration *parse_function_declaration();
-       ProgramSyntax::InterfaceBlock *parse_interface_block();
-       ProgramSyntax::Conditional *parse_conditional();
-       ProgramSyntax::Iteration *parse_iteration();
-       ProgramSyntax::Passthrough *parse_passthrough();
-       ProgramSyntax::Return *parse_return();
+       RefPtr<ProgramSyntax::Expression> parse_expression(unsigned = 0);
+       RefPtr<ProgramSyntax::BinaryExpression> parse_binary(const RefPtr<ProgramSyntax::Expression> &, const Operator *);
+       RefPtr<ProgramSyntax::FunctionCall> parse_function_call(const ProgramSyntax::VariableReference &);
+       RefPtr<ProgramSyntax::StructDeclaration> parse_struct_declaration();
+       RefPtr<ProgramSyntax::VariableDeclaration> parse_variable_declaration();
+       RefPtr<ProgramSyntax::FunctionDeclaration> parse_function_declaration();
+       RefPtr<ProgramSyntax::InterfaceBlock> parse_interface_block();
+       RefPtr<ProgramSyntax::Conditional> parse_conditional();
+       RefPtr<ProgramSyntax::Iteration> parse_iteration();
+       RefPtr<ProgramSyntax::Passthrough> parse_passthrough();
+       RefPtr<ProgramSyntax::Return> parse_return();
 };
 
 } // namespace GL
index c6e0f6d40e9bc9ca97583adf07454af208bcadf9..e67784fe8626a24522b43db5e203cb78354108bc 100644 (file)
@@ -192,7 +192,7 @@ void NodeVisitor::visit(Assignment &assign)
 
 void TraversingVisitor::visit(Block &block)
 {
-       for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
+       for(list<RefPtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
                (*i)->visit(*this);
 }
 
@@ -219,7 +219,7 @@ void TraversingVisitor::visit(BinaryExpression &binary)
 
 void TraversingVisitor::visit(FunctionCall &call)
 {
-       for(vector<NodePtr<Expression> >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
+       for(vector<RefPtr<Expression> >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
                (*i)->visit(*this);
 }
 
@@ -255,7 +255,7 @@ void TraversingVisitor::visit(InterfaceBlock &iface)
 
 void TraversingVisitor::visit(FunctionDeclaration &func)
 {
-       for(vector<NodePtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+       for(vector<RefPtr<VariableDeclaration> >::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
                (*i)->visit(*this);
        func.body.visit(*this);
 }
index c502ba47a90f32701bc885e44006ff48a8d93c24..9a0cc6ea3f4bc8c867a2d381494b816b937495eb 100644 (file)
@@ -5,6 +5,7 @@
 #include <map>
 #include <string>
 #include <vector>
+#include <msp/core/refptr.h>
 #include "extension.h"
 
 namespace Msp {
@@ -24,40 +25,13 @@ public:
        virtual void visit(NodeVisitor &) = 0;
 };
 
-template<typename T>
-class NodePtr
-{
-private:
-       T *node;
-
-public:
-       NodePtr(T *n = 0): node(n) { }
-       NodePtr(const NodePtr &p): node(clone(p.node)) { }
-       NodePtr &operator=(const NodePtr &p) { delete node; node = clone(p.node); return *this; }
-#if __cplusplus>=201103L
-       NodePtr(NodePtr &&p): node(p.node) { p.node = 0; }
-       NodePtr &operator=(NodePtr &&p) { delete node; node = p.node; p.node = 0; return *this; }
-#endif
-       ~NodePtr() { delete node; }
-
-private:
-       static T *clone(T *n) { return n ? n->clone() : 0; }
-
-public:
-       T *operator->() { return node; }
-       const T *operator->() const { return node; }
-       T &operator*() { return *node; }
-       const T &operator*() const { return *node; }
-       operator void *() const { return node; }
-};
-
 struct StructDeclaration;
 struct VariableDeclaration;
 struct FunctionDeclaration;
 
 struct Block: Node
 {
-       std::list<NodePtr<Node> > body;
+       std::list<RefPtr<Node> > body;
        bool use_braces;
        std::map<std::string, StructDeclaration *> types;
        std::map<std::string, VariableDeclaration *> variables;
@@ -83,7 +57,7 @@ struct Literal: Expression
 
 struct ParenthesizedExpression: Expression
 {
-       NodePtr<Expression> expression;
+       RefPtr<Expression> expression;
 
        virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
        virtual void visit(NodeVisitor &);
@@ -102,7 +76,7 @@ struct VariableReference: Expression
 
 struct MemberAccess: Expression
 {
-       NodePtr<Expression> left;
+       RefPtr<Expression> left;
        std::string member;
        VariableDeclaration *declaration;
 
@@ -113,7 +87,7 @@ struct MemberAccess: Expression
 struct UnaryExpression: Expression
 {
        std::string oper;
-       NodePtr<Expression> expression;
+       RefPtr<Expression> expression;
        bool prefix;
 
        UnaryExpression();
@@ -124,9 +98,9 @@ struct UnaryExpression: Expression
 
 struct BinaryExpression: Expression
 {
-       NodePtr<Expression> left;
+       RefPtr<Expression> left;
        std::string oper;
-       NodePtr<Expression> right;
+       RefPtr<Expression> right;
        std::string after;
 
        virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
@@ -149,7 +123,7 @@ struct FunctionCall: Expression
        std::string name;
        FunctionDeclaration *declaration;
        bool constructor;
-       std::vector<NodePtr<Expression> > arguments;
+       std::vector<RefPtr<Expression> > arguments;
 
        FunctionCall();
 
@@ -159,7 +133,7 @@ struct FunctionCall: Expression
 
 struct ExpressionStatement: Node
 {
-       NodePtr<Expression> expression;
+       RefPtr<Expression> expression;
 
        virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
        virtual void visit(NodeVisitor &);
@@ -216,10 +190,10 @@ struct VariableDeclaration: Node
        StructDeclaration *type_declaration;
        std::string name;
        bool array;
-       NodePtr<Expression> array_size;
-       NodePtr<Expression> init_expression;
+       RefPtr<Expression> array_size;
+       RefPtr<Expression> init_expression;
        VariableDeclaration *linked_declaration;
-       NodePtr<Layout> layout;
+       RefPtr<Layout> layout;
 
        VariableDeclaration();
 
@@ -245,7 +219,7 @@ struct FunctionDeclaration: Node
 {
        std::string return_type;
        std::string name;
-       std::vector<NodePtr<VariableDeclaration> > parameters;
+       std::vector<RefPtr<VariableDeclaration> > parameters;
        FunctionDeclaration *definition;
        Block body;
 
@@ -258,7 +232,7 @@ struct FunctionDeclaration: Node
 
 struct Conditional: Node
 {
-       NodePtr<Expression> condition;
+       RefPtr<Expression> condition;
        Block body;
        Block else_body;
 
@@ -268,9 +242,9 @@ struct Conditional: Node
 
 struct Iteration: Node
 {
-       NodePtr<Node> init_statement;
-       NodePtr<Expression> condition;
-       NodePtr<Expression> loop_expression;
+       RefPtr<Node> init_statement;
+       RefPtr<Expression> condition;
+       RefPtr<Expression> loop_expression;
        Block body;
 
        virtual Iteration *clone() const { return new Iteration(*this); }
@@ -279,7 +253,7 @@ struct Iteration: Node
 
 struct Passthrough: Node
 {
-       NodePtr<Expression> subscript;
+       RefPtr<Expression> subscript;
 
        virtual Passthrough *clone() const { return new Passthrough(*this); }
        virtual void visit(NodeVisitor &);
@@ -287,7 +261,7 @@ struct Passthrough: Node
 
 struct Return: Node
 {
-       NodePtr<Expression> expression;
+       RefPtr<Expression> expression;
 
        virtual Return *clone() const { return new Return(*this); }
        virtual void visit(NodeVisitor &);