Convert ScopeStack over to symbols.

This CL converts the ScopeStack to use a Symbol instead of a string as
the accessor.

Change-Id: I2893003bc119c86c4822732ef36c7393e4be1e79
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/36580
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair 2021-01-11 15:10:19 +00:00 committed by Commit Bot service account
parent f51d965bef
commit 795b6b5a28
15 changed files with 144 additions and 131 deletions

View File

@ -14,10 +14,11 @@
#ifndef SRC_SCOPE_STACK_H_
#define SRC_SCOPE_STACK_H_
#include <string>
#include <unordered_map>
#include <vector>
#include "src/symbol.h"
namespace tint {
/// Used to store a stack of scope information.
@ -45,38 +46,40 @@ class ScopeStack {
}
/// Set a global variable in the stack
/// @param name the name of the variable
/// @param symbol the symbol of the variable
/// @param val the value
void set_global(const std::string& name, T val) { stack_[0][name] = val; }
/// Sets variable into the top most scope of the stack
/// @param name the name of the variable
/// @param val the value
void set(const std::string& name, T val) { stack_.back()[name] = val; }
/// Checks for the given `name` in the stack
/// @param name the name to look for
/// @returns true if the stack contains `name`
bool has(const std::string& name) const { return get(name, nullptr); }
/// Retrieves a given name from the stack
/// @param name the name to look for
/// @param ret where to place the name
/// @returns true if the name was successfully found, false otherwise
bool get(const std::string& name, T* ret) const {
return get(name, ret, nullptr);
void set_global(const Symbol& symbol, T val) {
stack_[0][symbol.value()] = val;
}
/// Retrieves a given name from the stack
/// @param name the name to look for
/// @param ret where to place the name
/// @param is_global set true if the name references a global variable
/// Sets variable into the top most scope of the stack
/// @param symbol the symbol of the variable
/// @param val the value
void set(const Symbol& symbol, T val) { stack_.back()[symbol.value()] = val; }
/// Checks for the given `symbol` in the stack
/// @param symbol the symbol to look for
/// @returns true if the stack contains `symbol`
bool has(const Symbol& symbol) const { return get(symbol, nullptr); }
/// Retrieves a given variable from the stack
/// @param symbol the symbol to look for
/// @param ret where to place the value
/// @returns true if the symbol was successfully found, false otherwise
bool get(const Symbol& symbol, T* ret) const {
return get(symbol, ret, nullptr);
}
/// Retrieves a given variable from the stack
/// @param symbol the symbol to look for
/// @param ret where to place the value
/// @param is_global set true if the symbol references a global variable
/// otherwise unchanged
/// @returns true if the name was successfully found, false otherwise
bool get(const std::string& name, T* ret, bool* is_global) const {
/// @returns true if the symbol was successfully found, false otherwise
bool get(const Symbol& symbol, T* ret, bool* is_global) const {
for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) {
auto& map = *iter;
auto val = map.find(name);
auto val = map.find(symbol.value());
if (val != map.end()) {
if (ret) {
@ -92,7 +95,7 @@ class ScopeStack {
}
private:
std::vector<std::unordered_map<std::string, T>> stack_;
std::vector<std::unordered_map<uint32_t, T>> stack_;
};
} // namespace tint

View File

@ -17,6 +17,7 @@
#include "src/ast/builder.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/variable.h"
#include "src/symbol.h"
namespace tint {
namespace {
@ -25,68 +26,75 @@ class ScopeStackTest : public ast::BuilderWithModule, public testing::Test {};
TEST_F(ScopeStackTest, Global) {
ScopeStack<uint32_t> s;
s.set_global("var", 5);
Symbol sym(1);
s.set_global(sym, 5);
uint32_t val = 0;
EXPECT_TRUE(s.get("var", &val));
EXPECT_TRUE(s.get(sym, &val));
EXPECT_EQ(val, 5u);
}
TEST_F(ScopeStackTest, Global_SetWithPointer) {
auto* v = Var("my_var", ast::StorageClass::kNone, ty.f32);
ScopeStack<ast::Variable*> s;
s.set_global("var", v);
s.set_global(v->symbol(), v);
ast::Variable* v2 = nullptr;
EXPECT_TRUE(s.get("var", &v2));
EXPECT_EQ(v2->name(), "my_var");
EXPECT_TRUE(s.get(v->symbol(), &v2));
EXPECT_EQ(v2->symbol(), v->symbol());
}
TEST_F(ScopeStackTest, Global_CanNotPop) {
ScopeStack<uint32_t> s;
s.set_global("var", 5);
Symbol sym(1);
s.set_global(sym, 5);
s.pop_scope();
uint32_t val = 0;
EXPECT_TRUE(s.get("var", &val));
EXPECT_TRUE(s.get(sym, &val));
EXPECT_EQ(val, 5u);
}
TEST_F(ScopeStackTest, Scope) {
ScopeStack<uint32_t> s;
Symbol sym(1);
s.push_scope();
s.set("var", 5);
s.set(sym, 5);
uint32_t val = 0;
EXPECT_TRUE(s.get("var", &val));
EXPECT_TRUE(s.get(sym, &val));
EXPECT_EQ(val, 5u);
}
TEST_F(ScopeStackTest, Get_MissingName) {
TEST_F(ScopeStackTest, Get_MissingSymbol) {
ScopeStack<uint32_t> s;
Symbol sym(1);
uint32_t ret = 0;
EXPECT_FALSE(s.get("val", &ret));
EXPECT_FALSE(s.get(sym, &ret));
EXPECT_EQ(ret, 0u);
}
TEST_F(ScopeStackTest, Has) {
ScopeStack<uint32_t> s;
s.set_global("var2", 3);
Symbol sym(1);
Symbol sym2(2);
s.set_global(sym2, 3);
s.push_scope();
s.set("var", 5);
s.set(sym, 5);
EXPECT_TRUE(s.has("var"));
EXPECT_TRUE(s.has("var2"));
EXPECT_TRUE(s.has(sym));
EXPECT_TRUE(s.has(sym2));
}
TEST_F(ScopeStackTest, ReturnsScopeBeforeGlobalFirst) {
ScopeStack<uint32_t> s;
s.set_global("var", 3);
Symbol sym(1);
s.set_global(sym, 3);
s.push_scope();
s.set("var", 5);
s.set(sym, 5);
uint32_t ret;
EXPECT_TRUE(s.get("var", &ret));
EXPECT_TRUE(s.get(sym, &ret));
EXPECT_EQ(ret, 5u);
}

View File

@ -102,7 +102,7 @@ bool TypeDeterminer::Determine() {
}
for (auto* var : mod_->global_variables()) {
variable_stack_.set_global(var->name(), var);
variable_stack_.set_global(var->symbol(), var);
if (var->has_constructor()) {
if (!DetermineResultType(var->constructor())) {
@ -154,7 +154,7 @@ bool TypeDeterminer::DetermineFunction(ast::Function* func) {
variable_stack_.push_scope();
for (auto* param : func->params()) {
variable_stack_.set(param->name(), param);
variable_stack_.set(param->symbol(), param);
}
if (!DetermineStatements(func->body())) {
@ -267,7 +267,7 @@ bool TypeDeterminer::DetermineResultType(ast::Statement* stmt) {
return true;
}
if (auto* v = stmt->As<ast::VariableDeclStatement>()) {
variable_stack_.set(v->variable()->name(), v->variable());
variable_stack_.set(v->variable()->symbol(), v->variable());
return DetermineResultType(v->variable()->constructor());
}
@ -859,8 +859,9 @@ bool TypeDeterminer::DetermineConstructor(ast::ConstructorExpression* expr) {
bool TypeDeterminer::DetermineIdentifier(ast::IdentifierExpression* expr) {
auto name = expr->name();
auto symbol = expr->symbol();
ast::Variable* var;
if (variable_stack_.get(name, &var)) {
if (variable_stack_.get(symbol, &var)) {
// A constant is the type, but a variable is always a pointer so synthesize
// the pointer around the variable type.
if (var->is_const()) {

View File

@ -89,7 +89,7 @@ class TypeDeterminer {
/// Testing method to set a given variable into the type stack
/// @param var the variable to set
void RegisterVariableForTesting(ast::Variable* var) {
variable_stack_.set(var->name(), var);
variable_stack_.set(var->symbol(), var);
}
/// Retrieves information for the requested import.

View File

@ -18,15 +18,14 @@
namespace tint {
Validator::Validator() : impl_(std::make_unique<tint::ValidatorImpl>()) {}
Validator::Validator() = default;
Validator::~Validator() = default;
bool Validator::Validate(const ast::Module* module) {
bool ret = impl_->Validate(module);
diags_ = impl_->diagnostics();
ValidatorImpl impl(module);
bool ret = impl.Validate();
diags_ = impl.diagnostics();
return ret;
}

View File

@ -27,8 +27,6 @@
namespace tint {
class ValidatorImpl;
/// Determines if the module is complete and valid
class Validator {
public:
@ -52,7 +50,6 @@ class Validator {
const diag::List& diagnostics() const { return diags_; }
private:
std::unique_ptr<ValidatorImpl> impl_;
diag::List diags_;
};

View File

@ -52,7 +52,7 @@ TEST_F(ValidateFunctionTest, VoidFunctionEndWithoutReturnStatement_Pass) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod));
EXPECT_TRUE(v()->Validate());
}
TEST_F(ValidateFunctionTest,
@ -68,7 +68,7 @@ TEST_F(ValidateFunctionTest,
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod));
EXPECT_TRUE(v()->Validate());
}
TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
@ -86,7 +86,7 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0002: non-void function must end with a return statement");
}
@ -99,7 +99,7 @@ TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0002: non-void function must end with a return statement");
}
@ -132,7 +132,7 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
// TODO(sarahM0): replace 000y with a rule number
EXPECT_EQ(v()->error(),
"12:34 v-000y: return statement type must match its function "
@ -150,7 +150,7 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
// TODO(sarahM0): replace 000y with a rule number
EXPECT_EQ(v()->error(),
"12:34 v-000y: return statement type must match its function "
@ -177,7 +177,7 @@ TEST_F(ValidateFunctionTest, FunctionNamesMustBeUnique_fail) {
mod->AddFunction(func_copy);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(), "12:34 v-0016: function names must be unique 'func'");
}
@ -196,7 +196,7 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowed_Fail) {
mod->AddFunction(func0);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod)) << v()->error();
EXPECT_FALSE(v()->Validate()) << v()->error();
EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
}
@ -217,7 +217,7 @@ TEST_F(ValidateFunctionTest, RecursionIsNotAllowedExpr_Fail) {
mod->AddFunction(func0);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod)) << v()->error();
EXPECT_FALSE(v()->Validate()) << v()->error();
EXPECT_EQ(v()->error(), "12:34 v-0004: recursion is not allowed: 'func'");
}
@ -235,7 +235,7 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_NotVoid_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0024: Entry point function must return void: 'vtx_main'");
}
@ -257,7 +257,7 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0023: Entry point function must accept no parameters: "
"'vtx_func'");
@ -279,7 +279,7 @@ TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(
v()->error(),
"12:34 v-0020: only one stage decoration permitted per entry point");
@ -299,7 +299,7 @@ TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod)) << v()->error();
EXPECT_TRUE(v()->Validate()) << v()->error();
}
TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Fail) {
@ -312,7 +312,7 @@ TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"v-0003: At least one of vertex, fragment or compute shader must "
"be present");

View File

@ -37,7 +37,7 @@
namespace tint {
ValidatorImpl::ValidatorImpl() = default;
ValidatorImpl::ValidatorImpl(const ast::Module* module) : module_(*module) {}
ValidatorImpl::~ValidatorImpl() = default;
@ -60,21 +60,18 @@ void ValidatorImpl::add_error(const Source& src, const std::string& msg) {
diags_.add(std::move(diag));
}
bool ValidatorImpl::Validate(const ast::Module* module) {
if (!module) {
return false;
}
bool ValidatorImpl::Validate() {
function_stack_.push_scope();
if (!ValidateGlobalVariables(module->global_variables())) {
if (!ValidateGlobalVariables(module_.global_variables())) {
return false;
}
if (!ValidateConstructedTypes(module->constructed_types())) {
if (!ValidateConstructedTypes(module_.constructed_types())) {
return false;
}
if (!ValidateFunctions(module->functions())) {
if (!ValidateFunctions(module_.functions())) {
return false;
}
if (!ValidateEntryPoint(module->functions())) {
if (!ValidateEntryPoint(module_.functions())) {
return false;
}
function_stack_.pop_scope();
@ -113,9 +110,10 @@ bool ValidatorImpl::ValidateConstructedTypes(
bool ValidatorImpl::ValidateGlobalVariables(
const ast::VariableList& global_vars) {
for (auto* var : global_vars) {
if (variable_stack_.has(var->name())) {
if (variable_stack_.has(var->symbol())) {
add_error(var->source(), "v-0011",
"redeclared global identifier '" + var->name() + "'");
"redeclared global identifier '" +
module_.SymbolToName(var->symbol()) + "'");
return false;
}
if (!var->is_const() && var->storage_class() == ast::StorageClass::kNone) {
@ -129,20 +127,21 @@ bool ValidatorImpl::ValidateGlobalVariables(
"global constants shouldn't have a storage class");
return false;
}
variable_stack_.set_global(var->name(), var);
variable_stack_.set_global(var->symbol(), var);
}
return true;
}
bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
for (auto* func : funcs) {
if (function_stack_.has(func->name())) {
if (function_stack_.has(func->symbol())) {
add_error(func->source(), "v-0016",
"function names must be unique '" + func->name() + "'");
"function names must be unique '" +
module_.SymbolToName(func->symbol()) + "'");
return false;
}
function_stack_.set(func->name(), func);
function_stack_.set(func->symbol(), func);
current_function_ = func;
if (!ValidateFunction(func)) {
return false;
@ -197,7 +196,7 @@ bool ValidatorImpl::ValidateFunction(const ast::Function* func) {
variable_stack_.push_scope();
for (auto* param : func->params()) {
variable_stack_.set(param->name(), param);
variable_stack_.set(param->symbol(), param);
if (!ValidateParameter(param)) {
return false;
}
@ -265,18 +264,18 @@ bool ValidatorImpl::ValidateStatements(const ast::BlockStatement* block) {
bool ValidatorImpl::ValidateDeclStatement(
const ast::VariableDeclStatement* decl) {
auto name = decl->variable()->name();
auto symbol = decl->variable()->symbol();
bool is_global = false;
if (variable_stack_.get(name, nullptr, &is_global)) {
if (variable_stack_.get(symbol, nullptr, &is_global)) {
const char* error_code = "v-0014";
if (is_global) {
error_code = "v-0013";
}
add_error(decl->source(), error_code,
"redeclared identifier '" + name + "'");
"redeclared identifier '" + module_.SymbolToName(symbol) + "'");
return false;
}
variable_stack_.set(name, decl->variable());
variable_stack_.set(symbol, decl->variable());
if (auto* arr =
decl->variable()->type()->UnwrapAll()->As<ast::type::Array>()) {
if (arr->IsRuntimeArray()) {
@ -403,18 +402,20 @@ bool ValidatorImpl::ValidateCallExpr(const ast::CallExpression* expr) {
}
if (auto* ident = expr->func()->As<ast::IdentifierExpression>()) {
auto func_name = ident->name();
if (ident->IsIntrinsic()) {
// TODO(sarahM0): validate intrinsics - tied with type-determiner
} else {
if (!function_stack_.has(func_name)) {
auto symbol = ident->symbol();
if (!function_stack_.has(symbol)) {
add_error(expr->source(), "v-0005",
"function must be declared before use: '" + func_name + "'");
"function must be declared before use: '" +
module_.SymbolToName(symbol) + "'");
return false;
}
if (func_name == current_function_->name()) {
add_error(expr->source(), "v-0004",
"recursion is not allowed: '" + func_name + "'");
if (symbol == current_function_->symbol()) {
add_error(
expr->source(), "v-0004",
"recursion is not allowed: '" + module_.SymbolToName(symbol) + "'");
return false;
}
}
@ -450,10 +451,11 @@ bool ValidatorImpl::ValidateConstant(const ast::AssignmentStatement* assign) {
if (auto* ident = assign->lhs()->As<ast::IdentifierExpression>()) {
ast::Variable* var;
if (variable_stack_.get(ident->name(), &var)) {
if (variable_stack_.get(ident->symbol(), &var)) {
if (var->is_const()) {
add_error(assign->source(), "v-0021",
"cannot re-assign a constant: '" + ident->name() + "'");
"cannot re-assign a constant: '" +
module_.SymbolToName(ident->symbol()) + "'");
return false;
}
}
@ -495,9 +497,10 @@ bool ValidatorImpl::ValidateExpression(const ast::Expression* expr) {
bool ValidatorImpl::ValidateIdentifier(const ast::IdentifierExpression* ident) {
ast::Variable* var;
if (!variable_stack_.get(ident->name(), &var)) {
add_error(ident->source(), "v-0006",
"'" + ident->name() + "' is not declared");
if (!variable_stack_.get(ident->symbol(), &var)) {
add_error(
ident->source(), "v-0006",
"'" + module_.SymbolToName(ident->symbol()) + "' is not declared");
return false;
}
return true;

View File

@ -39,13 +39,13 @@ namespace tint {
class ValidatorImpl {
public:
/// Constructor
ValidatorImpl();
/// @param module the module to validate
explicit ValidatorImpl(const ast::Module* module);
~ValidatorImpl();
/// Runs the validator
/// @param module the module to validate
/// @returns true if the validation was successful
bool Validate(const ast::Module* module);
bool Validate();
/// @returns the diagnostic messages
const diag::List& diagnostics() const { return diags_; }
@ -148,6 +148,7 @@ class ValidatorImpl {
const std::vector<ast::type::Type*>& constructed_types);
private:
const ast::Module& module_;
diag::List diags_;
ScopeStack<ast::Variable*> variable_stack_;
ScopeStack<ast::Function*> function_stack_;

View File

@ -217,7 +217,7 @@ TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
ast::StorageClass::kNone, ty.f32, nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0022: global variables must have a storage class");
}
@ -228,7 +228,7 @@ TEST_F(ValidatorTest, GlobalConstantWithStorageClass_Fail) {
ast::StorageClass::kInput, ty.f32, nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(
v()->error(),
"12:34 v-global01: global constants shouldn't have a storage class");
@ -240,7 +240,7 @@ TEST_F(ValidatorTest, GlobalConstNoStorageClass_Pass) {
ast::StorageClass::kNone, ty.f32, nullptr,
ast::VariableDecorationList{}));
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod)) << v()->error();
EXPECT_FALSE(v()->Validate()) << v()->error();
}
TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
@ -263,7 +263,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
ast::FunctionDecorationList{});
mod->AddFunction(func);
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(), "12:34 v-0006: 'not_global_var' is not declared");
}
@ -290,7 +290,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod)) << v()->error();
EXPECT_TRUE(v()->Validate()) << v()->error();
}
TEST_F(ValidatorTest, UsingUndefinedVariableInnerScope_Fail) {
@ -435,7 +435,7 @@ TEST_F(ValidatorTest, GlobalVariableFunctionVariableNotUnique_Fail) {
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
EXPECT_FALSE(v()->Validate(mod)) << v()->error();
EXPECT_FALSE(v()->Validate()) << v()->error();
EXPECT_EQ(v()->error(), "12:34 v-0013: redeclared identifier 'a'");
}
@ -462,7 +462,7 @@ TEST_F(ValidatorTest, RedeclaredIndentifier_Fail) {
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(td()->DetermineFunction(func)) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(), "12:34 v-0014: redeclared identifier 'a'");
}
@ -552,7 +552,7 @@ TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
mod->AddFunction(func1);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod)) << v()->error();
EXPECT_TRUE(v()->Validate()) << v()->error();
}
TEST_F(ValidatorTest, VariableDeclNoConstructor_Pass) {

View File

@ -20,7 +20,7 @@ namespace tint {
ValidatorTestHelper::ValidatorTestHelper() {
td_ = std::make_unique<TypeDeterminer>(mod);
v_ = std::make_unique<ValidatorImpl>();
v_ = std::make_unique<ValidatorImpl>(mod);
}
ValidatorTestHelper::~ValidatorTestHelper() = default;

View File

@ -160,7 +160,7 @@ TEST_F(ValidatorTypeTest, RuntimeArrayInFunction_Fail) {
mod->AddFunction(func);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0015: runtime arrays may only appear as the last member "
"of a struct");
@ -192,7 +192,7 @@ TEST_F(ValidatorTypeTest, RuntimeArrayAsParameter_Fail) {
mod->AddFunction(main);
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod));
EXPECT_FALSE(v()->Validate());
EXPECT_EQ(v()->error(),
"12:34 v-0015: runtime arrays may only appear as the last member "
"of a struct");

View File

@ -205,7 +205,7 @@ bool GeneratorImpl::Generate(std::ostream& out) {
}
void GeneratorImpl::register_global(ast::Variable* global) {
global_variables_.set(global->name(), global);
global_variables_.set(global->symbol(), global);
}
std::string GeneratorImpl::generate_name(const std::string& prefix) {
@ -1077,7 +1077,7 @@ bool GeneratorImpl::EmitIdentifier(std::ostream&,
ast::IdentifierExpression* expr) {
auto* ident = expr->As<ast::IdentifierExpression>();
ast::Variable* var = nullptr;
if (global_variables_.get(ident->name(), &var)) {
if (global_variables_.get(ident->symbol(), &var)) {
if (global_is_in_struct(var)) {
auto var_type = var->storage_class() == ast::StorageClass::kInput
? VarType::kIn
@ -1964,7 +1964,7 @@ bool GeneratorImpl::is_storage_buffer_access(
// Check if this is a storage buffer variable
if (auto* ident = expr->structure()->As<ast::IdentifierExpression>()) {
ast::Variable* var = nullptr;
if (!global_variables_.get(ident->name(), &var)) {
if (!global_variables_.get(ident->symbol(), &var)) {
return false;
}
return var->storage_class() == ast::StorageClass::kStorageBuffer;

View File

@ -116,7 +116,7 @@ bool GeneratorImpl::Generate() {
out_ << "#include <metal_stdlib>" << std::endl << std::endl;
for (auto* global : module_->global_variables()) {
global_variables_.set(global->name(), global);
global_variables_.set(global->symbol(), global);
}
for (auto* const ty : module_->constructed_types()) {
@ -1528,7 +1528,7 @@ bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
bool GeneratorImpl::EmitIdentifier(ast::IdentifierExpression* expr) {
auto* ident = expr->As<ast::IdentifierExpression>();
ast::Variable* var = nullptr;
if (global_variables_.get(ident->name(), &var)) {
if (global_variables_.get(ident->symbol(), &var)) {
if (global_is_in_struct(var)) {
auto var_type = var->storage_class() == ast::StorageClass::kInput
? VarType::kIn

View File

@ -458,8 +458,9 @@ bool Builder::GenerateEntryPoint(ast::Function* func, uint32_t id) {
}
uint32_t var_id;
if (!scope_stack_.get(var->name(), &var_id)) {
error_ = "unable to find ID for global variable: " + var->name();
if (!scope_stack_.get(var->symbol(), &var_id)) {
error_ = "unable to find ID for global variable: " +
mod_->SymbolToName(var->symbol());
return false;
}
@ -567,7 +568,7 @@ bool Builder::GenerateFunction(ast::Function* func) {
params.push_back(Instruction{spv::Op::OpFunctionParameter,
{Operand::Int(param_type_id), param_op}});
scope_stack_.set(param->name(), param_id);
scope_stack_.set(param->symbol(), param_id);
}
push_function(Function{definition_inst, result_op(), std::move(params)});
@ -639,7 +640,7 @@ bool Builder::GenerateFunctionVariable(ast::Variable* var) {
error_ = "missing constructor for constant";
return false;
}
scope_stack_.set(var->name(), init_id);
scope_stack_.set(var->symbol(), init_id);
spirv_id_to_variable_[init_id] = var;
return true;
}
@ -673,7 +674,7 @@ bool Builder::GenerateFunctionVariable(ast::Variable* var) {
}
}
scope_stack_.set(var->name(), var_id);
scope_stack_.set(var->symbol(), var_id);
spirv_id_to_variable_[var_id] = var;
return true;
@ -707,7 +708,7 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
push_debug(spv::Op::OpName,
{Operand::Int(init_id), Operand::String(var->name())});
scope_stack_.set_global(var->name(), init_id);
scope_stack_.set_global(var->symbol(), init_id);
spirv_id_to_variable_[init_id] = var;
return true;
}
@ -820,7 +821,7 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
}
}
scope_stack_.set_global(var->name(), var_id);
scope_stack_.set_global(var->symbol(), var_id);
spirv_id_to_variable_[var_id] = var;
return true;
}
@ -1108,7 +1109,7 @@ uint32_t Builder::GenerateAccessorExpression(ast::Expression* expr) {
uint32_t Builder::GenerateIdentifierExpression(
ast::IdentifierExpression* expr) {
uint32_t val = 0;
if (scope_stack_.get(expr->name(), &val)) {
if (scope_stack_.get(expr->symbol(), &val)) {
return val;
}