Move the ast node ownership from Context to Module

Fixes: tint:335
Change-Id: I128e229daa56d43e7227ecab72269be33b3ee012
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33240
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-11-18 20:58:20 +00:00 committed by Commit Bot service account
parent 627732c408
commit 2f4096b0d7
23 changed files with 85 additions and 82 deletions

View File

@ -25,7 +25,8 @@ TypesBuilder::TypesBuilder(TypeManager* tm)
void_(tm->Get<ast::type::VoidType>()), void_(tm->Get<ast::type::VoidType>()),
tm_(tm) {} tm_(tm) {}
Builder::Builder(tint::Context* c) : ctx(c), ty(&c->type_mgr()) {} Builder::Builder(tint::Context* c, tint::ast::Module* m)
: ctx(c), mod(m), ty(&c->type_mgr()) {}
Builder::~Builder() = default; Builder::~Builder() = default;
ast::Variable* Builder::Var(const std::string& name, ast::Variable* Builder::Var(const std::string& name,
@ -36,9 +37,11 @@ ast::Variable* Builder::Var(const std::string& name,
return var; return var;
} }
BuilderWithContext::BuilderWithContext() : Builder(new Context()) {} BuilderWithContextAndModule::BuilderWithContextAndModule()
BuilderWithContext::~BuilderWithContext() { : Builder(new Context(), new ast::Module()) {}
BuilderWithContextAndModule::~BuilderWithContextAndModule() {
delete ctx; delete ctx;
delete mod;
} }
} // namespace ast } // namespace ast

View File

@ -24,6 +24,7 @@
#include "src/ast/expression.h" #include "src/ast/expression.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h" #include "src/ast/sint_literal.h"
#include "src/ast/type/array_type.h" #include "src/ast/type/array_type.h"
@ -185,7 +186,8 @@ class Builder {
/// Constructor /// Constructor
/// @param ctx the context to use in the builder /// @param ctx the context to use in the builder
explicit Builder(tint::Context* ctx); /// @param mod the module to use in the builder
explicit Builder(tint::Context* ctx, tint::ast::Module* mod);
virtual ~Builder(); virtual ~Builder();
/// @param expr the expression /// @param expr the expression
@ -441,17 +443,19 @@ class Builder {
ExprList(std::forward<ARGS>(args)...)}; ExprList(std::forward<ARGS>(args)...)};
} }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx->create<T>(std::forward<ARGS>(args)...); return mod->create<T>(std::forward<ARGS>(args)...);
} }
/// The builder context /// The builder module
tint::Context* const ctx; tint::Context* const ctx;
/// The builder module
tint::ast::Module* const mod;
/// The builder types /// The builder types
const TypesBuilder ty; const TypesBuilder ty;
@ -460,11 +464,12 @@ class Builder {
virtual void OnVariableBuilt(ast::Variable*) {} virtual void OnVariableBuilt(ast::Variable*) {}
}; };
/// BuilderWithContext is a `Builder` that constructs and owns its `Context`. /// BuilderWithContextAndModule is a `Builder` that constructs and owns its
class BuilderWithContext : public Builder { /// `Context` and `Module`.
class BuilderWithContextAndModule : public Builder {
public: public:
BuilderWithContext(); BuilderWithContextAndModule();
~BuilderWithContext() override; ~BuilderWithContextAndModule() override;
}; };
//! @cond Doxygen_Suppress //! @cond Doxygen_Suppress

View File

@ -77,6 +77,20 @@ class Module {
/// @returns a string representation of the module /// @returns a string representation of the module
std::string to_str() const; std::string to_str() const;
/// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor
/// @returns the node pointer
template <typename T, typename... ARGS>
T* create(ARGS&&... args) {
static_assert(std::is_base_of<ast::Node, T>::value,
"T does not derive from ast::Node");
auto uptr = std::make_unique<T>(std::forward<ARGS>(args)...);
auto ptr = uptr.get();
ast_nodes_.emplace_back(std::move(uptr));
return ptr;
}
private: private:
Module(const Module&) = delete; Module(const Module&) = delete;
@ -84,6 +98,7 @@ class Module {
// The constructed types are owned by the type manager // The constructed types are owned by the type manager
std::vector<type::Type*> constructed_types_; std::vector<type::Type*> constructed_types_;
FunctionList functions_; FunctionList functions_;
std::vector<std::unique_ptr<ast::Node>> ast_nodes_;
}; };
} // namespace ast } // namespace ast

View File

