]> git.tdb.fi Git - libs/gl.git/commitdiff
Refactor the GLSL compiler to use unique pointers
authorMikko Rasa <tdb@tdb.fi>
Sun, 17 Dec 2023 08:43:03 +0000 (10:43 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 17 Dec 2023 09:23:37 +0000 (11:23 +0200)
Both clone and move assignments are now explicit, although NodePtr still
has an implicitly cloning copy constructor to facilitate automatically
generated copy constructors in the node classes.  Node containers wrap
the std container instead of inheriting and only allow adding elements
by move.

21 files changed:
source/glsl/builtin.cpp
source/glsl/compiler.cpp
source/glsl/debug.cpp
source/glsl/finalize.cpp
source/glsl/finalize.h
source/glsl/generate.cpp
source/glsl/generate.h
source/glsl/optimize.cpp
source/glsl/optimize.h
source/glsl/output.cpp
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/reflect.cpp
source/glsl/resolve.cpp
source/glsl/resolve.h
source/glsl/spirv.cpp
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/validate.cpp
source/glsl/visitor.cpp
source/glsl/visitor.h

index 35042460c7c481e17e2d67ac660dda1b861814ec..881bec76587e5e65a020818be3e9ec5a7f3d4042 100644 (file)
@@ -12,14 +12,14 @@ namespace SL {
 
 void add_builtin_type(Stage &stage, const string &name, BasicTypeDeclaration::Kind kind, unsigned size, unsigned sign)
 {
-       RefPtr<BasicTypeDeclaration> type = new BasicTypeDeclaration;
+       unique_ptr<BasicTypeDeclaration> type = make_unique<BasicTypeDeclaration>();
        type->source = BUILTIN_SOURCE;
        type->name = name;
        type->kind = kind;
        type->size = size;
        type->sign = sign;
-       stage.content.body.push_back(type);
        stage.types[name] = type.get();
+       stage.content.body.push_back(move(type));
 }
 
 Module *get_builtins_module()
index 7da7fcd9601ca08f2b92971aa3df12b69657c596..7d1db5a3b664a6851e248606a432c7a9dfc64276 100644 (file)
@@ -250,8 +250,8 @@ void Compiler::append_module(const Module &mod, ModuleCache &mod_cache)
        module->source_map.merge_from(mod.source_map);
 
        vector<Import *> imports;
-       for(const RefPtr<Statement> &s: mod.shared.content.body)
-               if(Import *imp = dynamic_cast<Import *>(s.get()))
+       for(const NodePtr<Statement> &s: mod.shared.content.body)
+               if(Import *imp = s.get_as<Import>())
                        imports.push_back(imp);
        for(Import *i: imports)
                import(mod_cache, i->module);
@@ -284,9 +284,9 @@ void Compiler::append_stage(const Stage &stage)
 
        if(target->required_features.glsl_version<stage.required_features.glsl_version)
                target->required_features.glsl_version = stage.required_features.glsl_version;
-       for(const RefPtr<Statement> &s: stage.content.body)
-               if(!dynamic_cast<Import *>(s.get()))
-                       target->content.body.push_back(s);
+       for(const NodePtr<Statement> &s: stage.content.body)
+               if(!s.get_as<Import>())
+                       target->content.body.push_back(s.clone());
 }
 
 void Compiler::import(ModuleCache &mod_cache, const string &name)
@@ -434,8 +434,8 @@ void Compiler::finalize(Stage &stage, Mode mode)
 void Compiler::inject_block(Block &target, const Block &source)
 {
        auto insert_point = target.body.begin();
-       for(const RefPtr<Statement> &s: source.body)
-               target.body.insert(insert_point, s->clone());
+       for(const NodePtr<Statement> &s: source.body)
+               target.body.insert(insert_point, s.clone());
 }
 
 } // namespace SL
index a090c3622079bd9bfeedf2fc517a276d7877d463..f8d9515b58f161c5004879d96bf548b2bcfea321 100644 (file)
@@ -429,7 +429,7 @@ void DumpTree::visit(FunctionDeclaration &func)
        begin_sub();
        if(func.return_type_declaration)
                append(format("Return type: %s %s", get_label(*func.return_type_declaration), format_type(func.return_type_declaration)));
-       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+       for(const NodePtr<VariableDeclaration> &p: func.parameters)
                p->visit(*this);
        last_branch();
        if(func.definition==&func)
index c8fc04a9dc021536868d59fd2256244ab9b209d9..e26b7b26a849456d7734fe7105f54787d4ab8c13 100644 (file)
@@ -154,7 +154,7 @@ void LocationAllocator::allocate_locations(const string &iface)
        unplaced_variables.erase(write, unplaced_variables.end());
 }
 
-void LocationAllocator::bind_uniform(RefPtr<Layout> &layout, const string &name, unsigned range)
+void LocationAllocator::bind_uniform(NodePtr<Layout> &layout, const string &name, unsigned range)
 {
        auto i = uniforms.find(name);
 
@@ -178,7 +178,7 @@ void LocationAllocator::bind_uniform(RefPtr<Layout> &layout, const string &name,
        }
 }
 
-bool LocationAllocator::visit_uniform(const string &name, RefPtr<Layout> &layout)
+bool LocationAllocator::visit_uniform(const string &name, NodePtr<Layout> &layout)
 {
        int desc_set = get_layout_value(layout.get(), "set");
        int bind_point = get_layout_value(layout.get(), "binding");
@@ -264,40 +264,40 @@ void DepthRangeConverter::apply(Module &module, const Features &features)
                s->content.visit(*this);
 }
 
-NodePtr<Statement> DepthRangeConverter::create_conversion_statement()
+unique_ptr<Statement> DepthRangeConverter::create_conversion_statement()
 {
-       VariableReference *position = new VariableReference;
+       NodePtr<VariableReference> position = make_unique<VariableReference>();
        position->name = "gl_Position";
 
-       MemberAccess *z = new MemberAccess;
-       z->left = position;
+       NodePtr<MemberAccess> z = make_unique<MemberAccess>();
+       z->left = position.clone();
        z->member = "z";
 
-       Literal *scale = new Literal;
+       unique_ptr<Literal> scale = make_unique<Literal>();
        scale->token = "2.0";
        scale->value = 2.0f;
 
-       BinaryExpression *multiply = new BinaryExpression;
+       unique_ptr<BinaryExpression> multiply = make_unique<BinaryExpression>();
        multiply->oper = &Operator::get_operator("*", Operator::BINARY);
-       multiply->left = z;
-       multiply->right = scale;
+       multiply->left = z.clone();
+       multiply->right = move(scale);
 
-       MemberAccess *w = new MemberAccess;
-       w->left = position->clone();
+       unique_ptr<MemberAccess> w = make_unique<MemberAccess>();
+       w->left = move(position);
        w->member = "w";
 
-       BinaryExpression *subtract = new BinaryExpression;
+       unique_ptr<BinaryExpression> subtract = make_unique<BinaryExpression>();
        subtract->oper = &Operator::get_operator("-", Operator::BINARY);
-       subtract->left = multiply;
-       subtract->right = w;
+       subtract->left = move(multiply);
+       subtract->right = move(w);
 
-       Assignment *assign = new Assignment;
+       unique_ptr<Assignment> assign = make_unique<Assignment>();
        assign->oper = &Operator::get_operator("=", Operator::BINARY);
-       assign->left = z->clone();
-       assign->right = subtract;
+       assign->left = move(z);
+       assign->right = move(subtract);
 
-       ExpressionStatement *statement = new ExpressionStatement;
-       statement->expression = assign;
+       unique_ptr<ExpressionStatement> statement = make_unique<ExpressionStatement>();
+       statement->expression = move(assign);
 
        return statement;
 }
@@ -310,7 +310,7 @@ void DepthRangeConverter::visit(Block &block)
                (*i)->visit(*this);
                if(r_emitvertex && !r_position_z_assigned)
                {
-                       block.body.insert_nocopy(i, create_conversion_statement());
+                       block.body.insert(i, create_conversion_statement());
                        r_position_z_assigned = true;
                }
        }
@@ -364,7 +364,7 @@ void DepthRangeConverter::visit(FunctionDeclaration &func)
 
        if(func.definition==&func && func.name=="main" && r_position_assigned && !r_position_z_assigned)
        {
-               func.body.body.push_back_nocopy(create_conversion_statement());
+               func.body.body.push_back(create_conversion_statement());
                r_position_z_assigned = true;
        }
 }
@@ -426,10 +426,10 @@ void PrecisionConverter::visit(VariableDeclaration &var)
 
        if(!have_default.count(type->name))
        {
-               Precision *prec = new Precision;
+               unique_ptr<Precision> prec = make_unique<Precision>();
                prec->precision = default_prec;
                prec->type = type->name;
-               stage->content.body.insert(insert_point, prec);
+               stage->content.body.insert(insert_point, move(prec));
 
                have_default.insert(type->name);
        }
@@ -498,12 +498,12 @@ void StructuralFeatureConverter::visit(Block &block)
        }
 }
 
-void StructuralFeatureConverter::visit(RefPtr<Expression> &expr)
+void StructuralFeatureConverter::visit(NodePtr<Expression> &expr)
 {
        r_replaced_reference = nullptr;
        expr->visit(*this);
        if(r_replaced_reference)
-               expr = r_replaced_reference;
+               expr = move(r_replaced_reference);
        r_replaced_reference = nullptr;
 }
 
@@ -559,9 +559,9 @@ void StructuralFeatureConverter::visit(MemberAccess &memacc)
        visit(memacc.left);
        if(r_flattened_interface)
        {
-               VariableReference *var = new VariableReference;
+               unique_ptr<VariableReference> var = make_unique<VariableReference>();
                var->name = memacc.member;
-               r_replaced_reference = var;
+               r_replaced_reference = move(var);
        }
 }
 
@@ -654,7 +654,7 @@ void StructuralFeatureConverter::visit(VariableDeclaration &var)
                                unsupported("ARB_uniform_buffer_object required for interface block instances");
                        else
                        {
-                               for(const RefPtr<Statement> &s: var.block_declaration->members.body)
+                               for(const NodePtr<Statement> &s: var.block_declaration->members.body)
                                        if(VariableDeclaration *mem = dynamic_cast<VariableDeclaration *>(s.get()))
                                                mem->interface = var.interface;
                                stage->content.body.splice(uniform_insert_point, var.block_declaration->members.body);
index fcacf774a315125954a1bb67e207c40128e3c945..5ec64d4b88d7c390a859e3b9999cf5d02ffeb024 100644 (file)
@@ -53,9 +53,9 @@ private:
        void apply(Stage &);
 
        void allocate_locations(const std::string &);
-       void bind_uniform(RefPtr<Layout> &, const std::string &, unsigned);
+       void bind_uniform(NodePtr<Layout> &, const std::string &, unsigned);
 
-       bool visit_uniform(const std::string &, RefPtr<Layout> &);
+       bool visit_uniform(const std::string &, NodePtr<Layout> &);
        void visit(VariableDeclaration &) override;
        void visit(FunctionDeclaration &) override { }
 };
@@ -77,7 +77,7 @@ public:
        void apply(Module &, const Features &);
 
 private:
