ast: Remove ConstructorExpression

ConstructorExpression is abstract, and now only has a single class deriving
from it - TypeConstructorExpression. Just use that instead.

Bug: tint:888
Change-Id: I7ee52ad645bcd8a8a68710c63a1fdf834b5b2a24
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/68842
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton 2021-11-09 09:35:00 +00:00 committed by Ben Clayton
parent a838bb718b
commit 72b6bb94c2
19 changed files with 48 additions and 178 deletions

View File

@ -208,8 +208,6 @@ libtint_source_set("libtint_core_all_src") {
"ast/call_statement.h",
"ast/case_statement.cc",
"ast/case_statement.h",
"ast/constructor_expression.cc",
"ast/constructor_expression.h",
"ast/continue_statement.cc",
"ast/continue_statement.h",
"ast/decoration.cc",

View File

@ -74,8 +74,6 @@ set(TINT_LIB_SRCS
ast/call_statement.h
ast/case_statement.cc
ast/case_statement.h
ast/constructor_expression.cc
ast/constructor_expression.h
ast/continue_statement.cc
ast/continue_statement.h
ast/decoration.cc

View File

@ -1,30 +0,0 @@
// Copyright 2020 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/ast/constructor_expression.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::ConstructorExpression);
namespace tint {
namespace ast {
ConstructorExpression::~ConstructorExpression() = default;
ConstructorExpression::ConstructorExpression(ConstructorExpression&&) = default;
ConstructorExpression::ConstructorExpression(ProgramID pid, const Source& src)
: Base(pid, src) {}
} // namespace ast
} // namespace tint

View File

@ -1,41 +0,0 @@
// Copyright 2020 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_AST_CONSTRUCTOR_EXPRESSION_H_
#define SRC_AST_CONSTRUCTOR_EXPRESSION_H_
#include "src/ast/expression.h"
namespace tint {
namespace ast {
/// Base class for constructor style expressions
class ConstructorExpression
: public Castable<ConstructorExpression, Expression> {
public:
~ConstructorExpression() override;
protected:
/// Constructor
/// @param pid the identifier of the program that owns this node
/// @param src the source of this node
ConstructorExpression(ProgramID pid, const Source& src);
/// Move constructor
ConstructorExpression(ConstructorExpression&&);
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CONSTRUCTOR_EXPRESSION_H_

View File

@ -17,7 +17,7 @@
#include <utility>
#include "src/ast/constructor_expression.h"
#include "src/ast/expression.h"
namespace tint {
namespace ast {
@ -27,7 +27,7 @@ class Type;
/// A type specific constructor
class TypeConstructorExpression
: public Castable<TypeConstructorExpression, ConstructorExpression> {
: public Castable<TypeConstructorExpression, Expression> {
public:
/// Constructor
/// @param pid the identifier of the program that owns this node

View File

@ -24,7 +24,6 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl) {
auto e = p->expect_const_expr();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* t = e->As<ast::TypeConstructorExpression>();
@ -46,7 +45,6 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_Empty) {
auto e = p->expect_const_expr();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* t = e->As<ast::TypeConstructorExpression>();
@ -61,7 +59,6 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_TrailingComma) {
auto e = p->expect_const_expr();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* t = e->As<ast::TypeConstructorExpression>();
@ -137,7 +134,6 @@ TEST_F(ParserImplTest, ConstExpr_RegisteredType) {
auto e = p->expect_const_expr();
ASSERT_FALSE(e.errored);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
}

View File

@ -39,7 +39,6 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl) {
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* ty = e->As<ast::TypeConstructorExpression>();
@ -65,7 +64,6 @@ TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroConstructor) {
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* ty = e->As<ast::TypeConstructorExpression>();
@ -227,7 +225,6 @@ TEST_F(ParserImplTest, PrimaryExpression_Cast) {
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e.value, nullptr);
ASSERT_TRUE(e->Is<ast::ConstructorExpression>());
ASSERT_TRUE(e->Is<ast::TypeConstructorExpression>());
auto* c = e->As<ast::TypeConstructorExpression>();

View File

@ -90,7 +90,7 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit) {
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(e->variable->constructor, nullptr);
EXPECT_TRUE(e->variable->constructor->Is<ast::ConstructorExpression>());
EXPECT_TRUE(e->variable->constructor->Is<ast::TypeConstructorExpression>());
}
TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit_NoSpace) {
@ -105,7 +105,7 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit_NoSpace) {
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(e->variable->constructor, nullptr);
EXPECT_TRUE(e->variable->constructor->Is<ast::ConstructorExpression>());
EXPECT_TRUE(e->variable->constructor->Is<ast::TypeConstructorExpression>());
}
TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit) {
@ -120,7 +120,7 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit) {
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(e->variable->constructor, nullptr);
EXPECT_TRUE(e->variable->constructor->Is<ast::ConstructorExpression>());
EXPECT_TRUE(e->variable->constructor->Is<ast::TypeConstructorExpression>());
}
TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
@ -135,7 +135,7 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
EXPECT_EQ(e->variable->symbol, p->builder().Symbols().Get("a"));
ASSERT_NE(e->variable->constructor, nullptr);
EXPECT_TRUE(e->variable->constructor->Is<ast::ConstructorExpression>());
EXPECT_TRUE(e->variable->constructor->Is<ast::TypeConstructorExpression>());
}
TEST_F(ParserImplTest, VariableStmt_Let) {

View File

@ -2362,8 +2362,8 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
sem_expr = Bitcast(bitcast);
} else if (auto* call = expr->As<ast::CallExpression>()) {
sem_expr = Call(call);
} else if (auto* ctor = expr->As<ast::ConstructorExpression>()) {
sem_expr = Constructor(ctor);
} else if (auto* ctor = expr->As<ast::TypeConstructorExpression>()) {
sem_expr = TypeConstructor(ctor);
} else if (auto* ident = expr->As<ast::IdentifierExpression>()) {
sem_expr = Identifier(ident);
} else if (auto* literal = expr->As<ast::Literal>()) {
@ -2730,41 +2730,37 @@ bool Resolver::ValidateFunctionCall(const sem::Call* call) {
return true;
}
sem::Expression* Resolver::Constructor(const ast::ConstructorExpression* expr) {
if (auto* type_ctor = expr->As<ast::TypeConstructorExpression>()) {
auto* ty = Type(type_ctor->type);
if (!ty) {
return nullptr;
}
// Now that the argument types have been determined, make sure that they
// obey the constructor type rules laid out in
// https://gpuweb.github.io/gpuweb/wgsl.html#type-constructor-expr.
bool ok = true;
if (auto* vec_type = ty->As<sem::Vector>()) {
ok = ValidateVectorConstructor(type_ctor, vec_type);
} else if (auto* mat_type = ty->As<sem::Matrix>()) {
ok = ValidateMatrixConstructor(type_ctor, mat_type);
} else if (ty->is_scalar()) {
ok = ValidateScalarConstructor(type_ctor, ty);
} else if (auto* arr_type = ty->As<sem::Array>()) {
ok = ValidateArrayConstructor(type_ctor, arr_type);
} else if (auto* struct_type = ty->As<sem::Struct>()) {
ok = ValidateStructureConstructor(type_ctor, struct_type);
} else {
AddError("type is not constructible", type_ctor->source);
return nullptr;
}
if (!ok) {
return nullptr;
}
auto val = EvaluateConstantValue(expr, ty);
return builder_->create<sem::Expression>(expr, ty, current_statement_, val);
sem::Expression* Resolver::TypeConstructor(
const ast::TypeConstructorExpression* expr) {
auto* ty = Type(expr->type);
if (!ty) {
return nullptr;
}
TINT_ICE(Resolver, diagnostics_) << "unexpected constructor expression type";
return nullptr;
// Now that the argument types have been determined, make sure that they
// obey the constructor type rules laid out in
// https://gpuweb.github.io/gpuweb/wgsl.html#type-constructor-expr.
bool ok = true;
if (auto* vec_type = ty->As<sem::Vector>()) {
ok = ValidateVectorConstructor(expr, vec_type);
} else if (auto* mat_type = ty->As<sem::Matrix>()) {
ok = ValidateMatrixConstructor(expr, mat_type);
} else if (ty->is_scalar()) {
ok = ValidateScalarConstructor(expr, ty);
} else if (auto* arr_type = ty->As<sem::Array>()) {
ok = ValidateArrayConstructor(expr, arr_type);
} else if (auto* struct_type = ty->As<sem::Struct>()) {
ok = ValidateStructureConstructor(expr, struct_type);
} else {
AddError("type is not constructible", expr->source);
return nullptr;
}
if (!ok) {
return nullptr;
}
auto val = EvaluateConstantValue(expr, ty);
return builder_->create<sem::Expression>(expr, ty, current_statement_, val);
}
sem::Expression* Resolver::Literal(const ast::Literal* literal) {

View File

@ -171,7 +171,6 @@ class Resolver {
sem::Expression* Binary(const ast::BinaryExpression*);
sem::Expression* Bitcast(const ast::BitcastExpression*);
sem::Expression* Call(const ast::CallExpression*);
sem::Expression* Constructor(const ast::ConstructorExpression*);
sem::Expression* Expression(const ast::Expression*);
sem::Function* Function(const ast::Function*);
sem::Call* FunctionCall(const ast::CallExpression*);
@ -179,6 +178,7 @@ class Resolver {
sem::Call* IntrinsicCall(const ast::CallExpression*, sem::IntrinsicType);
sem::Expression* Literal(const ast::Literal*);
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
sem::Expression* TypeConstructor(const ast::TypeConstructorExpression*);
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
// Statement resolving methods

View File

@ -1385,11 +1385,6 @@ bool GeneratorImpl::EmitCase(const ast::CaseStatement* stmt) {
return true;
}
bool GeneratorImpl::EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr) {
return EmitTypeConstructor(out, expr->As<ast::TypeConstructorExpression>());
}
bool GeneratorImpl::EmitTypeConstructor(
std::ostream& out,
const ast::TypeConstructorExpression* expr) {
@ -1471,8 +1466,8 @@ bool GeneratorImpl::EmitExpression(std::ostream& out,
if (auto* c = expr->As<ast::CallExpression>()) {
return EmitCall(out, c);
}
if (auto* c = expr->As<ast::ConstructorExpression>()) {
return EmitConstructor(out, c);
if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
return EmitTypeConstructor(out, c);
}
if (auto* i = expr->As<ast::IdentifierExpression>()) {
return EmitIdentifier(out, i);

View File

@ -188,12 +188,6 @@ class GeneratorImpl : public TextGenerator {
/// @param stmt the statement
/// @returns true if the statement was emitted successfully
bool EmitCase(const ast::CaseStatement* stmt);
/// Handles generating constructor expressions
/// @param out the output of the expression stream
/// @param expr the constructor expression
/// @returns true if the expression was emitted
bool EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr);
/// Handles generating a discard statement
/// @param stmt the discard statement
/// @returns true if the statement was successfully emitted

View File

@ -2112,11 +2112,6 @@ bool GeneratorImpl::EmitCase(const ast::SwitchStatement* s, size_t case_idx) {
return true;
}
bool GeneratorImpl::EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr) {
return EmitTypeConstructor(out, expr->As<ast::TypeConstructorExpression>());
}
bool GeneratorImpl::EmitTypeConstructor(
std::ostream& out,
const ast::TypeConstructorExpression* expr) {
@ -2203,8 +2198,8 @@ bool GeneratorImpl::EmitExpression(std::ostream& out,
if (auto* c = expr->As<ast::CallExpression>()) {
return EmitCall(out, c);
}
if (auto* c = expr->As<ast::ConstructorExpression>()) {
return EmitConstructor(out, c);
if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
return EmitTypeConstructor(out, c);
}
if (auto* i = expr->As<ast::IdentifierExpression>()) {
return EmitIdentifier(out, i);

View File

@ -217,12 +217,6 @@ class GeneratorImpl : public TextGenerator {
/// @param case_idx the index of the switch case in the switch statement
/// @returns true if the statement was emitted successfully
bool EmitCase(const ast::SwitchStatement* s, size_t case_idx);
/// Handles generating constructor expressions
/// @param out the output of the expression stream
/// @param expr the constructor expression
/// @returns true if the expression was emitted
bool EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr);
/// Handles generating a discard statement
/// @param stmt the discard statement
/// @returns true if the statement was successfully emitted

View File

@ -1291,11 +1291,6 @@ bool GeneratorImpl::EmitCase(const ast::CaseStatement* stmt) {
return true;
}
bool GeneratorImpl::EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr) {
return EmitTypeConstructor(out, expr->As<ast::TypeConstructorExpression>());
}
bool GeneratorImpl::EmitContinue(const ast::ContinueStatement*) {
if (!emit_continuing_()) {
return false;
@ -1430,8 +1425,8 @@ bool GeneratorImpl::EmitExpression(std::ostream& out,
if (auto* c = expr->As<ast::CallExpression>()) {
return EmitCall(out, c);
}
if (auto* c = expr->As<ast::ConstructorExpression>()) {
return EmitConstructor(out, c);
if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
return EmitTypeConstructor(out, c);
}
if (auto* i = expr->As<ast::IdentifierExpression>()) {
return EmitIdentifier(out, i);

View File

@ -182,12 +182,6 @@ class GeneratorImpl : public TextGenerator {
/// @param stmt the statement
/// @returns true if the statement was emitted successfully
bool EmitCase(const ast::CaseStatement* stmt);
/// Handles generating constructor expressions
/// @param out the output of the expression stream
/// @param expr the constructor expression
/// @returns true if the expression was emitted
bool EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr);
/// Handles a continue statement
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully

View File

@ -577,7 +577,7 @@ uint32_t Builder::GenerateExpression(const ast::Expression* expr) {
if (auto* c = expr->As<ast::CallExpression>()) {
return GenerateCallExpression(c);
}
if (auto* c = expr->As<ast::ConstructorExpression>()) {
if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
return GenerateConstructorExpression(nullptr, c);
}
if (auto* i = expr->As<ast::IdentifierExpression>()) {

View File

@ -134,8 +134,8 @@ bool GeneratorImpl::EmitExpression(std::ostream& out,
if (auto* l = expr->As<ast::Literal>()) {
return EmitLiteral(out, l);
}
if (auto* c = expr->As<ast::ConstructorExpression>()) {
return EmitConstructor(out, c);
if (auto* c = expr->As<ast::TypeConstructorExpression>()) {
return EmitTypeConstructor(out, c);
}
if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
return EmitMemberAccessor(out, m);
@ -243,11 +243,6 @@ bool GeneratorImpl::EmitCall(std::ostream& out,
return true;
}
bool GeneratorImpl::EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr) {
return EmitTypeConstructor(out, expr->As<ast::TypeConstructorExpression>());
}
bool GeneratorImpl::EmitTypeConstructor(
std::ostream& out,
const ast::TypeConstructorExpression* expr) {

View File

@ -120,18 +120,12 @@ class GeneratorImpl : public TextGenerator {
/// Handles generating an identifier expression
/// @param out the output of the expression stream
/// @param expr the identifier expression
/// @returns true if the identifeir was emitted
/// @returns true if the identifier was emitted
bool EmitIdentifier(std::ostream& out, const ast::IdentifierExpression* expr);
/// Handles an if statement
/// @param stmt the statement to emit
/// @returns true if the statement was successfully emitted
bool EmitIf(const ast::IfStatement* stmt);
/// Handles generating constructor expressions
/// @param out the output of the expression stream
/// @param expr the constructor expression
/// @returns true if the expression was emitted
bool EmitConstructor(std::ostream& out,
const ast::ConstructorExpression* expr);
/// Handles generating a discard statement
/// @param stmt the discard statement
/// @returns true if the statement was successfully emitted