Replace Variable::(Is|As)* with Castable

Change-Id: I7a49287af079d53cee095fa2243dd21757546b56
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34318
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-11-30 23:30:58 +00:00
parent 19fe07236e
commit aedca4288c
14 changed files with 75 additions and 93 deletions

View File

@ -69,10 +69,6 @@ uint32_t DecoratedVariable::constant_id() const {
return 0;
}
bool DecoratedVariable::IsDecorated() const {
return true;
}
bool DecoratedVariable::IsValid() const {
return Variable::IsValid();
}

View File

@ -56,9 +56,6 @@ class DecoratedVariable : public Castable<DecoratedVariable, Variable> {
/// |HasConstantIdDecoration| has been called first.
uint32_t constant_id() const;
/// @returns true if this is a decorated variable
bool IsDecorated() const override;
/// @returns true if the name and path are both present
bool IsValid() const override;

View File

@ -108,7 +108,7 @@ TEST_F(DecoratedVariableTest, IsValid) {
TEST_F(DecoratedVariableTest, IsDecorated) {
DecoratedVariable dv;
EXPECT_TRUE(dv.IsDecorated());
EXPECT_TRUE(dv.Is<ast::DecoratedVariable>());
}
TEST_F(DecoratedVariableTest, to_str) {

View File

@ -85,13 +85,12 @@ Function::referenced_location_variables() const {
std::vector<std::pair<Variable*, LocationDecoration*>> ret;
for (auto* var : referenced_module_variables()) {
if (!var->IsDecorated()) {
continue;
}
for (auto* deco : var->AsDecorated()->decorations()) {
if (auto* location = deco->As<LocationDecoration>()) {
ret.push_back({var, location});
break;
if (auto* decos = var->As<ast::DecoratedVariable>()) {
for (auto* deco : decos->decorations()) {
if (auto* location = deco->As<LocationDecoration>()) {
ret.push_back({var, location});
break;
}
}
}
}
@ -103,14 +102,14 @@ Function::referenced_uniform_variables() const {
std::vector<std::pair<Variable*, Function::BindingInfo>> ret;
for (auto* var : referenced_module_variables()) {
if (!var->IsDecorated() ||
if (!var->Is<ast::DecoratedVariable>() ||
var->storage_class() != ast::StorageClass::kUniform) {
continue;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->AsDecorated()->decorations()) {
for (auto* deco : var->As<ast::DecoratedVariable>()->decorations()) {
if (auto* b = deco->As<ast::BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<ast::SetDecoration>()) {
@ -131,14 +130,14 @@ Function::referenced_storagebuffer_variables() const {
std::vector<std::pair<Variable*, Function::BindingInfo>> ret;
for (auto* var : referenced_module_variables()) {
if (!var->IsDecorated() ||
if (!var->Is<ast::DecoratedVariable>() ||
var->storage_class() != ast::StorageClass::kStorageBuffer) {
continue;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->AsDecorated()->decorations()) {
for (auto* deco : var->As<ast::DecoratedVariable>()->decorations()) {
if (auto* b = deco->As<ast::BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<ast::SetDecoration>()) {
@ -159,10 +158,10 @@ Function::referenced_builtin_variables() const {
std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
for (auto* var : referenced_module_variables()) {
if (!var->IsDecorated()) {
if (!var->Is<ast::DecoratedVariable>()) {
continue;
}
for (auto* deco : var->AsDecorated()->decorations()) {
for (auto* deco : var->As<ast::DecoratedVariable>()->decorations()) {
if (auto* builtin = deco->As<BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
@ -283,14 +282,15 @@ Function::ReferencedSamplerVariablesImpl(type::SamplerKind kind) const {
for (auto* var : referenced_module_variables()) {
auto* unwrapped_type = var->type()->UnwrapIfNeeded();
if (!var->IsDecorated() || !unwrapped_type->Is<ast::type::SamplerType>() ||
if (!var->Is<ast::DecoratedVariable>() ||
!unwrapped_type->Is<ast::type::SamplerType>() ||
unwrapped_type->As<ast::type::SamplerType>()->kind() != kind) {
continue;
}
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->AsDecorated()->decorations()) {
for (auto* deco : var->As<ast::DecoratedVariable>()->decorations()) {
if (auto* b = deco->As<ast::BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<ast::SetDecoration>()) {
@ -312,7 +312,8 @@ Function::ReferencedSampledTextureVariablesImpl(bool multisampled) const {
for (auto* var : referenced_module_variables()) {
auto* unwrapped_type = var->type()->UnwrapIfNeeded();
if (!var->IsDecorated() || !unwrapped_type->Is<ast::type::TextureType>()) {
if (!var->Is<ast::DecoratedVariable>() ||
!unwrapped_type->Is<ast::type::TextureType>()) {
continue;
}
@ -325,7 +326,7 @@ Function::ReferencedSampledTextureVariablesImpl(bool multisampled) const {
BindingDecoration* binding = nullptr;
SetDecoration* set = nullptr;
for (auto* deco : var->AsDecorated()->decorations()) {
for (auto* deco : var->As<ast::DecoratedVariable>()->decorations()) {
if (auto* b = deco->As<ast::BindingDecoration>()) {
binding = b;
} else if (auto* s = deco->As<ast::SetDecoration>()) {

View File

@ -36,20 +36,6 @@ Variable::Variable(Variable&&) = default;
Variable::~Variable() = default;
DecoratedVariable* Variable::AsDecorated() {
assert(IsDecorated());
return static_cast<DecoratedVariable*>(this);
}
const DecoratedVariable* Variable::AsDecorated() const {
assert(IsDecorated());
return static_cast<const DecoratedVariable*>(this);
}
bool Variable::IsDecorated() const {
return false;
}
bool Variable::IsValid() const {
if (name_.length() == 0) {
return false;

View File

@ -29,8 +29,6 @@
namespace tint {
namespace ast {
class DecoratedVariable;
/// A Variable statement.
///
/// An instance of this class represents one of three constructs in WGSL: "var"
@ -134,14 +132,6 @@ class Variable : public Castable<Variable, Node> {
/// @returns true if this is a constant, false otherwise
bool is_const() const { return is_const_; }
/// @returns true if this is a decorated variable
virtual bool IsDecorated() const;
/// @returns the expression as a decorated variable
DecoratedVariable* AsDecorated();
/// @returns the expression as a decorated variable
const DecoratedVariable* AsDecorated() const;
/// @returns true if the name and path are both present
bool IsValid() const override;

View File

@ -100,11 +100,11 @@ std::string Inspector::GetRemappedNameForEntryPoint(
std::map<uint32_t, Scalar> Inspector::GetConstantIDs() {
std::map<uint32_t, Scalar> result;
for (auto* var : module_.global_variables()) {
if (!var->IsDecorated()) {
auto* decorated = var->As<ast::DecoratedVariable>();
if (decorated == nullptr) {
continue;
}
auto* decorated = var->AsDecorated();
if (!decorated->HasConstantIdDecoration()) {
continue;
}

View File

@ -46,7 +46,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithoutConstructor) {
EXPECT_EQ(e->source().range.end.column, 11u);
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_FALSE(e->IsDecorated());
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
}
TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
@ -73,7 +73,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithConstructor) {
ASSERT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->constructor()->Is<ast::ScalarConstructorExpression>());
ASSERT_FALSE(e->IsDecorated());
ASSERT_FALSE(e->Is<ast::DecoratedVariable>());
}
TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
@ -86,7 +86,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->IsDecorated());
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
EXPECT_EQ(e->name(), "a");
ASSERT_NE(e->type(), nullptr);
@ -100,8 +100,8 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration) {
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_TRUE(e->IsDecorated());
auto* v = e->AsDecorated();
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
auto* v = e->As<ast::DecoratedVariable>();
auto& decorations = v->decorations();
ASSERT_EQ(decorations.size(), 2u);
@ -120,7 +120,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->IsDecorated());
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
EXPECT_EQ(e->name(), "a");
ASSERT_NE(e->type(), nullptr);
@ -134,8 +134,8 @@ TEST_F(ParserImplTest, GlobalVariableDecl_WithDecoration_MulitpleGroups) {
ASSERT_EQ(e->constructor(), nullptr);
ASSERT_TRUE(e->IsDecorated());
auto* v = e->AsDecorated();
ASSERT_TRUE(e->Is<ast::DecoratedVariable>());
auto* v = e->As<ast::DecoratedVariable>();
auto& decorations = v->decorations();
ASSERT_EQ(decorations.size(), 2u);

View File

@ -122,11 +122,12 @@ void VertexPullingTransform::FindOrInsertVertexIndexIfUsed() {
// Look for an existing vertex index builtin
for (auto* v : mod_->global_variables()) {
if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
if (!v->Is<ast::DecoratedVariable>() ||
v->storage_class() != ast::StorageClass::kInput) {
continue;
}
for (auto* d : v->AsDecorated()->decorations()) {
for (auto* d : v->As<ast::DecoratedVariable>()->decorations()) {
if (d->Is<ast::BuiltinDecoration>() &&
d->As<ast::BuiltinDecoration>()->value() ==
ast::Builtin::kVertexIdx) {
@ -165,11 +166,12 @@ void VertexPullingTransform::FindOrInsertInstanceIndexIfUsed() {
// Look for an existing instance index builtin
for (auto* v : mod_->global_variables()) {
if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
if (!v->Is<ast::DecoratedVariable>() ||
v->storage_class() != ast::StorageClass::kInput) {
continue;
}
for (auto* d : v->AsDecorated()->decorations()) {
for (auto* d : v->As<ast::DecoratedVariable>()->decorations()) {
if (d->Is<ast::BuiltinDecoration>() &&
d->As<ast::BuiltinDecoration>()->value() ==
ast::Builtin::kInstanceIdx) {
@ -195,11 +197,12 @@ void VertexPullingTransform::FindOrInsertInstanceIndexIfUsed() {
void VertexPullingTransform::ConvertVertexInputVariablesToPrivate() {
for (auto*& v : mod_->global_variables()) {
if (!v->IsDecorated() || v->storage_class() != ast::StorageClass::kInput) {
if (!v->Is<ast::DecoratedVariable>() ||
v->storage_class() != ast::StorageClass::kInput) {
continue;
}
for (auto* d : v->AsDecorated()->decorations()) {
for (auto* d : v->As<ast::DecoratedVariable>()->decorations()) {
if (auto* l = d->As<ast::LocationDecoration>()) {
uint32_t location = l->value();
// This is where the replacement happens. Expressions use identifier

View File

@ -1005,9 +1005,9 @@ bool GeneratorImpl::EmitExpression(std::ostream& pre,
}
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
return var->IsDecorated() &&
(var->AsDecorated()->HasLocationDecoration() ||
var->AsDecorated()->HasBuiltinDecoration()) &&
return var->Is<ast::DecoratedVariable>() &&
(var->As<ast::DecoratedVariable>()->HasLocationDecoration() ||
var->As<ast::DecoratedVariable>()->HasBuiltinDecoration()) &&
(var->storage_class() == ast::StorageClass::kInput ||
var->storage_class() == ast::StorageClass::kOutput);
}
@ -2219,7 +2219,7 @@ bool GeneratorImpl::EmitVariable(std::ostream& out,
make_indent(out);
// TODO(dsinclair): Handle variable decorations
if (var->IsDecorated()) {
if (var->Is<ast::DecoratedVariable>()) {
error_ = "Variable decorations are not handled yet";
return false;
}
@ -2253,7 +2253,8 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
const ast::Variable* var) {
make_indent(out);
if (var->IsDecorated() && !var->AsDecorated()->HasConstantIdDecoration()) {
if (var->Is<ast::DecoratedVariable>() &&
!var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
error_ = "Decorated const values not valid";
return false;
}
@ -2271,8 +2272,9 @@ bool GeneratorImpl::EmitProgramConstVariable(std::ostream& out,
out << pre.str();
}
if (var->IsDecorated() && var->AsDecorated()->HasConstantIdDecoration()) {
auto const_id = var->AsDecorated()->constant_id();
if (var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
auto const_id = var->As<ast::DecoratedVariable>()->constant_id();
out << "#ifndef WGSL_SPEC_CONSTANT_" << const_id << std::endl;

View File

@ -1492,11 +1492,13 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
bool GeneratorImpl::global_is_in_struct(ast::Variable* var) const {
bool in_or_out_struct_has_location =
var->IsDecorated() && var->AsDecorated()->HasLocationDecoration() &&
var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasLocationDecoration() &&
(var->storage_class() == ast::StorageClass::kInput ||
var->storage_class() == ast::StorageClass::kOutput);
bool in_struct_has_builtin =
var->IsDecorated() && var->AsDecorated()->HasBuiltinDecoration() &&
var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasBuiltinDecoration() &&
var->storage_class() == ast::StorageClass::kOutput;
return in_or_out_struct_has_location || in_struct_has_builtin;
}
@ -2006,7 +2008,7 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
make_indent();
// TODO(dsinclair): Handle variable decorations
if (var->IsDecorated()) {
if (var->Is<ast::DecoratedVariable>()) {
error_ = "Variable decorations are not handled yet";
return false;
}
@ -2044,7 +2046,8 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
make_indent();
if (var->IsDecorated() && !var->AsDecorated()->HasConstantIdDecoration()) {
if (var->Is<ast::DecoratedVariable>() &&
!var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
error_ = "Decorated const values not valid";
return false;
}
@ -2061,9 +2064,10 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
out_ << " " << var->name();
}
if (var->IsDecorated() && var->AsDecorated()->HasConstantIdDecoration()) {
out_ << " [[function_constant(" << var->AsDecorated()->constant_id()
<< ")]]";
if (var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
out_ << " [[function_constant("
<< var->As<ast::DecoratedVariable>()->constant_id() << ")]]";
} else if (var->constructor() != nullptr) {
out_ << " = ";
if (!EmitExpression(var->constructor())) {

View File

@ -747,7 +747,8 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
// one
// 2- If we don't have a constructor and we're an Output or Private variable
// then WGSL requires an initializer.
if (var->IsDecorated() && var->AsDecorated()->HasConstantIdDecoration()) {
if (var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
if (type->Is<ast::type::F32Type>()) {
ast::FloatLiteral l(type, 0.0f);
init_id = GenerateLiteralIfNeeded(var, &l);
@ -782,8 +783,8 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
push_type(spv::Op::OpVariable, std::move(ops));
if (var->IsDecorated()) {
for (auto* deco : var->AsDecorated()->decorations()) {
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
for (auto* deco : decorated->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(var_id), Operand::Int(SpvDecorationBuiltIn),
@ -1468,8 +1469,8 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
auto name = lit->name();
bool is_spec_constant = false;
if (var && var->IsDecorated() &&
var->AsDecorated()->HasConstantIdDecoration()) {
if (var && var->Is<ast::DecoratedVariable>() &&
var->As<ast::DecoratedVariable>()->HasConstantIdDecoration()) {
name = "__spec" + name;
is_spec_constant = true;
}
@ -1483,9 +1484,10 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Variable* var,
auto result_id = result.to_i();
if (is_spec_constant) {
push_annot(spv::Op::OpDecorate,
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
Operand::Int(var->AsDecorated()->constant_id())});
push_annot(
spv::Op::OpDecorate,
{Operand::Int(result_id), Operand::Int(SpvDecorationSpecId),
Operand::Int(var->As<ast::DecoratedVariable>()->constant_id())});
}
if (lit->IsBool()) {
@ -2701,10 +2703,10 @@ uint32_t Builder::GenerateStructMember(uint32_t struct_id,
bool has_layout = false;
for (auto* deco : member->decorations()) {
if (auto* offset = deco->As<ast::StructMemberOffsetDecoration>()) {
push_annot(spv::Op::OpMemberDecorate,
{Operand::Int(struct_id), Operand::Int(idx),
Operand::Int(SpvDecorationOffset),
Operand::Int(offset->offset())});
push_annot(
spv::Op::OpMemberDecorate,
{Operand::Int(struct_id), Operand::Int(idx),
Operand::Int(SpvDecorationOffset), Operand::Int(offset->offset())});
has_layout = true;
} else {
error_ = "unknown struct member decoration";

View File

@ -602,8 +602,8 @@ bool GeneratorImpl::EmitStructType(const ast::type::StructType* str) {
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
make_indent();
if (var->IsDecorated()) {
if (!EmitVariableDecorations(var->AsDecorated())) {
if (auto* decorated = var->As<ast::DecoratedVariable>()) {
if (!EmitVariableDecorations(decorated)) {
return false;
}
}

View File

@ -27,6 +27,7 @@
#include "src/ast/case_statement.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/identifier_expression.h"