-       NodePtr<Statement> create_conversion_statement();
+       std::unique_ptr<Statement> create_conversion_statement();
 
        void visit(Block &) override;
        void visit(VariableReference &) override;
@@ -135,7 +135,7 @@ private:
        VariableDeclaration *frag_out = nullptr;
        NodeList<Statement>::iterator uniform_insert_point;
        std::set<Node *> nodes_to_remove;
-       RefPtr<Expression> r_replaced_reference;
+       std::unique_ptr<Expression> r_replaced_reference;
        bool r_flattened_interface = false;
 
 public:
@@ -144,7 +144,7 @@ private:
        void apply() override;
 
        void visit(Block &) override;
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        bool supports_stage(Stage::Type) const;
        bool supports_unified_interface_syntax() const;
        void visit(VariableReference &) override;
index de32b90a2bb71b39285327237011fb4e2b0999bf..c6aae64ea9ed7c705432348c0e3d1f03a79b3cb1 100644 (file)
@@ -104,7 +104,7 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration
        if(stage->type==Stage::GEOMETRY && var.interface=="out" && var.array)
                return nullptr;
 
-       VariableDeclaration* iface_var = new VariableDeclaration;
+       unique_ptr<VariableDeclaration> iface_var = make_unique<VariableDeclaration>();
        iface_var->sampling = var.sampling;
        if(stage->type==Stage::FRAGMENT && iface=="in")
                if(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(var.type_declaration))
@@ -127,66 +127,70 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration
        else
                iface_var->array = var.array;
        if(iface_var->array)
-               iface_var->array_size = var.array_size;
+               iface_var->array_size = var.array_size.clone();
        if(iface=="in")
        {
-               iface_var->layout = var.layout;
+               iface_var->layout = var.layout.clone();
                iface_var->linked_declaration = &var;
-               var.linked_declaration = iface_var;
+               var.linked_declaration = iface_var.get();
        }
 
        if(var.block_declaration)
        {
-               StructDeclaration *iface_type = var.block_declaration->clone();
+               unique_ptr<StructDeclaration> iface_type(var.block_declaration->clone());
                iface_type->name = format("_%s_%s", iface, var.block_declaration->block_name);
-               iface_target_block->body.insert(iface_insert_point, iface_type);
 
                iface_var->type = iface_type->name;
                if(name.empty())
                        iface_var->name = format("%s %s", iface, var.block_declaration->block_name);
 
-               stage->interface_blocks.insert(make_pair("in "+var.block_declaration->block_name, iface_var));
+               stage->interface_blocks.insert(make_pair("in "+var.block_declaration->block_name, iface_var.get()));
                if(!name.empty())
-                       stage->interface_blocks.insert(make_pair(name, iface_var));
+                       stage->interface_blocks.insert(make_pair(name, iface_var.get()));
+
+               iface_target_block->body.insert(iface_insert_point, move(iface_type));
        }
 
-       iface_target_block->body.insert(iface_insert_point, iface_var);
-       iface_target_block->variables.insert(make_pair(name, iface_var));
+       iface_target_block->variables.insert(make_pair(name, iface_var.get()));
        if(iface_target_block==&stage->content && iface=="in")
-               declared_inputs.push_back(iface_var);
+               declared_inputs.push_back(iface_var.get());
+
+       VariableDeclaration *result = iface_var.get();
+       iface_target_block->body.insert(iface_insert_point, move(iface_var));
 
-       return iface_var;
+       return result;
 }
 
-ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, Expression *right)
+ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, unique_ptr<Expression> right)
 {
-       Assignment *assign = new Assignment;
+       unique_ptr<Assignment> assign = make_unique<Assignment>();
 
        string::size_type dot = left.find('.');
-       VariableReference *ref = new VariableReference;
+       unique_ptr<VariableReference> ref = make_unique<VariableReference>();
        ref->name = left.substr(0, dot);
-       assign->left = ref;
+       assign->left = move(ref);
 
        while(dot!=string::npos)
        {
                string::size_type start = dot+1;
                dot = left.find('.', start);
 
-               MemberAccess *memacc = new MemberAccess;
-               memacc->left = assign->left;
+               unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
+               memacc->left = move(assign->left);
                memacc->member = left.substr(start, dot-start);
-               assign->left = memacc;
+               assign->left = move(memacc);
        }
 
        assign->oper = &Operator::get_operator("=", Operator::BINARY);
-       assign->right = right;
+       assign->right = move(right);
 
-       ExpressionStatement *stmt = new ExpressionStatement;
-       stmt->expression = assign;
-       current_block->body.insert(assignment_insert_point, stmt);
-       stmt->visit(*this);
+       unique_ptr<ExpressionStatement> stmt = make_unique<ExpressionStatement>();
+       stmt->expression = move(assign);
+       ExpressionStatement *result = stmt.get();
+       current_block->body.insert(assignment_insert_point, move(stmt));
+       result->visit(*this);
 
-       return *stmt;
+       return *result;
 }
 
 void InterfaceGenerator::visit(VariableReference &var)
@@ -242,7 +246,7 @@ void InterfaceGenerator::visit(VariableDeclaration &var)
                        nodes_to_remove.insert(&var);
                        if(var.init_expression)
                        {
-                               ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone());
+                               ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression.clone());
                                stmt.source = var.source;
                                stmt.line = var.line;
                                return;
@@ -314,19 +318,19 @@ void InterfaceGenerator::visit(Passthrough &pass)
        {
                /* Special case for geometry shader: copy gl_Position from input to
                output. */
-               VariableReference *ref = new VariableReference;
+               unique_ptr<VariableReference> ref = make_unique<VariableReference>();
                ref->name = "gl_in";
 
-               BinaryExpression *subscript = new BinaryExpression;
-               subscript->left = ref;
+               unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+               subscript->left = move(ref);
                subscript->oper = &Operator::get_operator("[", Operator::BINARY);
-               subscript->right = pass.subscript;
+               subscript->right = pass.subscript.clone();
 
-               MemberAccess *memacc = new MemberAccess;
-               memacc->left = subscript;
+               unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
+               memacc->left = move(subscript);
                memacc->member = "gl_Position";
 
-               insert_assignment("out gl_PerVertex.gl_Position", memacc);
+               insert_assignment("out gl_PerVertex.gl_Position", move(memacc));
        }
 
        for(VariableDeclaration *v: pass_vars)
@@ -334,18 +338,18 @@ void InterfaceGenerator::visit(Passthrough &pass)
                string out_name = change_prefix(v->name, out_prefix);
                generate_interface(*v, "out", out_name);
 
-               VariableReference *ref = new VariableReference;
+               unique_ptr<VariableReference> ref = make_unique<VariableReference>();
                ref->name = v->name;
                if(pass.subscript)
                {
-                       BinaryExpression *subscript = new BinaryExpression;
-                       subscript->left = ref;
+                       unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+                       subscript->left = move(ref);
                        subscript->oper = &Operator::get_operator("[", Operator::BINARY);
-                       subscript->right = pass.subscript;
-                       insert_assignment(out_name, subscript);
+                       subscript->right = pass.subscript.clone();
+                       insert_assignment(out_name, move(subscript));
                }
                else
-                       insert_assignment(out_name, ref);
+                       insert_assignment(out_name, move(ref));
        }
 
        nodes_to_remove.insert(&pass);
@@ -400,10 +404,10 @@ void ArraySizer::apply(Stage &stage)
 
                        if(size>0)
                        {
-                               Literal *literal_size = new Literal;
+                               unique_ptr<Literal> literal_size = make_unique<Literal>();
                                literal_size->token = lexical_cast<string>(size);
                                literal_size->value = size;
-                               kvp.first->array_size = literal_size;
+                               kvp.first->array_size = move(literal_size);
                        }
                }
 }
index e43c5bd665b5c8e223a9542ff47be822135a1fca..bc25a7129778a7be684e689d72c28b194d1a3c39 100644 (file)
@@ -56,7 +56,7 @@ private:
        std::string change_prefix(const std::string &, const std::string &) const;
        void visit(Block &) override;
        VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
-       ExpressionStatement &insert_assignment(const std::string &, Expression *);
+       ExpressionStatement &insert_assignment(const std::string &, std::unique_ptr<Expression>);
        void visit(VariableReference &) override;
        void visit(VariableDeclaration &) override;
        void visit(FunctionDeclaration &) override;
index 45d8745d240835b7121703619daa69354d0e2000..a3eb20f2855ffda73820ddc4f9abbd38ec008748 100644 (file)
@@ -38,7 +38,7 @@ void ConstantSpecializer::visit(VariableDeclaration &var)
                auto i = values->find(var.name);
                if(i!=values->end())
                {
-                       RefPtr<Literal> literal = new Literal;
+                       unique_ptr<Literal> literal = make_unique<Literal>();
                        if(var.type=="bool")
                        {
                                literal->token = (i->second ? "true" : "false");
@@ -49,7 +49,7 @@ void ConstantSpecializer::visit(VariableDeclaration &var)
                                literal->token = lexical_cast<string>(i->second);
                                literal->value = i->second;
                        }
-                       var.init_expression = literal;
+                       var.init_expression = move(literal);
                }
        }
 }
@@ -77,7 +77,7 @@ void InlineableFunctionLocator::visit(FunctionCall &call)
 void InlineableFunctionLocator::visit(FunctionDeclaration &func)
 {
        bool has_out_params = any_of(func.parameters.begin(), func.parameters.end(),
-               [](const RefPtr<VariableDeclaration> &p){ return p->interface=="out"; });
+               [](const NodePtr<VariableDeclaration> &p){ return p->interface=="out"; });
 
        unsigned &count = refcounts[func.definition];
        if((count<=1 || func.source==BUILTIN_SOURCE) && !has_out_params)
@@ -132,31 +132,31 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu
        staging_block.parent = &tgt_blk;
        staging_block.variables.clear();
 
-       vector<RefPtr<VariableDeclaration> > params;
+       vector<VariableDeclaration *> params;
        params.reserve(source_func->parameters.size());
-       for(const RefPtr<VariableDeclaration> &p: source_func->parameters)
+       for(const NodePtr<VariableDeclaration> &p: source_func->parameters)
        {
-               RefPtr<VariableDeclaration> var = p->clone();
+               NodePtr<VariableDeclaration> var = p.clone();
                var->interface.clear();
 
                SetForScope<Pass> set_pass(pass, RENAME);
                var->visit(*this);
 
-               staging_block.body.push_back_nocopy(var);
-               params.push_back(var);
+               params.push_back(var.get());
+               staging_block.body.push_back(move(var));
        }
 