@ -19,7 +19,7 @@
#include <utility> #include <utility>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/context.h" #include "src/ast/module.h"
namespace tint { namespace tint {
namespace ast { namespace ast {
@ -31,17 +31,17 @@ class TestHelperBase : public BASE {
TestHelperBase() {} TestHelperBase() {}
~TestHelperBase() = default; ~TestHelperBase() = default;
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx.create<T>(std::forward<ARGS>(args)...); return mod.create<T>(std::forward<ARGS>(args)...);
} }
/// The context /// The module
Context ctx; Module mod;
}; };
using TestHelper = TestHelperBase<testing::Test>; using TestHelper = TestHelperBase<testing::Test>;

View File

@ -51,24 +51,9 @@ class Context {
/// @returns the namer object /// @returns the namer object
Namer* namer() const { return namer_.get(); } Namer* namer() const { return namer_.get(); }
/// Creates a new `ast::Node` owned by the Context. When the Context is
/// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor
/// @returns the node pointer
template <typename T, typename... ARGS>
T* create(ARGS&&... args) {
static_assert(std::is_base_of<ast::Node, T>::value,
"T does not derive from ast::Node");
auto uptr = std::make_unique<T>(std::forward<ARGS>(args)...);
auto ptr = uptr.get();
ast_nodes_.emplace_back(std::move(uptr));
return ptr;
}
private: private:
TypeManager type_mgr_; TypeManager type_mgr_;
std::unique_ptr<Namer> namer_; std::unique_ptr<Namer> namer_;
std::vector<std::unique_ptr<ast::Node>> ast_nodes_;
}; };
} // namespace tint } // namespace tint

View File

@ -635,13 +635,13 @@ class InspectorHelper {
return &comparison_sampler_type_; return &comparison_sampler_type_;
} }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return mod_.create<T>(std::forward<ARGS>(args)...);
} }
private: private:

View File

@ -59,15 +59,6 @@ class Reader {
/// @param diags the list of diagnostic messages /// @param diags the list of diagnostic messages
void set_diagnostics(const diag::List& diags) { diags_ = diags; } void set_diagnostics(const diag::List& diags) { diags_ = diags; }
/// Creates a new `ast::Node` owned by the Context. When the Context is
/// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor
/// @returns the node pointer
template <typename T, typename... ARGS>
T* create(ARGS&&... args) const {
return ctx_.create<T>(std::forward<ARGS>(args)...);
}
/// The Tint context object /// The Tint context object
Context& ctx_; Context& ctx_;

View File

@ -797,14 +797,13 @@ class FunctionEmitter {
/// @returns a boolean false expression. /// @returns a boolean false expression.
ast::Expression* MakeFalse() const; ast::Expression* MakeFalse() const;
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) const { T* create(ARGS&&... args) const {
auto& ctx = parser_impl_.context(); return ast_module_.create<T>(std::forward<ARGS>(args)...);
return ctx.create<T>(std::forward<ARGS>(args)...);
} }
ParserImpl& parser_impl_; ParserImpl& parser_impl_;

View File

@ -450,6 +450,15 @@ class ParserImpl : Reader {
bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type, bool ApplyArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
ast::type::ArrayType* ast_type); ast::type::ArrayType* ast_type);
/// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor
/// @returns the node pointer
template <typename T, typename... ARGS>
T* create(ARGS&&... args) {
return ast_module_.create<T>(std::forward<ARGS>(args)...);
}
// The SPIR-V binary we're parsing // The SPIR-V binary we're parsing
std::vector<uint32_t> spv_binary_; std::vector<uint32_t> spv_binary_;

View File

@ -734,13 +734,13 @@ class ParserImpl {
Maybe<ast::Statement*> for_header_initializer(); Maybe<ast::Statement*> for_header_initializer();
Maybe<ast::Statement*> for_header_continuing(); Maybe<ast::Statement*> for_header_continuing();
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return module_.create<T>(std::forward<ARGS>(args)...);
} }
Context& ctx_; Context& ctx_;

View File

@ -76,7 +76,6 @@ class ParserImplTestWithParam : public testing::TestWithParam<T> {
private: private:
std::vector<std::unique_ptr<Source::File>> files_; std::vector<std::unique_ptr<Source::File>> files_;
std::unique_ptr<ParserImpl> impl;
Context ctx_; Context ctx_;
}; };

View File

@ -76,13 +76,13 @@ class BoundArrayAccessorsTest : public testing::Test {
Manager* manager() { return manager_.get(); } Manager* manager() { return manager_.get(); }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return mod_.create<T>(std::forward<ARGS>(args)...);
} }
private: private:

View File

@ -44,13 +44,13 @@ class Transformer {
const std::string& error() { return error_; } const std::string& error() { return error_; }
protected: protected:
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_->create<T>(std::forward<ARGS>(args)...); return mod_->create<T>(std::forward<ARGS>(args)...);
} }
/// The context /// The context

View File

@ -86,13 +86,13 @@ class VertexPullingTransformHelper {
Manager* manager() { return manager_.get(); } Manager* manager() { return manager_.get(); }
VertexPullingTransform* transform() { return transform_; } VertexPullingTransform* transform() { return transform_; }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return mod_->create<T>(std::forward<ARGS>(args)...);
} }
private: private:

View File

@ -88,13 +88,13 @@ class TypeDeterminerHelper {
ast::Module* mod() { return &mod_; } ast::Module* mod() { return &mod_; }
Context* ctx() { return &ctx_; } Context* ctx() { return &ctx_; }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return mod_.create<T>(std::forward<ARGS>(args)...);
} }
private: private:

View File

