Add sem::Module
Holds `DependencyOrderedDeclarations()`, which will hold the sorted dependency-graph ordered list of global declarations. Bug: tint:1266 Change-Id: I9840fae8689abd214973ea4785f71c3ae2587bbc Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79766 Reviewed-by: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
597fc4cdbe
commit
a52be6c9ec
|
@ -398,6 +398,7 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"sem/info.h",
|
||||
"sem/loop_statement.h",
|
||||
"sem/matrix_type.h",
|
||||
"sem/module.h",
|
||||
"sem/multisampled_texture_type.h",
|
||||
"sem/node.h",
|
||||
"sem/parameter_usage.h",
|
||||
|
@ -574,6 +575,8 @@ libtint_source_set("libtint_sem_src") {
|
|||
"sem/matrix_type.cc",
|
||||
"sem/matrix_type.h",
|
||||
"sem/member_accessor_expression.cc",
|
||||
"sem/module.cc",
|
||||
"sem/module.h",
|
||||
"sem/multisampled_texture_type.cc",
|
||||
"sem/multisampled_texture_type.h",
|
||||
"sem/node.cc",
|
||||
|
|
|
@ -285,6 +285,8 @@ set(TINT_LIB_SRCS
|
|||
sem/pipeline_stage_set.h
|
||||
sem/node.cc
|
||||
sem/node.h
|
||||
sem/module.cc
|
||||
sem/module.h
|
||||
sem/sampler_texture_pair.h
|
||||
sem/statement.cc
|
||||
sem/struct.cc
|
||||
|
|
|
@ -34,16 +34,8 @@ Module::Module(ProgramID pid,
|
|||
if (decl == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Switch(
|
||||
decl, //
|
||||
[&](const ast::TypeDecl* type) { type_decls_.push_back(type); },
|
||||
[&](const Function* func) { functions_.push_back(func); },
|
||||
[&](const Variable* var) { global_variables_.push_back(var); },
|
||||
[&](Default) {
|
||||
diag::List diagnostics;
|
||||
TINT_ICE(AST, diagnostics) << "Unknown global declaration type";
|
||||
});
|
||||
diag::List diags;
|
||||
BinGlobalDeclaration(decl, diags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +50,33 @@ const ast::TypeDecl* Module::LookupType(Symbol name) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void Module::AddGlobalDeclaration(const tint::ast::Node* decl) {
|
||||
diag::List diags;
|
||||
BinGlobalDeclaration(decl, diags);
|
||||
global_declarations_.emplace_back(decl);
|
||||
}
|
||||
|
||||
void Module::BinGlobalDeclaration(const tint::ast::Node* decl,
|
||||
diag::List& diags) {
|
||||
Switch(
|
||||
decl, //
|
||||
[&](const ast::TypeDecl* type) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
|
||||
type_decls_.push_back(type);
|
||||
},
|
||||
[&](const Function* func) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
|
||||
functions_.push_back(func);
|
||||
},
|
||||
[&](const Variable* var) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
|
||||
global_variables_.push_back(var);
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(AST, diags) << "Unknown global declaration type";
|
||||
});
|
||||
}
|
||||
|
||||
void Module::AddGlobalVariable(const ast::Variable* var) {
|
||||
TINT_ASSERT(AST, var);
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
|
||||
|
@ -100,24 +119,7 @@ void Module::Copy(CloneContext* ctx, const Module* src) {
|
|||
<< "src global declaration was nullptr";
|
||||
continue;
|
||||
}
|
||||
Switch(
|
||||
decl,
|
||||
[&](const ast::TypeDecl* type) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
|
||||
type_decls_.push_back(type);
|
||||
},
|
||||
[&](const Function* func) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
|
||||
functions_.push_back(func);
|
||||
},
|
||||
[&](const Variable* var) {
|
||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
|
||||
global_variables_.push_back(var);
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(AST, ctx->dst->Diagnostics())
|
||||
<< "Unknown global declaration type";
|
||||
});
|
||||
BinGlobalDeclaration(decl, ctx->dst->Diagnostics());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class Module : public Castable<Module, Node> {
|
|||
/// Destructor
|
||||
~Module() override;
|
||||
|
||||
/// @returns the ordered global declarations for the translation unit
|
||||
/// @returns the declaration-ordered global declarations for the module
|
||||
const std::vector<const Node*>& GlobalDeclarations() const {
|
||||
return global_declarations_;
|
||||
}
|
||||
|
@ -67,10 +67,14 @@ class Module : public Castable<Module, Node> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// @returns the global variables for the translation unit
|
||||
/// Adds a global declaration to the Builder.
|
||||
/// @param decl the declaration to add
|
||||
void AddGlobalDeclaration(const tint::ast::Node* decl);
|
||||
|
||||
/// @returns the global variables for the module
|
||||
const VariableList& GlobalVariables() const { return global_variables_; }
|
||||
|
||||
/// @returns the global variables for the translation unit
|
||||
/// @returns the global variables for the module
|
||||
VariableList& GlobalVariables() { return global_variables_; }
|
||||
|
||||
/// Adds a type declaration to the Builder.
|
||||
|
@ -81,14 +85,14 @@ class Module : public Castable<Module, Node> {
|
|||
/// @param name the name of the type to search for
|
||||
const TypeDecl* LookupType(Symbol name) const;
|
||||
|
||||
/// @returns the declared types in the translation unit
|
||||
/// @returns the declared types in the module
|
||||
const std::vector<const TypeDecl*>& TypeDecls() const { return type_decls_; }
|
||||
|
||||
/// Add a function to the Builder
|
||||
/// @param func the function to add
|
||||
void AddFunction(const Function* func);
|
||||
|
||||
/// @returns the functions declared in the translation unit
|
||||
/// @returns the functions declared in the module
|
||||
const FunctionList& Functions() const { return functions_; }
|
||||
|
||||
/// Clones this node and all transitive child nodes using the `CloneContext`
|
||||
|
@ -103,6 +107,12 @@ class Module : public Castable<Module, Node> {
|
|||
void Copy(CloneContext* ctx, const Module* src);
|
||||
|
||||
private:
|
||||
/// Adds `decl` to either:
|
||||
/// * #global_declarations_
|
||||
/// * #type_decls_
|
||||
/// * #functions_
|
||||
void BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags);
|
||||
|
||||
std::vector<const Node*> global_declarations_;
|
||||
std::vector<const TypeDecl*> type_decls_;
|
||||
FunctionList functions_;
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "src/sem/if_statement.h"
|
||||
#include "src/sem/loop_statement.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/multisampled_texture_type.h"
|
||||
#include "src/sem/pointer_type.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
|
@ -99,6 +100,10 @@ bool Resolver::Resolve() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Create the semantic module
|
||||
builder_->Sem().SetModule(
|
||||
builder_->create<sem::Module>(dependencies_.ordered_globals));
|
||||
|
||||
bool result = ResolveInternal();
|
||||
|
||||
if (!result && !diagnostics_.contains_errors()) {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "src/sem/call.h"
|
||||
#include "src/sem/function.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/module.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
#include "src/sem/sampled_texture_type.h"
|
||||
#include "src/sem/statement.h"
|
||||
|
@ -2161,6 +2162,28 @@ TEST_F(ResolverTest, TextureSampler_TextureDimensions) {
|
|||
EXPECT_TRUE(pairs[0].first != nullptr);
|
||||
EXPECT_TRUE(pairs[0].second == nullptr);
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) {
|
||||
auto* f0 = Func("f0", {}, ty.void_(), {});
|
||||
auto* v0 = Global("v0", ty.i32(), ast::StorageClass::kPrivate);
|
||||
auto* a0 = Alias("a0", ty.i32());
|
||||
auto* s0 = Structure("s0", {Member("m", ty.i32())});
|
||||
auto* f1 = Func("f1", {}, ty.void_(), {});
|
||||
auto* v1 = Global("v1", ty.i32(), ast::StorageClass::kPrivate);
|
||||
auto* a1 = Alias("a1", ty.i32());
|
||||
auto* s1 = Structure("s1", {Member("m", ty.i32())});
|
||||
auto* f2 = Func("f2", {}, ty.void_(), {});
|
||||
auto* v2 = Global("v2", ty.i32(), ast::StorageClass::kPrivate);
|
||||
auto* a2 = Alias("a2", ty.i32());
|
||||
auto* s2 = Structure("s2", {Member("m", ty.i32())});
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(Sem().Module(), nullptr);
|
||||
EXPECT_THAT(Sem().Module()->DependencyOrderedDeclarations(),
|
||||
ElementsAre(f0, v0, a0, s0, f1, v1, a1, s1, f2, v2, a2, s2));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
#include "src/sem/node.h"
|
||||
#include "src/sem/type_mappings.h"
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
namespace tint::sem {
|
||||
|
||||
// Forward declarations
|
||||
class Module;
|
||||
|
||||
/// Info holds all the resolved semantic information for a Program.
|
||||
class Info {
|
||||
|
@ -60,8 +62,8 @@ class Info {
|
|||
typename AST_OR_TYPE = CastableBase,
|
||||
typename RESULT = GetResultType<SEM, AST_OR_TYPE>>
|
||||
const RESULT* Get(const AST_OR_TYPE* node) const {
|
||||
auto it = map.find(node);
|
||||
if (it == map.end()) {
|
||||
auto it = map_.find(node);
|
||||
if (it == map_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return As<RESULT>(it->second);
|
||||
|
@ -76,7 +78,7 @@ class Info {
|
|||
const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
|
||||
// Check there's no semantic info already existing for the node
|
||||
TINT_ASSERT(Semantic, Get(node) == nullptr);
|
||||
map.emplace(node, sem_node);
|
||||
map_.emplace(node, sem_node);
|
||||
}
|
||||
|
||||
/// Wrap returns a new Info created with the contents of `inner`.
|
||||
|
@ -88,17 +90,26 @@ class Info {
|
|||
/// @return the Info that wraps `inner`
|
||||
static Info Wrap(const Info& inner) {
|
||||
Info out;
|
||||
out.map = inner.map;
|
||||
out.map_ = inner.map_;
|
||||
out.module_ = inner.module_;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Assigns the semantic module.
|
||||
/// @param module the module to assign.
|
||||
void SetModule(sem::Module* module) { module_ = module; }
|
||||
|
||||
/// @returns the semantic module.
|
||||
const sem::Module* Module() const { return module_; }
|
||||
|
||||
private:
|
||||
// TODO(crbug.com/tint/724): Once finished, this map should be:
|
||||
// std::unordered_map<const ast::Node*, const sem::Node*>
|
||||
std::unordered_map<const CastableBase*, const CastableBase*> map;
|
||||
std::unordered_map<const CastableBase*, const CastableBase*> map_;
|
||||
// The semantic module
|
||||
sem::Module* module_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
} // namespace tint::sem
|
||||
|
||||
#endif // SRC_SEM_INFO_H_
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2022 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.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/sem/module.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Module);
|
||||
|
||||
namespace tint::sem {
|
||||
|
||||
Module::Module(std::vector<const ast::Node*> dep_ordered_decls)
|
||||
: dep_ordered_decls_(std::move(dep_ordered_decls)) {}
|
||||
|
||||
Module::~Module() = default;
|
||||
|
||||
} // namespace tint::sem
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2022 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.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_SEM_MODULE_H_
|
||||
#define SRC_SEM_MODULE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "src/sem/node.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint::ast {
|
||||
class Node;
|
||||
class Module;
|
||||
} // namespace tint::ast
|
||||
|
||||
namespace tint::sem {
|
||||
|
||||
/// Module holds the top-level semantic types, functions and global variables
|
||||
/// used by a Program.
|
||||
class Module : public Castable<Module, Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param dep_ordered_decls the dependency-ordered module-scope declarations
|
||||
explicit Module(std::vector<const ast::Node*> dep_ordered_decls);
|
||||
|
||||
/// Destructor
|
||||
~Module() override;
|
||||
|
||||
/// @returns the dependency-ordered global declarations for the module
|
||||
const std::vector<const ast::Node*>& DependencyOrderedDeclarations() const {
|
||||
return dep_ordered_decls_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<const ast::Node*> dep_ordered_decls_;
|
||||
};
|
||||
|
||||
} // namespace tint::sem
|
||||
|
||||
#endif // SRC_SEM_MODULE_H_
|
Loading…
Reference in New Issue