Reintroduce ast::Module as the root AST structure
Holds the global variables, constructed types and functions. Deprecate the functions on program that forward on to the module. These will be fixed up in another change. Bug: tint:390 Change-Id: I47b6921a7d84be18113dec830c8435d4e0d4182d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38544 Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
9f7a414505
commit
a07396a13c
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
// Copyright 2021 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -14,10 +14,104 @@
|
|||
|
||||
#include "src/ast/module.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/clone_context.h"
|
||||
#include "src/program.h"
|
||||
#include "src/type/alias_type.h"
|
||||
#include "src/type/struct_type.h"
|
||||
|
||||
TINT_INSTANTIATE_CLASS_ID(tint::ast::Module);
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
// Placeholder
|
||||
Module::Module() : Base(Source{}) {}
|
||||
|
||||
Module::Module(std::vector<type::Type*> constructed_types,
|
||||
FunctionList functions,
|
||||
VariableList global_variables)
|
||||
: Base(Source{}),
|
||||
constructed_types_(std::move(constructed_types)),
|
||||
functions_(std::move(functions)),
|
||||
global_variables_(std::move(global_variables)) {}
|
||||
|
||||
Module::~Module() = default;
|
||||
|
||||
bool Module::IsValid() const {
|
||||
for (auto* var : global_variables_) {
|
||||
if (var == nullptr || !var->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto* const ty : constructed_types_) {
|
||||
if (ty == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (auto* alias = ty->As<type::Alias>()) {
|
||||
if (alias->type() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (auto* str = alias->type()->As<type::Struct>()) {
|
||||
if (!str->symbol().IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (auto* str = ty->As<type::Struct>()) {
|
||||
if (!str->symbol().IsValid()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto* func : functions_) {
|
||||
if (func == nullptr || !func->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Module* Module::Clone(CloneContext* ctx) const {
|
||||
return ctx->dst->create<Module>(ctx->Clone(constructed_types_),
|
||||
ctx->Clone(functions_),
|
||||
ctx->Clone(global_variables_));
|
||||
}
|
||||
|
||||
void Module::to_str(std::ostream& out, size_t indent) const {
|
||||
make_indent(out, indent);
|
||||
out << "Module{" << std::endl;
|
||||
indent += 2;
|
||||
for (auto* const ty : constructed_types_) {
|
||||
make_indent(out, indent);
|
||||
if (auto* alias = ty->As<type::Alias>()) {
|
||||
out << alias->symbol().to_str() << " -> " << alias->type()->type_name()
|
||||
<< std::endl;
|
||||
if (auto* str = alias->type()->As<type::Struct>()) {
|
||||
str->impl()->to_str(out, indent);
|
||||
}
|
||||
} else if (auto* str = ty->As<type::Struct>()) {
|
||||
out << str->symbol().to_str() << " ";
|
||||
str->impl()->to_str(out, indent);
|
||||
}
|
||||
}
|
||||
for (auto* var : global_variables_) {
|
||||
var->to_str(out, indent);
|
||||
}
|
||||
for (auto* func : functions_) {
|
||||
func->to_str(out, indent);
|
||||
}
|
||||
out << "}" << std::endl;
|
||||
}
|
||||
|
||||
std::string Module::to_str() const {
|
||||
std::ostringstream out;
|
||||
to_str(out, 0);
|
||||
return out.str();
|
||||
}
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 The Tint Authors.
|
||||
// Copyright 2021 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -15,10 +15,89 @@
|
|||
#ifndef SRC_AST_MODULE_H_
|
||||
#define SRC_AST_MODULE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/function.h"
|
||||
#include "src/ast/node.h"
|
||||
#include "src/ast/variable.h"
|
||||
#include "src/type/type.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
// Placeholder
|
||||
/// Module holds the top-level AST types, functions and global variables used by
|
||||
/// a Program.
|
||||
class Module : public Castable<Module, Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
Module();
|
||||
|
||||
/// Constructor
|
||||
/// @param constructed_types the list of types explicitly declared in the AST
|
||||
/// @param functions the list of program functions
|
||||
/// @param global_variables the list of global variables
|
||||
Module(std::vector<type::Type*> constructed_types,
|
||||
FunctionList functions,
|
||||
VariableList global_variables);
|
||||
|
||||
/// Destructor
|
||||
~Module() override;
|
||||
|
||||
/// Add a global variable to the Builder
|
||||
/// @param var the variable to add
|
||||
void AddGlobalVariable(ast::Variable* var) {
|
||||
global_variables_.push_back(var);
|
||||
}
|
||||
|
||||
/// @returns the global variables for the translation unit
|
||||
const VariableList& GlobalVariables() const { return global_variables_; }
|
||||
|
||||
/// @returns the global variables for the translation unit
|
||||
VariableList& GlobalVariables() { return global_variables_; }
|
||||
|
||||
/// Adds a constructed type to the Builder.
|
||||
/// The type must be an alias or a struct.
|
||||
/// @param type the constructed type to add
|
||||
void AddConstructedType(type::Type* type) {
|
||||
constructed_types_.push_back(type);
|
||||
}
|
||||
|
||||
/// @returns the constructed types in the translation unit
|
||||
const std::vector<type::Type*>& ConstructedTypes() const {
|
||||
return constructed_types_;
|
||||
}
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
const FunctionList& Functions() const { return functions_; }
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
FunctionList& Functions() { return functions_; }
|
||||
|
||||
/// @returns true if all required fields in the AST are present.
|
||||
bool IsValid() const override;
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
/// `ctx`.
|
||||
/// @note Semantic information such as resolved expression type and intrinsic
|
||||
/// information is not cloned.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned node
|
||||
Module* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// Writes a representation of the node to the output stream
|
||||
/// @param out the stream to write to
|
||||
/// @param indent number of spaces to indent the node when writing
|
||||
void to_str(std::ostream& out, size_t indent) const override;
|
||||
|
||||
/// @returns a string representation of the Builder
|
||||
std::string to_str() const;
|
||||
|
||||
private:
|
||||
std::vector<type::Type*> constructed_types_;
|
||||
FunctionList functions_;
|
||||
VariableList global_variables_;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
|
|
@ -30,4 +30,13 @@ void CloneContext::Clone() {
|
|||
src->Clone(this);
|
||||
}
|
||||
|
||||
ast::FunctionList CloneContext::Clone(const ast::FunctionList& v) {
|
||||
ast::FunctionList out;
|
||||
out.reserve(v.size());
|
||||
for (ast::Function* el : v) {
|
||||
out.Add(Clone(el));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/function.h"
|
||||
#include "src/castable.h"
|
||||
#include "src/source.h"
|
||||
#include "src/symbol.h"
|
||||
|
@ -106,6 +107,14 @@ class CloneContext {
|
|||
return out;
|
||||
}
|
||||
|
||||
/// Clones each of the elements of the vector `v` into the Program #dst.
|
||||
///
|
||||
/// All the elements of the vector `v` must be owned by the Program #src.
|
||||
///
|
||||
/// @param v the vector to clone
|
||||
/// @return the cloned vector
|
||||
ast::FunctionList Clone(const ast::FunctionList& v);
|
||||
|
||||
/// ReplaceAll() registers `replacer` to be called whenever the Clone() method
|
||||
/// is called with a type that matches (or derives from) the type of the
|
||||
/// second parameter of `replacer`.
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
namespace tint {
|
||||
|
||||
Program::Program() = default;
|
||||
Program::Program() : ast_(nodes_.Create<ast::Module>()) {}
|
||||
|
||||
Program::Program(Program&&) = default;
|
||||
Program::Program(Program&& rhs) = default;
|
||||
|
||||
Program& Program::operator=(Program&& rhs) = default;
|
||||
|
||||
|
@ -36,93 +36,35 @@ Program Program::Clone() const {
|
|||
}
|
||||
|
||||
void Program::Clone(CloneContext* ctx) const {
|
||||
for (auto* ty : constructed_types_) {
|
||||
ctx->dst->constructed_types_.emplace_back(ctx->Clone(ty));
|
||||
for (auto* ty : AST().ConstructedTypes()) {
|
||||
ctx->dst->AST().AddConstructedType(ctx->Clone(ty));
|
||||
}
|
||||
for (auto* var : global_variables_) {
|
||||
ctx->dst->global_variables_.emplace_back(ctx->Clone(var));
|
||||
for (auto* var : AST().GlobalVariables()) {
|
||||
ctx->dst->AST().AddGlobalVariable(ctx->Clone(var));
|
||||
}
|
||||
for (auto* func : functions_) {
|
||||
ctx->dst->functions_.emplace_back(ctx->Clone(func));
|
||||
for (auto* func : AST().Functions()) {
|
||||
ctx->dst->AST().Functions().Add(ctx->Clone(func));
|
||||
}
|
||||
}
|
||||
|
||||
Symbol Program::RegisterSymbol(const std::string& name) {
|
||||
return symbol_table_.Register(name);
|
||||
return symbols_.Register(name);
|
||||
}
|
||||
|
||||
Symbol Program::GetSymbol(const std::string& name) const {
|
||||
return symbol_table_.Get(name);
|
||||
return symbols_.Get(name);
|
||||
}
|
||||
|
||||
std::string Program::SymbolToName(const Symbol sym) const {
|
||||
return symbol_table_.NameFor(sym);
|
||||
return symbols_.NameFor(sym);
|
||||
}
|
||||
|
||||
bool Program::IsValid() const {
|
||||
for (auto* var : global_variables_) {
|
||||
if (var == nullptr || !var->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto* const ty : constructed_types_) {
|
||||
if (ty == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (auto* alias = ty->As<type::Alias>()) {
|
||||
if (alias->type() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (auto* str = alias->type()->As<type::Struct>()) {
|
||||
if (!str->symbol().IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (auto* str = ty->As<type::Struct>()) {
|
||||
if (!str->symbol().IsValid()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto* func : functions_) {
|
||||
if (func == nullptr || !func->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return ast_->IsValid();
|
||||
}
|
||||
|
||||
std::string Program::to_str() const {
|
||||
std::ostringstream out;
|
||||
|
||||
out << "Module{" << std::endl;
|
||||
const auto indent = 2;
|
||||
for (auto* const ty : constructed_types_) {
|
||||
for (size_t i = 0; i < indent; ++i) {
|
||||
out << " ";
|
||||
}
|
||||
if (auto* alias = ty->As<type::Alias>()) {
|
||||
out << alias->symbol().to_str() << " -> " << alias->type()->type_name()
|
||||
<< std::endl;
|
||||
if (auto* str = alias->type()->As<type::Struct>()) {
|
||||
str->impl()->to_str(out, indent);
|
||||
}
|
||||
} else if (auto* str = ty->As<type::Struct>()) {
|
||||
out << str->symbol().to_str() << " ";
|
||||
str->impl()->to_str(out, indent);
|
||||
}
|
||||
}
|
||||
for (auto* var : global_variables_) {
|
||||
var->to_str(out, indent);
|
||||
}
|
||||
for (auto* func : functions_) {
|
||||
func->to_str(out, indent);
|
||||
}
|
||||
out << "}" << std::endl;
|
||||
|
||||
return out.str();
|
||||
return ast_->to_str();
|
||||
}
|
||||
|
||||
} // namespace tint
|
||||
|
|
118
src/program.h
118
src/program.h
|
@ -24,6 +24,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "src/ast/function.h"
|
||||
#include "src/ast/module.h"
|
||||
#include "src/ast/variable.h"
|
||||
#include "src/block_allocator.h"
|
||||
#include "src/symbol_table.h"
|
||||
|
@ -36,11 +37,15 @@ namespace tint {
|
|||
/// Represents all the source in a given program.
|
||||
class Program {
|
||||
public:
|
||||
/// ASTNodes is an alias to BlockAllocator<ast::Node>
|
||||
using ASTNodes = BlockAllocator<ast::Node>;
|
||||
|
||||
/// Constructor
|
||||
Program();
|
||||
|
||||
/// Move constructor
|
||||
Program(Program&&);
|
||||
/// @param rhs the Program to move
|
||||
Program(Program&& rhs);
|
||||
|
||||
/// Move assignment operator
|
||||
/// @param rhs the Program to move
|
||||
|
@ -50,10 +55,28 @@ class Program {
|
|||
/// Destructor
|
||||
~Program();
|
||||
|
||||
/// @returns a reference to the program's types
|
||||
const type::Manager& Types() const { return types_; }
|
||||
|
||||
/// @returns a reference to the program's AST nodes storage
|
||||
const ASTNodes& Nodes() const { return nodes_; }
|
||||
|
||||
/// @returns a reference to the program's AST root Module
|
||||
const ast::Module& AST() const { return *ast_; }
|
||||
|
||||
/// @returns a reference to the program's AST root Module
|
||||
ast::Module& AST() { return *ast_; }
|
||||
|
||||
/// @returns a reference to the program's SymbolTable
|
||||
const SymbolTable& Symbols() const { return symbols_; }
|
||||
|
||||
/// @returns a reference to the program's SymbolTable
|
||||
SymbolTable& Symbols() { return symbols_; }
|
||||
|
||||
/// @return a deep copy of this program
|
||||
Program Clone() const;
|
||||
|
||||
/// Clone this program into `ctx->mod` using the provided CloneContext
|
||||
/// Clone this program into `ctx->dst` using the provided CloneContext
|
||||
/// The program will be cloned in this order:
|
||||
/// * Constructed types
|
||||
/// * Global variables
|
||||
|
@ -61,36 +84,6 @@ class Program {
|
|||
/// @param ctx the clone context
|
||||
void Clone(CloneContext* ctx) const;
|
||||
|
||||
/// Add a global variable to the program
|
||||
/// @param var the variable to add
|
||||
void AddGlobalVariable(ast::Variable* var) {
|
||||
global_variables_.push_back(var);
|
||||
}
|
||||
/// @returns the global variables for the program
|
||||
const ast::VariableList& global_variables() const {
|
||||
return global_variables_;
|
||||
}
|
||||
|
||||
/// @returns the global variables for the program
|
||||
ast::VariableList& global_variables() { return global_variables_; }
|
||||
|
||||
/// Adds a constructed type to the program.
|
||||
/// The type must be an alias or a struct.
|
||||
/// @param type the constructed type to add
|
||||
void AddConstructedType(type::Type* type) {
|
||||
constructed_types_.push_back(type);
|
||||
}
|
||||
/// @returns the constructed types in the program
|
||||
const std::vector<type::Type*>& constructed_types() const {
|
||||
return constructed_types_;
|
||||
}
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
const ast::FunctionList& Functions() const { return functions_; }
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
ast::FunctionList& Functions() { return functions_; }
|
||||
|
||||
/// @returns true if all required fields in the AST are present.
|
||||
bool IsValid() const;
|
||||
|
||||
|
@ -103,7 +96,7 @@ class Program {
|
|||
/// @returns the node pointer
|
||||
template <typename T, typename... ARGS>
|
||||
traits::EnableIfIsType<T, ast::Node>* create(ARGS&&... args) {
|
||||
return ast_nodes_.Create<T>(std::forward<ARGS>(args)...);
|
||||
return nodes_.Create<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// Creates a new type::Type owned by the Program.
|
||||
|
@ -122,44 +115,83 @@ class Program {
|
|||
traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
|
||||
static_assert(std::is_base_of<type::Type, T>::value,
|
||||
"T does not derive from type::Type");
|
||||
return type_mgr_.Get<T>(std::forward<ARGS>(args)...);
|
||||
return types_.Get<T>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// Add a global variable to the program
|
||||
/// [DEPRECATED]: Use AST().AddGlobalVariable(var)
|
||||
/// @param var the variable to add
|
||||
void AddGlobalVariable(ast::Variable* var) { AST().AddGlobalVariable(var); }
|
||||
|
||||
/// [DEPRECATED]: Use AST().GlobalVariables()
|
||||
/// @returns the global variables for the program
|
||||
const ast::VariableList& global_variables() const {
|
||||
return AST().GlobalVariables();
|
||||
}
|
||||
|
||||
/// [DEPRECATED]: Use AST().GlobalVariables()
|
||||
/// @returns the global variables for the program
|
||||
ast::VariableList& global_variables() { return AST().GlobalVariables(); }
|
||||
|
||||
/// Adds a constructed type to the program.
|
||||
/// The type must be an alias or a struct.
|
||||
/// [DEPRECATED]: Use AST().AddConstructedType(type)
|
||||
/// @param type the constructed type to add
|
||||
void AddConstructedType(type::Type* type) { AST().AddConstructedType(type); }
|
||||
|
||||
/// @returns the constructed types in the program
|
||||
/// [DEPRECATED]: Use AST().ConstructedTypes()
|
||||
const std::vector<type::Type*>& constructed_types() const {
|
||||
return AST().ConstructedTypes();
|
||||
}
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
/// [DEPRECATED]: Use AST().Functions()
|
||||
const ast::FunctionList& Functions() const { return AST().Functions(); }
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
/// [DEPRECATED]: Use AST().Functions()
|
||||
ast::FunctionList& Functions() { return AST().Functions(); }
|
||||
|
||||
/// Returns all the declared types in the program
|
||||
/// [DEPRECATED]: Use AST().Types().types()
|
||||
/// @returns the mapping from name string to type.
|
||||
const std::unordered_map<std::string, type::Type*>& types() {
|
||||
return type_mgr_.types();
|
||||
return types_.types();
|
||||
}
|
||||
|
||||
/// @returns all the declared nodes in the program
|
||||
BlockAllocator<ast::Node>::View nodes() { return ast_nodes_.Objects(); }
|
||||
/// [DEPRECATED]: Use Nodes().Objects()
|
||||
BlockAllocator<ast::Node>::ConstView nodes() const {
|
||||
return Nodes().Objects();
|
||||
}
|
||||
|
||||
/// Registers `name` as a symbol
|
||||
/// @param name the name to register
|
||||
/// @returns the symbol for the `name`. If `name` is already registered the
|
||||
/// previously generated symbol will be returned.
|
||||
/// [DEPRECATED]: Use Symbols().Register()
|
||||
Symbol RegisterSymbol(const std::string& name);
|
||||
|
||||
/// Returns the symbol for `name`
|
||||
/// @param name the name to lookup
|
||||
/// @returns the symbol for name or symbol::kInvalid
|
||||
/// [DEPRECATED]: Use Symbols().Get()
|
||||
Symbol GetSymbol(const std::string& name) const;
|
||||
|
||||
/// Returns the `name` for `sym`
|
||||
/// @param sym the symbol to retrieve the name for
|
||||
/// @returns the use provided `name` for the symbol or "" if not found
|
||||
/// [DEPRECATED]: Use Symbols().NameFor()
|
||||
std::string SymbolToName(const Symbol sym) const;
|
||||
|
||||
private:
|
||||
Program(const Program&) = delete;
|
||||
|
||||
SymbolTable symbol_table_;
|
||||
ast::VariableList global_variables_;
|
||||
// The constructed types are owned by the type manager
|
||||
std::vector<type::Type*> constructed_types_;
|
||||
ast::FunctionList functions_;
|
||||
BlockAllocator<ast::Node> ast_nodes_;
|
||||
type::Manager type_mgr_;
|
||||
type::Manager types_;
|
||||
ASTNodes nodes_;
|
||||
ast::Module* ast_;
|
||||
SymbolTable symbols_;
|
||||
};
|
||||
|
||||
} // namespace tint
|
||||
|
|
Loading…
Reference in New Issue