@ -41,13 +41,13 @@ class ValidatorTestHelper {
/// @return a pointer to the test module /// @return a pointer to the test module
ast::Module* mod() { return &mod_; } ast::Module* mod() { return &mod_; }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx_.create<T>(std::forward<ARGS>(args)...); return mod_.create<T>(std::forward<ARGS>(args)...);
} }
private: private:

View File

@ -43,13 +43,13 @@ class TestHelperBase : public BODY {
/// @returns the pre result string /// @returns the pre result string
std::string pre_result() const { return pre.str(); } std::string pre_result() const { return pre.str(); }
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer template <typename T, typename... ARGS> /// @returns the node pointer template <typename T, typename... ARGS>
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx.create<T>(std::forward<ARGS>(args)...); return mod.create<T>(std::forward<ARGS>(args)...);
} }
/// The context /// The context

View File

@ -35,13 +35,13 @@ class TestHelperBase : public BASE {
TestHelperBase() : td(&ctx, &mod), gen(&ctx, &mod) {} TestHelperBase() : td(&ctx, &mod), gen(&ctx, &mod) {}
~TestHelperBase() = default; ~TestHelperBase() = default;
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx.create<T>(std::forward<ARGS>(args)...); return mod.create<T>(std::forward<ARGS>(args)...);
} }
/// The context /// The context

View File

@ -105,9 +105,9 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
mod.AddGlobalVariable(v_in); mod->AddGlobalVariable(v_in);
mod.AddGlobalVariable(v_out); mod->AddGlobalVariable(v_out);
mod.AddGlobalVariable(v_wg); mod->AddGlobalVariable(v_wg);
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "tint_6d795f696e" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "tint_6d795f696e"
@ -168,9 +168,9 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_wg)) << b.error();
mod.AddGlobalVariable(v_in); mod->AddGlobalVariable(v_in);
mod.AddGlobalVariable(v_out); mod->AddGlobalVariable(v_out);
mod.AddGlobalVariable(v_wg); mod->AddGlobalVariable(v_wg);
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "tint_6d795f696e" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "tint_6d795f696e"

View File

@ -252,10 +252,10 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
decos.push_back(create<ast::SetDecoration>(0, Source{})); decos.push_back(create<ast::SetDecoration>(0, Source{}));
data_var->set_decorations(decos); data_var->set_decorations(decos);
mod.AddConstructedType(&s); mod->AddConstructedType(&s);
td.RegisterVariableForTesting(data_var); td.RegisterVariableForTesting(data_var);
mod.AddGlobalVariable(data_var); mod->AddGlobalVariable(data_var);
{ {
ast::VariableList params; ast::VariableList params;
@ -272,7 +272,7 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod.AddFunction(func); mod->AddFunction(func);
} }
{ {
@ -290,7 +290,7 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
func->add_decoration( func->add_decoration(
create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{})); create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
mod.AddFunction(func); mod->AddFunction(func);
} }
ASSERT_TRUE(td.Determine()) << td.error(); ASSERT_TRUE(td.Determine()) << td.error();

View File

@ -51,16 +51,15 @@ namespace writer {
namespace spirv { namespace spirv {
namespace { namespace {
class IntrinsicBuilderTest : public ast::BuilderWithContext, class IntrinsicBuilderTest : public ast::BuilderWithContextAndModule,
public testing::Test { public testing::Test {
protected: protected:
void OnVariableBuilt(ast::Variable* var) override { void OnVariableBuilt(ast::Variable* var) override {
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
} }
ast::Module mod; TypeDeterminer td{ctx, mod};
TypeDeterminer td{ctx, &mod}; spirv::Builder b{ctx, mod};
spirv::Builder b{ctx, &mod};
}; };
template <typename T> template <typename T>

View File

@ -31,13 +31,11 @@ namespace spirv {
/// Helper class for testing /// Helper class for testing
template <typename BASE> template <typename BASE>
class TestHelperBase : public ast::BuilderWithContext, public BASE { class TestHelperBase : public ast::BuilderWithContextAndModule, public BASE {
public: public:
TestHelperBase() : td(ctx, &mod), b(ctx, &mod) {} TestHelperBase() : td(ctx, mod), b(ctx, mod) {}
~TestHelperBase() override = default; ~TestHelperBase() override = default;
/// The module
ast::Module mod;
/// The type determiner /// The type determiner
TypeDeterminer td; TypeDeterminer td;
/// The generator /// The generator

View File

@ -36,13 +36,13 @@ class TestHelperBase : public BASE {
~TestHelperBase() = default; ~TestHelperBase() = default;
/// Creates a new `ast::Node` owned by the Context. When the Context is /// Creates a new `ast::Node` owned by the Module. When the Module is
/// destructed, the `ast::Node` will also be destructed. /// destructed, the `ast::Node` will also be destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* create(ARGS&&... args) { T* create(ARGS&&... args) {
return ctx.create<T>(std::forward<ARGS>(args)...); return mod.create<T>(std::forward<ARGS>(args)...);
} }
/// The context /// The context