-       for(const RefPtr<Statement> &s: source_func->body.body)
+       for(const NodePtr<Statement> &s: source_func->body.body)
        {
                r_inlined_statement = nullptr;
                s->visit(*this);
                if(!r_inlined_statement)
-                       r_inlined_statement = s->clone();
+                       r_inlined_statement = s.clone();
 
                SetForScope<Pass> set_pass(pass, RENAME);
                r_inlined_statement->visit(*this);
 
-               staging_block.body.push_back_nocopy(r_inlined_statement);
+               staging_block.body.push_back(move(r_inlined_statement));
        }
 
        /* Now collect names from the staging block.  Local variables that would
@@ -174,7 +174,7 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu
 
        // Put the argument expressions in place after all renaming has been done.
        for(unsigned i=0; i<source_func->parameters.size(); ++i)
-               params[i]->init_expression = call.arguments[i]->clone();
+               params[i]->init_expression = call.arguments[i].clone();
 
        tgt_blk.body.splice(ins_pt, staging_block.body);
 
@@ -234,13 +234,13 @@ void InlineContentInjector::visit(Return &ret)
        {
                // Create a new variable to hold the return value of the inlined function.
                r_result_name = get_unused_variable_name(staging_block, "_return");
-               RefPtr<VariableDeclaration> var = new VariableDeclaration;
+               unique_ptr<VariableDeclaration> var = make_unique<VariableDeclaration>();
                var->source = ret.source;
                var->line = ret.line;
                var->type = source_func->return_type;
                var->name = r_result_name;
-               var->init_expression = ret.expression->clone();
-               r_inlined_statement = var;
+               var->init_expression = ret.expression.clone();
+               r_inlined_statement = move(var);
        }
 }
 
@@ -254,13 +254,13 @@ bool FunctionInliner::apply(Stage &s)
        return r_any_inlined;
 }
 
-void FunctionInliner::visit(RefPtr<Expression> &ptr)
+void FunctionInliner::visit(NodePtr<Expression> &ptr)
 {
        r_inline_result = nullptr;
        ptr->visit(*this);
        if(r_inline_result)
        {
-               ptr = r_inline_result;
+               ptr = move(r_inline_result);
                r_any_inlined = true;
        }
        r_inline_result = nullptr;
@@ -297,9 +297,9 @@ void FunctionInliner::visit(FunctionCall &call)
                if(result_name.empty())
                        result_name = "_msp_unused_from_inline";
 
-               RefPtr<VariableReference> ref = new VariableReference;
+               unique_ptr<VariableReference> ref = make_unique<VariableReference>();
                ref->name = result_name;
-               r_inline_result = ref;
+               r_inline_result = move(ref);
 
                /* Inlined variables need to be resolved before this function can be
                inlined further. */
@@ -341,7 +341,7 @@ bool ExpressionInliner::apply(Stage &s)
                        for(ExpressionUse &u: e.uses)
                                if(!u.blocked)
                                {
-                                       *u.reference = e.expression->clone();
+                                       *u.reference = unique_ptr<Expression>(e.expression->clone());
                                        if(u.containing_expr)
                                                u.containing_expr->expression = 0;
                                        any_inlined = true;
@@ -351,7 +351,7 @@ bool ExpressionInliner::apply(Stage &s)
        return any_inlined;
 }
 
-void ExpressionInliner::visit(RefPtr<Expression> &expr)
+void ExpressionInliner::visit(NodePtr<Expression> &expr)
 {
        r_ref_info = nullptr;
        expr->visit(*this);
@@ -436,7 +436,7 @@ void ExpressionInliner::visit(Assignment &assign)
                info->target = assign.target;
                // Self-referencing assignments can't be inlined without additional work.
                if(!assign.self_referencing)
-                       info->expression = assign.right;
+                       info->expression = assign.right.get();
                info->assign_scope = current_block;
        }
 
@@ -492,7 +492,7 @@ void ExpressionInliner::visit(VariableDeclaration &var)
                /* Assume variables declared in an iteration initialization statement
                will have their values change throughout the iteration. */
                if(!iteration_init)
-                       info->expression = var.init_expression;
+                       info->expression = var.init_expression.get();
                info->assign_scope = current_block;
        }
 
@@ -557,24 +557,25 @@ bool AggregateDismantler::apply(Stage &stage)
                                name = format("%s_%s", kvp.second.declaration->name, m.declaration->name);
                        else
                                name = format("%s_%d", kvp.second.declaration->name, m.index);
+                       name = get_unused_variable_name(*kvp.second.decl_scope, name);
 
-                       VariableDeclaration *var = new VariableDeclaration;
+                       unique_ptr<VariableDeclaration> var = make_unique<VariableDeclaration>();
                        var->source = kvp.first->source;
                        var->line = kvp.first->line;
-                       var->name = get_unused_variable_name(*kvp.second.decl_scope, name);
+                       var->name = name;
                        /* XXX This is kind of brittle and depends on the array declaration's
                        textual type not having brackets in it. */
                        var->type = (m.declaration ? m.declaration : kvp.second.declaration)->type;
                        if(m.initializer)
                                var->init_expression = m.initializer->clone();
 
-                       kvp.second.decl_scope->body.insert(kvp.second.insert_point, var);
+                       kvp.second.decl_scope->body.insert(kvp.second.insert_point, move(var));
 
-                       for(RefPtr<Expression> *r: m.references)
+                       for(NodePtr<Expression> *r: m.references)
                        {
-                               VariableReference *ref = new VariableReference;
-                               ref->name = var->name;
-                               *r = ref;
+                               unique_ptr<VariableReference> ref = make_unique<VariableReference>();
+                               ref->name = name;
+                               *r = move(ref);
                        }
 
                        any_dismantled = true;
@@ -594,7 +595,7 @@ void AggregateDismantler::visit(Block &block)
        }
 }
 
-void AggregateDismantler::visit(RefPtr<Expression> &expr)
+void AggregateDismantler::visit(NodePtr<Expression> &expr)
 {
        r_aggregate_ref = nullptr;
        expr->visit(*this);
@@ -627,7 +628,7 @@ void AggregateDismantler::visit(VariableReference &var)
        }
 }
 
-void AggregateDismantler::visit_composite(RefPtr<Expression> &expr)
+void AggregateDismantler::visit_composite(NodePtr<Expression> &expr)
 {
        if(!composite_reference)
                r_reference = Assignment::Target();
@@ -662,7 +663,7 @@ void AggregateDismantler::visit(BinaryExpression &binary)
                }
 
                unsigned index = 0x3F;
-               if(Literal *literal_subscript = dynamic_cast<Literal *>(binary.right.get()))
+               if(Literal *literal_subscript = binary.right.get_as<Literal>())
                        if(literal_subscript->value.has_type<int>())
                                index = literal_subscript->value.value<int>();
                add_to_chain(r_reference, Assignment::Target::ARRAY, index);
@@ -690,7 +691,7 @@ void AggregateDismantler::visit(VariableDeclaration &var)
        {
                if(const StructDeclaration *strct = dynamic_cast<const StructDeclaration *>(var.type_declaration))
                {
-                       const FunctionCall *init_call = dynamic_cast<const FunctionCall *>(var.init_expression.get());
+                       const FunctionCall *init_call = var.init_expression.get_as<const FunctionCall>();
                        if((init_call && init_call->constructor) || !var.init_expression)
                        {
 
@@ -700,21 +701,21 @@ void AggregateDismantler::visit(VariableDeclaration &var)
                                aggre.insert_point = insert_point;
 
                                unsigned i = 0;
-                               for(const RefPtr<Statement> &s: strct->members.body)
+                               for(const NodePtr<Statement> &s: strct->members.body)
                                {
-                                       if(const VariableDeclaration *mem_decl = dynamic_cast<const VariableDeclaration *>(s.get()))
+                                       if(const VariableDeclaration *mem_decl = s.get_as<const VariableDeclaration>())
                                        {
                                                AggregateMember &member = aggre.members.emplace_back();
                                                member.declaration = mem_decl;
                                                member.index = i;
                                                if(init_call)
-                                                       member.initializer = init_call->arguments[i];
+                                                       member.initializer = &init_call->arguments[i];
                                        }
                                        ++i;
                                }
                        }
                }
-               else if(const Literal *literal_size = dynamic_cast<const Literal *>(var.array_size.get()))
+               else if(const Literal *literal_size = var.array_size.get_as<const Literal>())
                {
                        if(literal_size->value.has_type<int>())
                        {
@@ -811,7 +812,7 @@ void ConstantFolder::set_result(const Variant &value, bool literal)
        r_literal = literal;
 }
 
-void ConstantFolder::visit(RefPtr<Expression> &expr)
+void ConstantFolder::visit(NodePtr<Expression> &expr)
 {
        r_constant_value = Variant();
        r_constant = false;
@@ -824,7 +825,7 @@ void ConstantFolder::visit(RefPtr<Expression> &expr)
        if(!r_constant || r_literal || r_uses_iter_var)
                return;
 
-       RefPtr<Literal> literal = new Literal;
+       unique_ptr<Literal> literal = make_unique<Literal>();
        if(r_constant_value.has_type<bool>())
                literal->token = (r_constant_value.value<bool>() ? "true" : "false");
        else if(r_constant_value.has_type<int>())
@@ -843,7 +844,7 @@ void ConstantFolder::visit(RefPtr<Expression> &expr)
                return;
        }
        literal->value = r_constant_value;
-       expr = literal;
+       expr = move(literal);
        r_any_folded = true;
 }
 
@@ -1053,10 +1054,10 @@ void ConstantFolder::visit(Iteration &iter)
                visit(iter.condition);
                if(r_constant && r_constant_value.has_type<bool>() && !r_constant_value.value<bool>())
                {
-                       RefPtr<Literal> literal = new Literal;
+                       unique_ptr<Literal> literal = make_unique<Literal>();
                        literal->token = "false";
                        literal->value = r_constant_value;
-                       iter.condition = literal;
+                       iter.condition = move(literal);
                }
        }
        iteration_var = nullptr;
@@ -1092,19 +1093,19 @@ void ConstantConditionEliminator::visit(Block &block)
        }
 }
 
-void ConstantConditionEliminator::visit(RefPtr<Expression> &expr)
+void ConstantConditionEliminator::visit(NodePtr<Expression> &expr)
 {
        r_ternary_result = nullptr;
        expr->visit(*this);
        if(r_ternary_result)
-               expr = r_ternary_result;
+               expr = move(*r_ternary_result);
        r_ternary_result = nullptr;
 }
 
 void ConstantConditionEliminator::visit(UnaryExpression &unary)
 {
        if(unary.oper->token[1]=='+' || unary.oper->token[1]=='-')
-               if(const VariableReference *var = dynamic_cast<const VariableReference *>(unary.expression.get()))
+               if(const VariableReference *var = unary.expression.get_as<const VariableReference>())
                {
                        auto i = current_block->variables.find(var->name);
                        r_external_side_effects = (i==current_block->variables.end() || i->second!=var->declaration);
@@ -1126,7 +1127,7 @@ void ConstantConditionEliminator::visit(TernaryExpression &ternary)
 {
        ConstantStatus result = check_constant_condition(*ternary.condition);
        if(result!=NOT_CONSTANT)
-               r_ternary_result = (result==CONSTANT_TRUE ? ternary.true_expr : ternary.false_expr);
+               r_ternary_result = (result==CONSTANT_TRUE ? &ternary.true_expr : &ternary.false_expr);
        else
                r_ternary_result = nullptr;
 }
@@ -1224,7 +1225,7 @@ bool UnusedTypeRemover::apply(Stage &stage)
        return !unused_nodes.empty();
 }
 
-void UnusedTypeRemover::visit(RefPtr<Expression> &expr)
+void UnusedTypeRemover::visit(NodePtr<Expression> &expr)
 {
        unused_nodes.erase(expr->type);
        TraversingVisitor::visit(expr);
@@ -1524,7 +1525,7 @@ void UnusedVariableRemover::visit(FunctionDeclaration &func)
 
        /* Always treat function parameters as referenced.  Removing unused
        parameters is not currently supported. */
-       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+       for(const NodePtr<VariableDeclaration> &p: func.parameters)
        {
                auto j = variables.find(p.get());
                if(j!=variables.end())
index 7f885360d78c6c18efad30852da413bb1e745896..d3d475b636cef153ec1f3fa0f2b31c7ae1bf88c5 100644 (file)
@@ -61,7 +61,7 @@ private:
        FunctionDeclaration *source_func = nullptr;
        Block staging_block;
        Pass pass = REFERENCED;
-       RefPtr<Statement> r_inlined_statement;
+       NodePtr<Statement> r_inlined_statement;
        std::set<Node *> dependencies;
        std::set<std::string> referenced_names;
        std::string r_result_name;
@@ -86,7 +86,7 @@ private:
        std::set<FunctionDeclaration *> inlineable;
        FunctionDeclaration *current_function = nullptr;
        NodeList<Statement>::iterator insert_point;
-       RefPtr<Expression> r_inline_result;
+       std::unique_ptr<Expression> r_inline_result;
        bool r_any_inlined = false;
        bool r_inlined_here = false;
 
@@ -94,7 +94,7 @@ public:
        bool apply(Stage &);
 
 private:
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(Block &) override;
        void visit(FunctionCall &) override;
        void visit(FunctionDeclaration &) override;
@@ -111,7 +111,7 @@ private:
 
        struct ExpressionUse
        {
-               RefPtr<Expression> *reference = nullptr;
+               NodePtr<Expression> *reference = nullptr;
                Block *ref_scope = nullptr;
                ExpressionInfo *containing_expr = nullptr;
                bool blocked = false;
@@ -120,7 +120,7 @@ private:
        struct ExpressionInfo
        {
                Assignment::Target target;
-               RefPtr<Expression> expression;
+               const Expression *expression = nullptr;
                Block *assign_scope = nullptr;
                std::vector<ExpressionUse> uses;
                bool trivial = false;
@@ -142,7 +142,7 @@ public:
        bool apply(Stage &);
 
 private:
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(VariableReference &) override;
        void visit(MemberAccess &) override;
        void visit(Swizzle &) override;
@@ -166,8 +166,8 @@ private:
        {
                const VariableDeclaration *declaration = nullptr;
                unsigned index = 0;
-               RefPtr<Expression> initializer;
-               std::vector<RefPtr<Expression> *> references;
+               const NodePtr<Expression> *initializer;
+               std::vector<NodePtr<Expression> *> references;
        };
 
        struct Aggregate
@@ -191,9 +191,9 @@ public:
 
 private:
        void visit(Block &) override;
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(VariableReference &) override;
-       void visit_composite(RefPtr<Expression> &);
+       void visit_composite(NodePtr<Expression> &);
        void visit(MemberAccess &) override;
        void visit(BinaryExpression &) override;
        void visit(StructDeclaration &) override { }
@@ -231,7 +231,7 @@ private:
        void convert_to_result(const Variant &);
        void set_result(const Variant &, bool = false);
 
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(Literal &) override;
        void visit(VariableReference &) override;
        void visit(MemberAccess &) override;
@@ -260,7 +260,7 @@ private:
 
        NodeList<Statement>::iterator insert_point;
        std::set<Node *> nodes_to_remove;
-       RefPtr<Expression> r_ternary_result;
+       NodePtr<Expression> *r_ternary_result;
        bool r_external_side_effects = false;
 
 public:
@@ -270,7 +270,7 @@ private:
        ConstantStatus check_constant_condition(const Expression &);
 
        void visit(Block &) override;
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(UnaryExpression &) override;
        void visit(Assignment &) override;
        void visit(TernaryExpression &) override;
@@ -308,7 +308,7 @@ public:
        bool apply(Stage &);
 
 private:
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void visit(BasicTypeDeclaration &) override;
        void visit(ImageTypeDeclaration &) override;
        void visit(StructDeclaration &) override;
index 2b82ddbcc352510917fe38e2f6cc3c7e102745d8..c6d0a3e2496b404470d2e96e9059c9d83f8b887a 100644 (file)
@@ -91,7 +91,7 @@ void Formatter::visit(Block &block)
        SetForScope<unsigned> set(indent, indent+(indent>0 || use_braces));
        string spaces(indent*2, ' ');
        bool first = true;
-       for(const RefPtr<Statement> &s: block.body)
+       for(const NodePtr<Statement> &s: block.body)
        {
                if(omit_builtin && s->source<=BUILTIN_SOURCE)
                        continue;
index a9962afef93bf042b6af400715bdbf4961097794..b055c5da7783747563dc4ccfc81361220096a911 100644 (file)
@@ -64,14 +64,11 @@ void Parser::parse_source(const string &name, int index)
        tokenizer.begin(source, name);
        allow_stage_change = true;
        while(!tokenizer.peek_token().empty())
-               if(RefPtr<Statement> statement = parse_with_recovery(&Parser::parse_global_declaration))
+               if(unique_ptr<Statement> statement = parse_with_recovery(&Parser::parse_global_declaration))
                {
-                       cur_stage->content.body.push_back(statement);
+                       cur_stage->content.body.push_back(move(statement));
                        if(next_global_declaration)
-                       {
-                               cur_stage->content.body.push_back(next_global_declaration);
-                               next_global_declaration = nullptr;
-                       }
+                               cur_stage->content.body.push_back(move(next_global_declaration));
                }
 
        if(!errors.empty())
@@ -209,16 +206,16 @@ bool Parser::is_identifier(const string &token)
 }
 
 template<typename T>
-RefPtr<T> Parser::create_node()
+unique_ptr<T> Parser::create_node()
 {
-       RefPtr<T> node = new T;
+       unique_ptr<T> node = make_unique<T>();
        node->source = source_index;
        node->line = tokenizer.get_location().line;
        return node;
 }
 
 template<typename T>
-RefPtr<T> Parser::parse_with_recovery(RefPtr<T> (Parser::*parse_func)())
+unique_ptr<T> Parser::parse_with_recovery(unique_ptr<T> (Parser::*parse_func)())
 {
        tokenizer.clear_progress_mark();
        try
@@ -258,10 +255,10 @@ RefPtr<T> Parser::parse_with_recovery(RefPtr<T> (Parser::*parse_func)())
                }
        }
 
-       return RefPtr<T>();
+       return unique_ptr<T>();
 }
 
-RefPtr<Statement> Parser::parse_global_declaration()
+unique_ptr<Statement> Parser::parse_global_declaration()
 {
        string token = tokenizer.peek_token();
        SetFlag disallow(allow_stage_change, false);
@@ -272,11 +269,11 @@ RefPtr<Statement> Parser::parse_global_declaration()
                return parse_precision();
        else if(token=="layout")
        {
-               RefPtr<Layout> layout = parse_layout();
+               unique_ptr<Layout> layout = parse_layout();
                token = tokenizer.peek_token();
                if(is_interface_qualifier(token) && tokenizer.peek_token(1)==";")
                {
-                       RefPtr<InterfaceLayout> iface_lo = create_node<InterfaceLayout>();
+                       unique_ptr<InterfaceLayout> iface_lo = create_node<InterfaceLayout>();
                        iface_lo->layout.source = layout->source;
                        iface_lo->layout.line = layout->line;
                        iface_lo->layout.qualifiers = layout->qualifiers;
@@ -286,16 +283,16 @@ RefPtr<Statement> Parser::parse_global_declaration()
                }
                else if(is_interface_qualifier(token) && tokenizer.peek_token(2)=="{")
                {
-                       RefPtr<StructDeclaration> iface_strct = parse_interface_block();
-                       VariableDeclaration *iface_var = iface_strct->block_declaration;
-                       iface_var->layout = layout;
-                       next_global_declaration = iface_var;
+                       unique_ptr<StructDeclaration> iface_strct = parse_interface_block();
+                       unique_ptr<VariableDeclaration> iface_var = unique_ptr<VariableDeclaration>(iface_strct->block_declaration);
+                       iface_var->layout = move(layout);
+                       next_global_declaration = move(iface_var);
                        return iface_strct;
                }
                else
                {
-                       RefPtr<VariableDeclaration> var = parse_variable_declaration();
-                       var->layout = layout;
+                       unique_ptr<VariableDeclaration> var = parse_variable_declaration();
+                       var->layout = move(layout);
                        return var;
                }
        }
@@ -314,8 +311,8 @@ RefPtr<Statement> Parser::parse_global_declaration()
                }
                else
                {
-                       RefPtr<StructDeclaration> iface_strct = parse_interface_block();
-                       next_global_declaration = iface_strct->block_declaration;
+                       unique_ptr<StructDeclaration> iface_strct = parse_interface_block();
+                       next_global_declaration = unique_ptr<Statement>(iface_strct->block_declaration);
                        return iface_strct;
                }
        }
@@ -336,7 +333,7 @@ RefPtr<Statement> Parser::parse_global_declaration()
                throw parse_error(tokenizer.get_location(), token, "a global declaration");
 }
 
-RefPtr<Statement> Parser::parse_statement()
+unique_ptr<Statement> Parser::parse_statement()
 {
        string token = tokenizer.peek_token();
        if(token=="if")
@@ -351,7 +348,7 @@ RefPtr<Statement> Parser::parse_statement()
                return parse_return();
        else if(token=="break" || token=="continue" || token=="discard")
        {
-               RefPtr<Jump> jump = create_node<Jump>();
+               unique_ptr<Jump> jump = create_node<Jump>();
                jump->keyword = tokenizer.parse_token();
                tokenizer.expect(";");
 
@@ -366,7 +363,7 @@ RefPtr<Statement> Parser::parse_statement()
        }
        else if(!token.empty())
        {
-               RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
+               unique_ptr<ExpressionStatement> expr = create_node<ExpressionStatement>();
                expr->expression = parse_expression();
                tokenizer.expect(";");
 
@@ -376,13 +373,13 @@ RefPtr<Statement> Parser::parse_statement()
                throw parse_error(tokenizer.get_location(), token, "a statement");
 }
 
-RefPtr<Import> Parser::parse_import()
+unique_ptr<Import> Parser::parse_import()
 {
        if(cur_stage->type!=Stage::SHARED)
                throw invalid_shader_source(tokenizer.get_location(), "Imports are only allowed in the shared section");
 
        tokenizer.expect("import");
-       RefPtr<Import> import = create_node<Import>();
+       unique_ptr<Import> import = create_node<Import>();
        import->module = expect_identifier();
        tokenizer.expect(";");
 
@@ -397,10 +394,10 @@ RefPtr<Import> Parser::parse_import()
        return import;
 }
 
-RefPtr<Precision> Parser::parse_precision()
+unique_ptr<Precision> Parser::parse_precision()
 {
        tokenizer.expect("precision");
-       RefPtr<Precision> precision = create_node<Precision>();
+       unique_ptr<Precision> precision = create_node<Precision>();
 
        precision->precision = tokenizer.parse_token();
        if(!is_precision_qualifier(precision->precision))
@@ -414,11 +411,11 @@ RefPtr<Precision> Parser::parse_precision()
        return precision;
 }
 
-RefPtr<Layout> Parser::parse_layout()
+unique_ptr<Layout> Parser::parse_layout()
 {
        tokenizer.expect("layout");
        tokenizer.expect("(");
-       RefPtr<Layout> layout = create_node<Layout>();
+       unique_ptr<Layout> layout = create_node<Layout>();
        while(1)
        {
                string token = tokenizer.parse_token();
@@ -450,7 +447,7 @@ RefPtr<Layout> Parser::parse_layout()
 }
 
 template<typename T>
-void Parser::parse_block(Block &block, bool require_braces, RefPtr<T> (Parser::*parse_content)())
+void Parser::parse_block(Block &block, bool require_braces, unique_ptr<T> (Parser::*parse_content)())
 {
        bool have_braces = (require_braces || tokenizer.peek_token()=="{");
        if(have_braces)
@@ -459,8 +456,8 @@ void Parser::parse_block(Block &block, bool require_braces, RefPtr<T> (Parser::*
        if(have_braces)
        {
                while(tokenizer.peek_token()!="}")
-                       if(RefPtr<Statement> node = parse_with_recovery(parse_content))
-                               block.body.push_back(node);
+                       if(unique_ptr<Statement> node = parse_with_recovery(parse_content))
+                               block.body.push_back(move(node));
        }
        else
                block.body.push_back((this->*parse_content)());
@@ -471,10 +468,10 @@ void Parser::parse_block(Block &block, bool require_braces, RefPtr<T> (Parser::*
                tokenizer.expect("}");
 }
 
-RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
+unique_ptr<Expression> Parser::parse_expression(const Operator *outer_oper)
 {
        unsigned outer_precedence = (outer_oper ? outer_oper->precedence+(outer_oper->assoc==Operator::RIGHT_TO_LEFT) : 20);
-       RefPtr<Expression> left;
+       unique_ptr<Expression> left;
        VariableReference *left_var = nullptr;
        while(1)
        {
@@ -503,25 +500,25 @@ RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
                        }
                        else if(token==".")
                        {
-                               RefPtr<MemberAccess> memacc = create_node<MemberAccess>();
-                               memacc->left = left;
+                               unique_ptr<MemberAccess> memacc = create_node<MemberAccess>();
+                               memacc->left = move(left);
                                memacc->oper = oper;
                                tokenizer.parse_token();
                                memacc->member = expect_identifier();
-                               left = memacc;
+                               left = move(memacc);
                        }
                        else if(oper && oper->type==Operator::POSTFIX)
                        {
-                               RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
+                               unique_ptr<UnaryExpression> unary = create_node<UnaryExpression>();
                                unary->oper = oper;
                                tokenizer.parse_token();
-                               unary->expression = left;
-                               left = unary;
+                               unary->expression = move(left);
+                               left = move(unary);
                        }
                        else if(oper && oper->type==Operator::BINARY)
-                               left = parse_binary(left, *oper);
+                               left = parse_binary(move(left), *oper);
                        else if(oper && oper->type==Operator::TERNARY)
-                               left = parse_ternary(left, *oper);
+                               left = parse_ternary(move(left), *oper);
                        else
                                throw parse_error(tokenizer.get_location(), token, "an operator");
                        left_var = nullptr;
@@ -538,18 +535,18 @@ RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
                                left = parse_literal();
                        else if(is_identifier(token))
                        {
-                               RefPtr<VariableReference> var = create_node<VariableReference>();
+                               unique_ptr<VariableReference> var = create_node<VariableReference>();
                                var->name = expect_identifier();
-                               left = var;
                                left_var = var.get();
+                               left = move(var);
                        }
                        else if(oper && oper->type==Operator::PREFIX)
                        {
-                               RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
+                               unique_ptr<UnaryExpression> unary = create_node<UnaryExpression>();
                                unary->oper = oper;
                                tokenizer.parse_token();
                                unary->expression = parse_expression(oper);
-                               left = unary;
+                               left = move(unary);
                        }
                        else
                                throw parse_error(tokenizer.get_location(), token, "an expression");
@@ -557,9 +554,9 @@ RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
        }
 }
 
-RefPtr<Literal> Parser::parse_literal()
+unique_ptr<Literal> Parser::parse_literal()
 {
-       RefPtr<Literal> literal = create_node<Literal>();
+       unique_ptr<Literal> literal = create_node<Literal>();
        literal->token = tokenizer.parse_token();
        if(isdigit(literal->token[0]))
        {
@@ -581,11 +578,11 @@ RefPtr<Literal> Parser::parse_literal()
        return literal;
 }
 
-RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, const Operator &oper)
+unique_ptr<BinaryExpression> Parser::parse_binary(unique_ptr<Expression> left, const Operator &oper)
 {
-       RefPtr<BinaryExpression> binary = (oper.precedence==16 ?
-               static_cast<RefPtr<BinaryExpression> >(create_node<Assignment>()) : create_node<BinaryExpression>());
-       binary->left = left;
+       unique_ptr<BinaryExpression> binary = (oper.precedence==16 ?
+               static_cast<unique_ptr<BinaryExpression> >(create_node<Assignment>()) : create_node<BinaryExpression>());
+       binary->left = move(left);
        binary->oper = &oper;
        tokenizer.expect(oper.token);
        if(oper.token2[0])
@@ -598,10 +595,10 @@ RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, co
        return binary;
 }
 
-RefPtr<TernaryExpression> Parser::parse_ternary(const RefPtr<Expression> &cond, const Operator &oper)
+unique_ptr<TernaryExpression> Parser::parse_ternary(unique_ptr<Expression> cond, const Operator &oper)
 {
-       RefPtr<TernaryExpression> ternary = create_node<TernaryExpression>();
-       ternary->condition = cond;
+       unique_ptr<TernaryExpression> ternary = create_node<TernaryExpression>();
+       ternary->condition = move(cond);
        ternary->oper = &oper;
        tokenizer.expect("?");
        ternary->true_expr = parse_expression(&oper);
@@ -610,9 +607,9 @@ RefPtr<TernaryExpression> Parser::parse_ternary(const RefPtr<Expression> &cond,
        return ternary;
 }
 
-RefPtr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
+unique_ptr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
 {
-       RefPtr<FunctionCall> call = create_node<FunctionCall>();
+       unique_ptr<FunctionCall> call = create_node<FunctionCall>();
        call->name = var.name;
        call->oper = &Operator::get_operator("(", Operator::POSTFIX);
        tokenizer.expect("(");
@@ -635,11 +632,11 @@ void Parser::add_type(TypeDeclaration &type)
                stage_types.insert(type.name);
 }
 
-RefPtr<TypeDeclaration> Parser::parse_type_declaration()
+unique_ptr<TypeDeclaration> Parser::parse_type_declaration()
 {
        tokenizer.expect("typedef");
 
-       RefPtr<TypeDeclaration> type;
+       unique_ptr<TypeDeclaration> type;
        if(tokenizer.peek_token()=="image")
                type = parse_image_type_declaration();
        else
@@ -650,9 +647,9 @@ RefPtr<TypeDeclaration> Parser::parse_type_declaration()
        return type;
 }
 
-RefPtr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
+unique_ptr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
 {
-       RefPtr<BasicTypeDeclaration> type = create_node<BasicTypeDeclaration>();
+       unique_ptr<BasicTypeDeclaration> type = create_node<BasicTypeDeclaration>();
 
        if(tokenizer.peek_token()=="vector")
        {
@@ -676,12 +673,12 @@ RefPtr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
        return type;
 }
 
-RefPtr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
+unique_ptr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
 {
        tokenizer.expect("image");
        tokenizer.expect("(");
 
-       RefPtr<ImageTypeDeclaration> type = create_node<ImageTypeDeclaration>();
+       unique_ptr<ImageTypeDeclaration> type = create_node<ImageTypeDeclaration>();
        while(1)
        {
                string token = tokenizer.parse_token();
@@ -729,10 +726,10 @@ RefPtr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
        return type;
 }
 
-RefPtr<StructDeclaration> Parser::parse_struct_declaration()
+unique_ptr<StructDeclaration> Parser::parse_struct_declaration()
 {
        tokenizer.expect("struct");
-       RefPtr<StructDeclaration> strct = create_node<StructDeclaration>();
+       unique_ptr<StructDeclaration> strct = create_node<StructDeclaration>();
 
        strct->name = expect_identifier();
        parse_block(strct->members, true, &Parser::parse_variable_declaration);
@@ -742,9 +739,9 @@ RefPtr<StructDeclaration> Parser::parse_struct_declaration()
        return strct;
 }
 
-RefPtr<VariableDeclaration> Parser::parse_variable_declaration()
+unique_ptr<VariableDeclaration> Parser::parse_variable_declaration()
 {
-       RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+       unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
 
        string token = tokenizer.peek_token();
        while(is_qualifier(token))
@@ -783,21 +780,21 @@ RefPtr<VariableDeclaration> Parser::parse_variable_declaration()
        return var;
 }
 
-RefPtr<VariableDeclaration> Parser::parse_variable_declaration_with_layout()
+unique_ptr<VariableDeclaration> Parser::parse_variable_declaration_with_layout()
 {
-       RefPtr<Layout> layout;
+       unique_ptr<Layout> layout;
        if(tokenizer.peek_token()=="layout")
                layout = parse_layout();
 
-       RefPtr<VariableDeclaration> var = parse_variable_declaration();
-       var->layout = layout;
+       unique_ptr<VariableDeclaration> var = parse_variable_declaration();
+       var->layout = move(layout);
 
        return var;
 }
 
-RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
+unique_ptr<FunctionDeclaration> Parser::parse_function_declaration()
 {
-       RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
+       unique_ptr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
 
        func->virtua = check("virtual");
        func->return_type = expect_type();
@@ -808,13 +805,13 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
                if(!func->parameters.empty())
                        tokenizer.expect(",");
 
-               RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+               unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
                string token = tokenizer.peek_token();
                if(token=="in" || token=="out" || token=="inout")
                        var->interface = tokenizer.parse_token();
                var->type = expect_type();
                var->name = expect_identifier();
-               func->parameters.push_back(var);
+               func->parameters.push_back(move(var));
        }
        tokenizer.expect(")");
 
@@ -834,10 +831,10 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
        return func;
 }
 
-RefPtr<StructDeclaration> Parser::parse_interface_block()
+unique_ptr<StructDeclaration> Parser::parse_interface_block()
 {
-       RefPtr<StructDeclaration> strct = create_node<StructDeclaration>();
-       RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+       unique_ptr<StructDeclaration> strct = create_node<StructDeclaration>();
+       unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
 
        var->interface = tokenizer.parse_token();
        if(!is_interface_qualifier(var->interface))
@@ -873,10 +870,10 @@ RefPtr<StructDeclaration> Parser::parse_interface_block()
        return strct;
 }
 
-RefPtr<Conditional> Parser::parse_conditional()
+unique_ptr<Conditional> Parser::parse_conditional()
 {
        tokenizer.expect("if");
-       RefPtr<Conditional> cond = create_node<Conditional>();
+       unique_ptr<Conditional> cond = create_node<Conditional>();
        tokenizer.expect("(");
        cond->condition = parse_expression();
        tokenizer.expect(")");
@@ -893,10 +890,10 @@ RefPtr<Conditional> Parser::parse_conditional()
        return cond;
 }
 
-RefPtr<Iteration> Parser::parse_for()
+unique_ptr<Iteration> Parser::parse_for()
 {
        tokenizer.expect("for");
-       RefPtr<Iteration> loop = create_node<Iteration>();
+       unique_ptr<Iteration> loop = create_node<Iteration>();
        tokenizer.expect("(");
        string token = tokenizer.peek_token();
        if(is_type(token))
@@ -905,9 +902,9 @@ RefPtr<Iteration> Parser::parse_for()
        {
                if(token!=";")
                {
-                       RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
+                       unique_ptr<ExpressionStatement> expr = create_node<ExpressionStatement>();
                        expr->expression = parse_expression();
-                       loop->init_statement = expr;
+                       loop->init_statement = move(expr);
                }
                tokenizer.expect(";");
        }
@@ -923,10 +920,10 @@ RefPtr<Iteration> Parser::parse_for()
        return loop;
 }
 
-RefPtr<Iteration> Parser::parse_while()
+unique_ptr<Iteration> Parser::parse_while()
 {
        tokenizer.expect("while");
-       RefPtr<Iteration> loop = create_node<Iteration>();
+       unique_ptr<Iteration> loop = create_node<Iteration>();
        tokenizer.expect("(");
        loop->condition = parse_expression();
        tokenizer.expect(")");
@@ -936,10 +933,10 @@ RefPtr<Iteration> Parser::parse_while()
        return loop;
 }
 
-RefPtr<Passthrough> Parser::parse_passthrough()
+unique_ptr<Passthrough> Parser::parse_passthrough()
 {
        tokenizer.expect("passthrough");
-       RefPtr<Passthrough> pass = create_node<Passthrough>();
+       unique_ptr<Passthrough> pass = create_node<Passthrough>();
        if(cur_stage->type==Stage::GEOMETRY)
        {
                tokenizer.expect("[");
@@ -950,10 +947,10 @@ RefPtr<Passthrough> Parser::parse_passthrough()
        return pass;
 }
 
-RefPtr<Return> Parser::parse_return()
+unique_ptr<Return> Parser::parse_return()
 {
        tokenizer.expect("return");
-       RefPtr<Return> ret = create_node<Return>();
+       unique_ptr<Return> ret = create_node<Return>();
        if(tokenizer.peek_token()!=";")
                ret->expression = parse_expression();
        tokenizer.expect(";");
index d46afcdc122cfa9bb56e34df980518f5fad015d8..435752322c6525235a49d2090d33c4110ba4efe5 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GL_SL_PARSER_H_
 #define MSP_GL_SL_PARSER_H_
 
+#include <memory>
 #include <set>
 #include <string>
 #include <msp/io/base.h>
@@ -30,7 +31,7 @@ private:
        std::set<std::string> global_types;
        std::set<std::string> stage_types;
        std::vector<std::string> errors;
-       RefPtr<Statement> next_global_declaration;
+       std::unique_ptr<Statement> next_global_declaration;
 
 public:
        Parser(ModuleCache *);
@@ -65,35 +66,35 @@ private:
        void preprocess_stage();
 
        template<typename T>
-       RefPtr<T> create_node();
+       std::unique_ptr<T> create_node();
        template<typename T>
-       RefPtr<T> parse_with_recovery(RefPtr<T> (Parser::*)());
-       RefPtr<Statement> parse_global_declaration();
-       RefPtr<Statement> parse_statement();
-       RefPtr<Import> parse_import();
-       RefPtr<Precision> parse_precision();
-       RefPtr<Layout> parse_layout();
+       std::unique_ptr<T> parse_with_recovery(std::unique_ptr<T> (Parser::*)());
+       std::unique_ptr<Statement> parse_global_declaration();
+       std::unique_ptr<Statement> parse_statement();
+       std::unique_ptr<Import> parse_import();
+       std::unique_ptr<Precision> parse_precision();
+       std::unique_ptr<Layout> parse_layout();
        template<typename T>
-       void parse_block(Block &, bool, RefPtr<T> (Parser::*)());
-       RefPtr<Expression> parse_expression(const Operator * = nullptr);
-       RefPtr<Literal> parse_literal();
-       RefPtr<BinaryExpression> parse_binary(const RefPtr<Expression> &, const Operator &);
-       RefPtr<TernaryExpression> parse_ternary(const RefPtr<Expression> &, const Operator &);
-       RefPtr<FunctionCall> parse_function_call(const VariableReference &);
+       void parse_block(Block &, bool, std::unique_ptr<T> (Parser::*)());
+       std::unique_ptr<Expression> parse_expression(const Operator * = nullptr);
+       std::unique_ptr<Literal> parse_literal();
+       std::unique_ptr<BinaryExpression> parse_binary(std::unique_ptr<Expression>, const Operator &);
+       std::unique_ptr<TernaryExpression> parse_ternary(std::unique_ptr<Expression>, const Operator &);
+       std::unique_ptr<FunctionCall> parse_function_call(const VariableReference &);
        void add_type(TypeDeclaration &);
-       RefPtr<TypeDeclaration> parse_type_declaration();
-       RefPtr<BasicTypeDeclaration> parse_basic_type_declaration();
-       RefPtr<ImageTypeDeclaration> parse_image_type_declaration();
-       RefPtr<StructDeclaration> parse_struct_declaration();
-       RefPtr<VariableDeclaration> parse_variable_declaration();
-       RefPtr<VariableDeclaration> parse_variable_declaration_with_layout();
-       RefPtr<FunctionDeclaration> parse_function_declaration();
-       RefPtr<StructDeclaration> parse_interface_block();
-       RefPtr<Conditional> parse_conditional();
-       RefPtr<Iteration> parse_for();
-       RefPtr<Iteration> parse_while();
-       RefPtr<Passthrough> parse_passthrough();
-       RefPtr<Return> parse_return();
+       std::unique_ptr<TypeDeclaration> parse_type_declaration();
+       std::unique_ptr<BasicTypeDeclaration> parse_basic_type_declaration();
+       std::unique_ptr<ImageTypeDeclaration> parse_image_type_declaration();
+       std::unique_ptr<StructDeclaration> parse_struct_declaration();
+       std::unique_ptr<VariableDeclaration> parse_variable_declaration();
+       std::unique_ptr<VariableDeclaration> parse_variable_declaration_with_layout();
+       std::unique_ptr<FunctionDeclaration> parse_function_declaration();
+       std::unique_ptr<StructDeclaration> parse_interface_block();
+       std::unique_ptr<Conditional> parse_conditional();
+       std::unique_ptr<Iteration> parse_for();
+       std::unique_ptr<Iteration> parse_while();
+       std::unique_ptr<Passthrough> parse_passthrough();
+       std::unique_ptr<Return> parse_return();
 };
 
 } // namespace SL
index c4fba0682f224b5bdd0e00089624b09ec8320e68..702c8536176cb633be5a5afdc3917bb94874748c 100644 (file)
@@ -264,7 +264,7 @@ void LocationCounter::visit(ImageTypeDeclaration &)
 void LocationCounter::visit(StructDeclaration &strct)
 {
        unsigned total = 0;
-       for(const RefPtr<Statement> &s: strct.members.body)
+       for(const NodePtr<Statement> &s: strct.members.body)
        {
                r_count = 1;
                s->visit(*this);
@@ -316,7 +316,7 @@ void MemoryRequirementsCalculator::visit(StructDeclaration &strct)
 {
        unsigned total = 0;
        unsigned max_align = 1;
-       for(const RefPtr<Statement> &s: strct.members.body)
+       for(const NodePtr<Statement> &s: strct.members.body)
        {
                r_size = 0;
                r_alignment = 1;
index c1771ea702ae07ab1ec59aa72bc0bb6b4e19bba9..bd8358803741e7ffe479edad7babb949d3a8e349 100644 (file)
@@ -35,16 +35,18 @@ TypeDeclaration *TypeResolver::get_or_create_array_type(TypeDeclaration &type)
        if(i!=array_types.end())
                return i->second;
 
-       BasicTypeDeclaration *array = new BasicTypeDeclaration;
+       unique_ptr<BasicTypeDeclaration> array = make_unique<BasicTypeDeclaration>();
        array->source = INTERNAL_SOURCE;
        array->name = type.name+"[]";
        array->kind = BasicTypeDeclaration::ARRAY;
        array->extended_alignment = extended_alignment;
        array->base = type.name;
        array->base_type = &type;
-       stage->content.body.insert(type_insert_point, array);
-       array_types[key] = array;
-       return array;
+
+       BasicTypeDeclaration *result = array.get();
+       stage->content.body.insert(type_insert_point, move(array));
+       array_types[key] = result;
+       return result;
 }
 
 TypeDeclaration *TypeResolver::get_or_create_image_type(ImageTypeDeclaration &type, const std::string &texel_format)
@@ -57,14 +59,16 @@ TypeDeclaration *TypeResolver::get_or_create_image_type(ImageTypeDeclaration &ty
        if(i!=image_types.end())
                return i->second;
 
-       ImageTypeDeclaration *image = new ImageTypeDeclaration(type);
+       unique_ptr<ImageTypeDeclaration> image = make_unique<ImageTypeDeclaration>(type);
        image->source = INTERNAL_SOURCE;
        image->name = format("%s_%s", type.name, texel_format);
        image->format = texel_format;
        image->base_image = &type;
-       stage->content.body.insert(type_insert_point, image);
-       image_types[key] = image;
-       return image;
+
+       ImageTypeDeclaration *result = image.get();
+       stage->content.body.insert(type_insert_point, move(image));
+       image_types[key] = result;
+       return result;
 }
 
 void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool array, const Layout *layout)
@@ -204,13 +208,13 @@ void VariableResolver::enter(Block &block)
        block.variables.clear();
 }
 
-void VariableResolver::visit(RefPtr<Expression> &expr)
+void VariableResolver::visit(NodePtr<Expression> &expr)
 {
        r_replacement_expr = nullptr;
        expr->visit(*this);
        if(r_replacement_expr)
        {
-               expr = r_replacement_expr;
+               expr = move(r_replacement_expr);
                /* Don't record assignment target when doing a replacement, because chain
                information won't be correct. */
                r_assignment_target.declaration = nullptr;
@@ -259,19 +263,19 @@ void VariableResolver::visit(VariableReference &var)
                        {
                                /* The name refers a member of an anonymous interface block.  Prepare
                                new syntax tree nodes accordingly. */
-                               VariableReference *iface_ref = new VariableReference;
+                               unique_ptr<VariableReference> iface_ref = make_unique<VariableReference>();
                                iface_ref->name = kvp.first;
                                iface_ref->source = var.source;
                                iface_ref->line = var.line;
                                iface_ref->declaration = kvp.second;
 
-                               MemberAccess *memacc = new MemberAccess;
+                               unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
                                memacc->source = var.source;
                                memacc->line = var.line;
-                               memacc->left = iface_ref;
+                               memacc->left = move(iface_ref);
                                memacc->member = var.name;
 
-                               r_replacement_expr = memacc;
+                               r_replacement_expr = move(memacc);
                                break;
                        }
        }
@@ -317,15 +321,15 @@ void VariableResolver::visit(MemberAccess &memacc)
 
                        if(ok)
                        {
-                               Swizzle *swizzle = new Swizzle;
+                               unique_ptr<Swizzle> swizzle = make_unique<Swizzle>();
                                swizzle->source = memacc.source;
                                swizzle->line = memacc.line;
                                swizzle->oper = memacc.oper;
-                               swizzle->left = memacc.left;
+                               swizzle->left = move(memacc.left);
                                swizzle->component_group = memacc.member;
                                swizzle->count = memacc.member.size();
                                copy(components, components+memacc.member.size(), swizzle->components);
-                               r_replacement_expr = swizzle;
+                               r_replacement_expr = move(swizzle);
                        }
                }
        }
@@ -410,10 +414,10 @@ void VariableResolver::redeclare_builtin(VariableDeclaration &existing, Variable
                if(existing.layout)
                        merge_layouts(*existing.layout, *var.layout);
                else
-                       existing.layout = var.layout;
+                       existing.layout = var.layout.clone();
        }
        if(var.array_size)
-               existing.array_size = var.array_size;
+               existing.array_size = var.array_size.clone();
 
        redeclared_builtins.push_back(&existing);
 }
@@ -500,7 +504,7 @@ void VariableResolver::visit(VariableDeclaration &var)
                }
                else if(existing->array && !existing->array_size && var.type==existing->type && !var.layout && !var.init_expression)
                {
-                       existing->array_size = var.array_size;
+                       existing->array_size = move(var.array_size);
                        nodes_to_remove.insert(&var);
                        r_any_resolved = true;
                }
@@ -542,17 +546,17 @@ BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration &elem_t
        return (i!=basic_types.end() ? *i : 0);
 }
 
-void ExpressionResolver::convert_to(RefPtr<Expression> &expr, BasicTypeDeclaration &type)
+void ExpressionResolver::convert_to(NodePtr<Expression> &expr, BasicTypeDeclaration &type)
 {
-       RefPtr<FunctionCall> call = new FunctionCall;
+       unique_ptr<FunctionCall> call = make_unique<FunctionCall>();
        call->name = type.name;
        call->constructor = true;
-       call->arguments.push_back_nocopy(expr);
+       call->arguments.push_back(move(expr));
        call->type = &type;
-       expr = call;
+       expr = move(call);
 }
 
-bool ExpressionResolver::convert_to_element(RefPtr<Expression> &expr, BasicTypeDeclaration &elem_type)
+bool ExpressionResolver::convert_to_element(NodePtr<Expression> &expr, BasicTypeDeclaration &elem_type)
 {
        if(BasicTypeDeclaration *expr_basic = dynamic_cast<BasicTypeDeclaration *>(expr->type))
        {
@@ -569,13 +573,13 @@ bool ExpressionResolver::convert_to_element(RefPtr<Expression> &expr, BasicTypeD
        return false;
 }
 
-bool ExpressionResolver::truncate_vector(RefPtr<Expression> &expr, unsigned size)
+bool ExpressionResolver::truncate_vector(NodePtr<Expression> &expr, unsigned size)
 {
        if(BasicTypeDeclaration *expr_basic = dynamic_cast<BasicTypeDeclaration *>(expr->type))
                if(BasicTypeDeclaration *expr_elem = get_element_type(*expr_basic))
                {
-                       RefPtr<Swizzle> swizzle = new Swizzle;
-                       swizzle->left = expr;
+                       unique_ptr<Swizzle> swizzle = make_unique<Swizzle>();
+                       swizzle->left = move(expr);
                        swizzle->oper = &Operator::get_operator(".", Operator::POSTFIX);
                        swizzle->component_group = string("xyzw", size);
                        swizzle->count = size;
@@ -585,7 +589,7 @@ bool ExpressionResolver::truncate_vector(RefPtr<Expression> &expr, unsigned size
                                swizzle->type = expr_elem;
                        else
                                swizzle->type = find_type(*expr_elem, BasicTypeDeclaration::VECTOR, size);
-                       expr = swizzle;
+                       expr = move(swizzle);
 
                        return true;
                }
@@ -921,7 +925,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                unsigned arg_component_total = 0;
                bool homogeneous_args = true;
                bool has_matrices = false;
-               for(const RefPtr<Expression> &a: call.arguments)
+               for(const NodePtr<Expression> &a: call.arguments)
                {
                        ArgumentInfo info;
                        if(!(info.type=dynamic_cast<BasicTypeDeclaration *>(a->type)))
@@ -978,7 +982,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                        unsigned column_count = basic->size&0xFFFF;
                        unsigned row_count = basic->size>>16;
 
-                       vector<RefPtr<Expression> > columns;
+                       NodeArray<Expression> columns;
                        columns.reserve(column_count);
                        bool changed_columns = false;
 
@@ -997,29 +1001,30 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
 
                                        /* Always generate a temporary here and let the optimization
                                        stage inline it if that's reasonable. */
-                                       RefPtr<VariableDeclaration> temporary = new VariableDeclaration;
+                                       unique_ptr<VariableDeclaration> temporary = make_unique<VariableDeclaration>();
                                        temporary->type = args.front().type->name;
                                        temporary->name = get_unused_variable_name(*current_block, "_temp");
-                                       temporary->init_expression = call.arguments.front();
-                                       current_block->body.insert(insert_point, temporary);
+                                       temporary->init_expression = move(call.arguments.front());
+                                       string temp_name = temporary->name;
+                                       current_block->body.insert(insert_point, move(temporary));
 
                                        // Create expressions to build each column.
                                        for(unsigned j=0; j<column_count; ++j)
                                        {
-                                               RefPtr<VariableReference> ref = new VariableReference;
-                                               ref->name = temporary->name;
+                                               unique_ptr<VariableReference> ref = make_unique<VariableReference>();
+                                               ref->name = temp_name;
 
-                                               RefPtr<Literal> index = new Literal;
+                                               unique_ptr<Literal> index = make_unique<Literal>();
                                                index->token = lexical_cast<string>(j);
                                                index->value = static_cast<int>(j);
 
-                                               RefPtr<BinaryExpression> subscript = new BinaryExpression;
-                                               subscript->left = ref;
+                                               unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+                                               subscript->left = move(ref);
                                                subscript->oper = &Operator::get_operator("[", Operator::BINARY);
-                                               subscript->right = index;
+                                               subscript->right = move(index);
                                                subscript->type = args.front().type->base_type;
 
-                                               columns.push_back(subscript);
+                                               columns.push_back(move(subscript));
                                                if(arg_rows>row_count)
                                                        truncate_vector(columns.back(), row_count);
                                        }
@@ -1051,7 +1056,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                                                return;
                                }
 
-                               vector<RefPtr<Expression> > column_args;
+                               NodeArray<Expression> column_args;
                                column_args.reserve(row_count);
 
                                column_component_count = 0;
@@ -1061,25 +1066,24 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                                        if(!column_component_count && info.component_count==row_count)
                                        {
                                                // A vector filling the entire column can be used as is.
-                                               columns.push_back(call.arguments[j]);
+                                               columns.push_back(move(call.arguments[j]));
                                                convert_args = true;
                                        }
                                        else
                                        {
-                                               column_args.push_back(call.arguments[j]);
+                                               column_args.push_back(move(call.arguments[j]));
                                                column_component_count += info.component_count;
                                                if(column_component_count==row_count)
                                                {
                                                        /* The column has filled up.  Create a vector constructor
                                                        for it.*/
-                                                       RefPtr<FunctionCall> column_call = new FunctionCall;
+                                                       unique_ptr<FunctionCall> column_call = make_unique<FunctionCall>();
                                                        column_call->name = basic->base_type->name;
                                                        column_call->constructor = true;
-                                                       column_call->arguments.resize(column_args.size());
-                                                       copy(column_args.begin(), column_args.end(), column_call->arguments.begin());
+                                                       column_call->arguments = move(column_args);
                                                        column_call->type = basic->base_type;
                                                        visit_constructor(*column_call);
-                                                       columns.push_back(column_call);
+                                                       columns.push_back(move(column_call));
 
                                                        column_args.clear();
                                                        column_component_count = 0;
@@ -1094,8 +1098,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
 
                        if(changed_columns)
                        {
-                               call.arguments.resize(column_count);
-                               copy(columns.begin(), columns.end(), call.arguments.begin());
+                               call.arguments = move(columns);
 
                                /* Let VariableResolver process the new nodes and finish
                                resolving the constructor on the next pass. */
@@ -1109,7 +1112,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                if(convert_args)
                {
                        // The argument list may have changed so can't rely on args.
-                       for(RefPtr<Expression> &a: call.arguments)
+                       for(NodePtr<Expression> &a: call.arguments)
                                if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>(a->type))
                                {
                                        BasicTypeDeclaration *elem_arg = get_element_type(*basic_arg);
@@ -1124,7 +1127,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                        return;
 
                auto j = call.arguments.begin();
-               for(const RefPtr<Statement> &s: strct->members.body)
+               for(const NodePtr<Statement> &s: strct->members.body)
                {
                        if(VariableDeclaration *var = dynamic_cast<VariableDeclaration *>(s.get()))
                        {
@@ -1310,7 +1313,7 @@ void FunctionResolver::visit(FunctionDeclaration &func)
        if(func.signature.empty())
        {
                string param_types;
-               for(const RefPtr<VariableDeclaration> &p: func.parameters)
+               for(const NodePtr<VariableDeclaration> &p: func.parameters)
                {
                        if(p->type_declaration)
                                append(param_types, ",", p->type_declaration->name);
index 5cb77c19e7c0e4551105d71dff0c24f1bd2e41cd..563c1a573766c52e8139608a5066823d6716e5d8 100644 (file)
@@ -57,7 +57,7 @@ class VariableResolver: private TraversingVisitor
 {
 private:
        Stage *stage = nullptr;
-       RefPtr<Expression> r_replacement_expr;
+       std::unique_ptr<Expression> r_replacement_expr;
        bool r_any_resolved = false;
        bool record_target = false;
        bool r_self_referencing = false;
@@ -70,7 +70,7 @@ public:
 
 private:
        void enter(Block &) override;
-       void visit(RefPtr<Expression> &) override;
+       void visit(NodePtr<Expression> &) override;
        void check_assignment_target(VariableDeclaration *);
        void visit(VariableReference &) override;
        void visit(MemberAccess &) override;
@@ -113,9 +113,9 @@ private:
        static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
        BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned, bool = true);
        BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
-       void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
-       bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
-       bool truncate_vector(RefPtr<Expression> &, unsigned);
+       void convert_to(NodePtr<Expression> &, BasicTypeDeclaration &);
+       bool convert_to_element(NodePtr<Expression> &, BasicTypeDeclaration &);
+       bool truncate_vector(NodePtr<Expression> &, unsigned);
        void resolve(Expression &, TypeDeclaration *, bool);
 
        void visit(Block &) override;
index ce8da1ed285a333994bf346569cbf507cc75875c..3f4559c348736606c5d87c6783c5cbfca733162e 100644 (file)
@@ -557,7 +557,7 @@ SpirVGenerator::Id SpirVGenerator::write_construct(Id type_id, const Id *elem_id
 
 void SpirVGenerator::visit(Block &block)
 {
-       for(const RefPtr<Statement> &s: block.body)
+       for(const NodePtr<Statement> &s: block.body)
                s->visit(*this);
 }
 
@@ -1133,7 +1133,7 @@ void SpirVGenerator::visit(FunctionCall &call)
        vector<Id> argument_ids;
        argument_ids.reserve(call.arguments.size());
        bool all_args_const = true;
-       for(const RefPtr<Expression> &a: call.arguments)
+       for(const NodePtr<Expression> &a: call.arguments)
        {
                a->visit(*this);
                argument_ids.push_back(r_expression_result_id);
@@ -1151,7 +1151,7 @@ void SpirVGenerator::visit(FunctionCall &call)
        else if(call.declaration->source==BUILTIN_SOURCE)
        {
                string arg_types;
-               for(const RefPtr<Expression> &a: call.arguments)
+               for(const NodePtr<Expression> &a: call.arguments)
                        if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>(a->type))
                        {
                                BasicTypeDeclaration &elem_arg = *get_element_type(*basic_arg);
@@ -1655,7 +1655,7 @@ void SpirVGenerator::visit(StructDeclaration &strct)
        bool builtin = !strct.block_name.compare(0, 3, "gl_");
        vector<Id> member_type_ids;
        member_type_ids.reserve(strct.members.body.size());
-       for(const RefPtr<Statement> &s: strct.members.body)
+       for(const NodePtr<Statement> &s: strct.members.body)
        {
                const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(s.get());
                if(!var)
@@ -1925,7 +1925,7 @@ void SpirVGenerator::visit(FunctionDeclaration &func)
        Id return_type_id = get_id(*func.return_type_declaration);
        vector<unsigned> param_type_ids;
        param_type_ids.reserve(func.parameters.size());
-       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+       for(const NodePtr<VariableDeclaration> &p: func.parameters)
                param_type_ids.push_back(get_variable_type_id(*p));
 
        string sig_with_return = func.return_type+func.signature;
index f69c70bf2f099c4c7e8d17715bb5389fc4ad964b..4c3d468c30b954c67901a50282a4f52489fd3933 100644 (file)
@@ -66,15 +66,6 @@ const Operator &Operator::get_operator(const string &token, Type type)
 }
 
 
-template<typename C>
-NodeContainer<C>::NodeContainer(const NodeContainer &c):
-       C(c)
-{
-       for(auto &i: *this)
-               i = i->clone();
-}
-
-
 Block::Block(const Block &other):
        Node(other),
        body(other.body),
@@ -391,10 +382,10 @@ int get_layout_value(const Layout *layout, const string &name, int def_value)
        return (i!=layout->qualifiers.end() ? i->value : def_value);
 }
 
-void add_layout_qualifier(RefPtr<Layout> &layout, const Layout::Qualifier &q)
+void add_layout_qualifier(NodePtr<Layout> &layout, const Layout::Qualifier &q)
 {
        if(!layout)
-               layout = new Layout;
+               layout = make_unique<Layout>();
        layout->qualifiers.push_back(q);
 }
 
index 03c5b80d36d6e859fed683e082f2016b2aa45a4f..61083dee02a0c941c07786ae5bd7706e7cd1c33c 100644 (file)
@@ -3,11 +3,11 @@
 
 #include <list>
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
 #include <cstdint>
-#include <msp/core/refptr.h>
 #include <msp/core/variant.h>
 #include <msp/gl/mspgl_api.h>
 #include "features.h"
@@ -76,42 +76,99 @@ public:
 };
 
 template<typename T>
-class NodePtr: public RefPtr<T>
+class NodePtr
 {
+       template<typename U>
+       friend class NodePtr;
+
+private:
+       std::unique_ptr<T> ptr;
+
 public:
        NodePtr() = default;
-       NodePtr(T *p): RefPtr<T>(p) { }
-       NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : nullptr) { }
-       NodePtr &operator=(const NodePtr &p) = default;
+       NodePtr(const NodePtr &p): ptr(p ? p->clone() : nullptr) { }
+       NodePtr(NodePtr &&) = default;
+       NodePtr &operator=(NodePtr &&) = default;
+       NodePtr &operator=(nullptr_t) { ptr = nullptr; return *this; }
 
        template<typename U>
-       NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
+       NodePtr(NodePtr<U> &&p): ptr(std::move(p.ptr)) { }
 
        template<typename U>
-       NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
+       NodePtr(std::unique_ptr<U> &&p): ptr(std::move(p)) { }
+
+       template<typename U>
+       NodePtr &operator=(std::unique_ptr<U> &&p) { ptr = std::move(p); return *this; }
+
+       template<typename U>
+       U *get_as() const { return dynamic_cast<U *>(ptr.get()); }
+
+       T *get() const { return ptr.get(); }
+       T *operator->() const { return ptr.get(); }
+       T &operator*() const { return *ptr; }
+
+       explicit operator bool() const { return static_cast<bool>(ptr); }
+
+       std::unique_ptr<T> clone() const { return std::unique_ptr<T>(ptr ? ptr->clone() : nullptr); }
 };
 
 template<typename C>
-class NodeContainer: public C
+class NodeContainer
 {
 public:
-       NodeContainer() = default;
-       NodeContainer(const NodeContainer &);
+       using size_type = typename C::size_type;
+       using value_type = typename C::value_type;
+       using iterator = typename C::iterator;
+       using const_iterator = typename C::const_iterator;
+
+protected:
+       C container;
+
+public:
+       size_type size() const { return container.size(); }
+       bool empty() const { return container.empty(); }
+
+       iterator begin() { return container.begin(); }
+       iterator end() { return container.end(); }
+       const_iterator begin() const { return container.begin(); }
+       const_iterator end() const { return container.end(); }
+       const_iterator cbegin() const { return container.begin(); }
+       const_iterator cend() const { return container.end(); }
 
-       void push_back_nocopy(const typename C::value_type &v)
-       { C::push_back(0); C::back() = v; }
+       value_type &front() { return container.front(); }
+       const value_type &front() const { return container.front(); }
+       value_type &back() { return container.back(); }
+       const value_type &back() const { return container.back(); }
 
-       void insert_nocopy(typename C::iterator i, const typename C::value_type &v)
-       { i = C::insert(i, 0); *i = v; }
+       void push_back(value_type &&v) { container.push_back(std::move(v)); }
+       iterator insert(iterator i, value_type &&v) { return container.insert(i, std::move(v)); }
+       iterator erase(iterator i) { return container.erase(i); }
+       void clear() { container.clear(); }
 };
 
 template<typename T>
-class NodeList: public NodeContainer<std::list<RefPtr<T> > >
-{ };
+class NodeList: public NodeContainer<std::list<NodePtr<T>>>
+{
+private:
+       using Base = NodeContainer<std::list<NodePtr<T>>>;
+
+public:
+       void splice(typename Base::iterator i, NodeList &l) { this->container.splice(i, l.container); }
+       void splice(typename Base::iterator i, NodeList &l, typename Base::iterator j) { this->container.splice(i, l.container, j); }
+};
 
 template<typename T>
-class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
-{ };
+class NodeArray: public NodeContainer<std::vector<NodePtr<T>>>
+{
+private:
+       using Base = NodeContainer<std::vector<NodePtr<T>>>;
+
+public:
+       typename Base::value_type &operator[](std::size_t i) { return this->container[i]; }
+       const typename Base::value_type &operator[](std::size_t i) const { return this->container[i]; }
+
+       void reserve(typename Base::size_type s) { this->container.reserve(s); }
+};
 
 struct TypeDeclaration;
 struct VariableDeclaration;
@@ -531,7 +588,7 @@ std::string get_unused_variable_name(const Block &, const std::string &);
 TypeDeclaration *get_ultimate_base_type(TypeDeclaration *);
 bool has_layout_qualifier(const Layout *, const std::string &);
 int get_layout_value(const Layout *, const std::string &, int = -1);
-void add_layout_qualifier(RefPtr<Layout> &, const Layout::Qualifier &);
+void add_layout_qualifier(NodePtr<Layout> &, const Layout::Qualifier &);
 void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
 bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
 
index f4dd42ac42f011af9b77c79266534e256b93c084..3a438a774b29d5bd3cd797bc0f378389db94fea3 100644 (file)
@@ -418,7 +418,7 @@ void DeclarationValidator::visit(VariableDeclaration &var)
 void DeclarationValidator::visit(FunctionDeclaration &func)
 {
        SetForScope<ScopeType> set_scope(scope, FUNCTION_PARAM);
-       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+       for(const NodePtr<VariableDeclaration> &p: func.parameters)
                p->visit(*this);
        scope = FUNCTION;
        func.body.visit(*this);
@@ -810,7 +810,7 @@ void ExpressionValidator::visit(Return &ret)
 
 void FlowControlValidator::visit(Block &block)
 {
-       for(const RefPtr<Statement> &s: block.body)
+       for(const NodePtr<Statement> &s: block.body)
        {
                if(!reachable)
                {
index d3a08d8d60c70439b74162ec2d6c79f0d6f06aec..0bb13c623333fe95aa15d9122db595453f093dc3 100644 (file)
@@ -12,11 +12,11 @@ void TraversingVisitor::visit(Block &block)
        if(&block!=current_block)
                enter(block);
        SetForScope<Block *> set_block(current_block, &block);
-       for(const RefPtr<Statement> &s: block.body)
+       for(const NodePtr<Statement> &s: block.body)
                s->visit(*this);
 }
 
-void TraversingVisitor::visit(RefPtr<Expression> &expr)
+void TraversingVisitor::visit(NodePtr<Expression> &expr)
 {
        expr->visit(*this);
 }
@@ -57,7 +57,7 @@ void TraversingVisitor::visit(TernaryExpression &ternary)
 
 void TraversingVisitor::visit(FunctionCall &call)
 {
-       for(RefPtr<Expression> &a: call.arguments)
+       for(NodePtr<Expression> &a: call.arguments)
                visit(a);
 }
 
@@ -90,7 +90,7 @@ void TraversingVisitor::visit(FunctionDeclaration &func)
 {
        enter(func.body);
        SetForScope<Block *> set_block(current_block, &func.body);
-       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+       for(const NodePtr<VariableDeclaration> &p: func.parameters)
                p->visit(*this);
        func.body.visit(*this);
 }
index 7cd5cb616ca74629824f8b0ad63aefd72aecb489..7833914d1c90a6739927905b607a8c66ef71067b 100644 (file)
@@ -55,7 +55,7 @@ protected:
 public:
        virtual void enter(Block &) { }
        void visit(Block &) override;
-       virtual void visit(RefPtr<Expression> &);
+       virtual void visit(NodePtr<Expression> &);
        void visit(MemberAccess &) override;
        void visit(Swizzle &) override;
        void visit(UnaryExpression &) override;