reader/wgsl: Migrate to AST types

Bug: tint:724
Change-Id: I484813dd139122244cd09829ab5b035cec9981e6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49960
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton 2021-05-06 15:57:13 +00:00 committed by Commit Bot service account
parent 58750eab19
commit b7bd0e12d1
14 changed files with 238 additions and 285 deletions

View File

@ -213,7 +213,7 @@ ParserImpl::TypedIdentifier::TypedIdentifier() = default;
ParserImpl::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default;
ParserImpl::TypedIdentifier::TypedIdentifier(typ::Type type_in,
ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type* type_in,
std::string name_in,
Source source_in)
: type(type_in), name(std::move(name_in)), source(std::move(source_in)) {}
@ -227,7 +227,7 @@ ParserImpl::FunctionHeader::FunctionHeader(const FunctionHeader&) = default;
ParserImpl::FunctionHeader::FunctionHeader(Source src,
std::string n,
ast::VariableList p,
typ::Type ret_ty,
ast::Type* ret_ty,
ast::DecorationList ret_decos)
: source(src),
name(n),
@ -247,7 +247,7 @@ ParserImpl::VarDeclInfo::VarDeclInfo(const VarDeclInfo&) = default;
ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
std::string name_in,
ast::StorageClass storage_class_in,
typ::Type type_in)
ast::Type* type_in)
: source(std::move(source_in)),
name(std::move(name_in)),
storage_class(storage_class_in),
@ -317,11 +317,11 @@ Token ParserImpl::last_token() const {
}
void ParserImpl::register_constructed(const std::string& name,
sem::Type* type) {
const ast::Type* type) {
registered_constructs_[name] = type;
}
sem::Type* ParserImpl::get_constructed(const std::string& name) {
const ast::Type* ParserImpl::get_constructed(const std::string& name) {
if (registered_constructs_.find(name) == registered_constructs_.end()) {
return nullptr;
}
@ -401,7 +401,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
if (!expect("type alias", Token::Type::kSemicolon))
return Failure::kErrored;
builder_.AST().AddConstructedType(const_cast<ast::Alias*>(ta.value.ast));
builder_.AST().AddConstructedType(const_cast<ast::Alias*>(ta.value));
return true;
}
@ -413,10 +413,9 @@ Expect<bool> ParserImpl::expect_global_decl() {
if (!expect("struct declaration", Token::Type::kSemicolon))
return Failure::kErrored;
register_constructed(
builder_.Symbols().NameFor(str.value->impl()->name()), str.value);
builder_.AST().AddConstructedType(
const_cast<ast::Struct*>(str.value.ast));
register_constructed(builder_.Symbols().NameFor(str.value->name()),
str.value);
builder_.AST().AddConstructedType(str.value);
return true;
}
@ -565,8 +564,7 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
if (decl.errored)
return Failure::kErrored;
if ((decl->type.sem && decl->type.sem->UnwrapAll()->is_handle()) ||
(decl->type.ast && decl->type.ast->UnwrapAll()->is_handle())) {
if (decl->type && decl->type->UnwrapAll()->is_handle()) {
// handle types implicitly have the `UniformConstant` storage class.
if (explicit_sc.matched) {
return add_error(
@ -586,7 +584,7 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
// | sampled_texture_type LESS_THAN type_decl GREATER_THAN
// | multisampled_texture_type LESS_THAN type_decl GREATER_THAN
// | storage_texture_type LESS_THAN image_storage_type GREATER_THAN
Maybe<typ::Type> ParserImpl::texture_sampler_types() {
Maybe<ast::Type*> ParserImpl::texture_sampler_types() {
auto type = sampler_type();
if (type.matched)
return type;
@ -644,7 +642,7 @@ Maybe<typ::Type> ParserImpl::texture_sampler_types() {
// sampler_type
// : SAMPLER
// | SAMPLER_COMPARISON
Maybe<typ::Type> ParserImpl::sampler_type() {
Maybe<ast::Type*> ParserImpl::sampler_type() {
Source source;
if (match(Token::Type::kSampler, &source))
return builder_.ty.sampler(source, ast::SamplerKind::kSampler);
@ -686,7 +684,7 @@ Maybe<ast::TextureDimension> ParserImpl::sampled_texture_type() {
// external_texture_type
// : TEXTURE_EXTERNAL
Maybe<typ::Type> ParserImpl::external_texture_type() {
Maybe<ast::Type*> ParserImpl::external_texture_type() {
Source source;
if (match(Token::Type::kTextureExternal, &source)) {
return builder_.ty.external_texture(source);
@ -727,7 +725,7 @@ Maybe<ast::TextureDimension> ParserImpl::storage_texture_type() {
// | TEXTURE_DEPTH_2D_ARRAY
// | TEXTURE_DEPTH_CUBE
// | TEXTURE_DEPTH_CUBE_ARRAY
Maybe<typ::Type> ParserImpl::depth_texture_type() {
Maybe<ast::Type*> ParserImpl::depth_texture_type() {
Source source;
if (match(Token::Type::kTextureDepth2d, &source))
@ -921,7 +919,7 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
if (access_decos.size() > 1)
return add_error(ident.source, "multiple access decorations not allowed");
typ::Type ty = type.value;
ast::Type* ty = type.value;
for (auto* deco : access_decos) {
// If we have an access control decoration then we take it and wrap our
@ -965,7 +963,7 @@ Maybe<ast::StorageClass> ParserImpl::variable_storage_decoration() {
// type_alias
// : TYPE IDENT EQUAL type_decl
Maybe<typ::Alias> ParserImpl::type_alias() {
Maybe<ast::Alias*> ParserImpl::type_alias() {
auto t = peek();
if (!t.IsType())
return Failure::kNoMatch;
@ -1017,7 +1015,7 @@ Maybe<typ::Alias> ParserImpl::type_alias() {
// | MAT4x3 LESS_THAN type_decl GREATER_THAN
// | MAT4x4 LESS_THAN type_decl GREATER_THAN
// | texture_sampler_types
Maybe<typ::Type> ParserImpl::type_decl() {
Maybe<ast::Type*> ParserImpl::type_decl() {
auto decos = decoration_list();
if (decos.errored)
return Failure::kErrored;
@ -1034,7 +1032,7 @@ Maybe<typ::Type> ParserImpl::type_decl() {
return type;
}
Maybe<typ::Type> ParserImpl::type_decl(ast::DecorationList& decos) {
Maybe<ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
auto t = peek();
Source source;
if (match(Token::Type::kIdentifier, &source)) {
@ -1043,9 +1041,8 @@ Maybe<typ::Type> ParserImpl::type_decl(ast::DecorationList& decos) {
if (ty == nullptr)
return add_error(t, "unknown constructed type '" + t.to_str() + "'");
return typ::Type{builder_.create<ast::TypeName>(
source, builder_.Symbols().Register(t.to_str())),
ty};
return builder_.create<ast::TypeName>(
source, builder_.Symbols().Register(t.to_str()));
}
if (match(Token::Type::kBool, &source))
@ -1088,7 +1085,7 @@ Maybe<typ::Type> ParserImpl::type_decl(ast::DecorationList& decos) {
return Failure::kNoMatch;
}
Expect<typ::Type> ParserImpl::expect_type(const std::string& use) {
Expect<ast::Type*> ParserImpl::expect_type(const std::string& use) {
auto type = type_decl();
if (type.errored)
return Failure::kErrored;
@ -1097,12 +1094,12 @@ Expect<typ::Type> ParserImpl::expect_type(const std::string& use) {
return type.value;
}
Expect<typ::Type> ParserImpl::expect_type_decl_pointer(Token t) {
Expect<ast::Type*> ParserImpl::expect_type_decl_pointer(Token t) {
const char* use = "ptr declaration";
ast::StorageClass storage_class = ast::StorageClass::kNone;
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<typ::Type> {
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<ast::Type*> {
auto sc = expect_storage_class(use);
if (sc.errored)
return Failure::kErrored;
@ -1126,7 +1123,7 @@ Expect<typ::Type> ParserImpl::expect_type_decl_pointer(Token t) {
storage_class);
}
Expect<typ::Type> ParserImpl::expect_type_decl_vector(Token t) {
Expect<ast::Type*> ParserImpl::expect_type_decl_vector(Token t) {
uint32_t count = 2;
if (t.IsVec3())
count = 3;
@ -1143,14 +1140,14 @@ Expect<typ::Type> ParserImpl::expect_type_decl_vector(Token t) {
count);
}
Expect<typ::Type> ParserImpl::expect_type_decl_array(
Expect<ast::Type*> ParserImpl::expect_type_decl_array(
Token t,
ast::DecorationList decos) {
const char* use = "array declaration";
uint32_t size = 0;
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<typ::Type> {
auto subtype = expect_lt_gt_block(use, [&]() -> Expect<ast::Type*> {
auto type = expect_type(use);
if (type.errored)
return Failure::kErrored;
@ -1173,7 +1170,7 @@ Expect<typ::Type> ParserImpl::expect_type_decl_array(
size, std::move(decos));
}
Expect<typ::Type> ParserImpl::expect_type_decl_matrix(Token t) {
Expect<ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
uint32_t rows = 2;
uint32_t columns = 2;
if (t.IsMat3x2() || t.IsMat3x3() || t.IsMat3x4()) {
@ -1239,7 +1236,7 @@ Expect<ast::StorageClass> ParserImpl::expect_storage_class(
// struct_decl
// : struct_decoration_decl* STRUCT IDENT struct_body_decl
Maybe<typ::Struct> ParserImpl::struct_decl(ast::DecorationList& decos) {
Maybe<ast::Struct*> ParserImpl::struct_decl(ast::DecorationList& decos) {
auto t = peek();
auto source = t.source();
@ -1255,9 +1252,8 @@ Maybe<typ::Struct> ParserImpl::struct_decl(ast::DecorationList& decos) {
return Failure::kErrored;
auto sym = builder_.Symbols().Register(name.value);
auto* str =
create<ast::Struct>(source, sym, std::move(body.value), std::move(decos));
return typ::Struct{str, create<sem::StructType>(str)};
return create<ast::Struct>(source, sym, std::move(body.value),
std::move(decos));
}
// struct_body_decl
@ -1346,7 +1342,7 @@ Maybe<ast::Function*> ParserImpl::function_decl(ast::DecorationList& decos) {
// function_type_decl
// : type_decl
// | VOID
Maybe<typ::Type> ParserImpl::function_type_decl() {
Maybe<ast::Type*> ParserImpl::function_type_decl() {
Source source;
if (match(Token::Type::kVoid, &source))
return builder_.ty.void_(source);
@ -1381,7 +1377,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
}
}
typ::Type return_type;
ast::Type* return_type = nullptr;
ast::DecorationList return_decorations;
if (match(Token::Type::kArrow)) {
@ -1402,7 +1398,7 @@ Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
return_type = type.value;
}
if (Is<ast::Void>(return_type.ast)) {
if (Is<ast::Void>(return_type)) {
// crbug.com/tint/677: void has been removed from the language
deprecated(tok.source(),
"omit '-> void' for functions that do not return a value");

View File

@ -211,12 +211,12 @@ class ParserImpl {
/// @param type_in parsed type
/// @param name_in parsed identifier
/// @param source_in source to the identifier
TypedIdentifier(typ::Type type_in, std::string name_in, Source source_in);
TypedIdentifier(ast::Type* type_in, std::string name_in, Source source_in);
/// Destructor
~TypedIdentifier();
/// Parsed type.
typ::Type type;
ast::Type* type;
/// Parsed identifier.
std::string name;
/// Source to the identifier.
@ -239,7 +239,7 @@ class ParserImpl {
FunctionHeader(Source src,
std::string n,
ast::VariableList p,
typ::Type ret_ty,
ast::Type* ret_ty,
ast::DecorationList ret_decos);
/// Destructor
~FunctionHeader();
@ -255,7 +255,7 @@ class ParserImpl {
/// Function parameters
ast::VariableList params;
/// Function return type
typ::Type return_type;
ast::Type* return_type;
/// Function return type decorations
ast::DecorationList return_type_decorations;
};
@ -275,7 +275,7 @@ class ParserImpl {
VarDeclInfo(Source source_in,
std::string name_in,
ast::StorageClass storage_class_in,
typ::Type type_in);
ast::Type* type_in);
/// Destructor
~VarDeclInfo();
@ -286,7 +286,7 @@ class ParserImpl {
/// Variable storage class
ast::StorageClass storage_class;
/// Variable type
typ::Type type;
ast::Type* type = nullptr;
};
/// Creates a new parser using the given file
@ -365,12 +365,12 @@ class ParserImpl {
/// TODO(crbug.com/tint/724): Remove
/// @param name the constructed name
/// @param type the constructed type
void register_constructed(const std::string& name, sem::Type* type);
void register_constructed(const std::string& name, const ast::Type* type);
/// Retrieves a constructed type
/// TODO(crbug.com/tint/724): Remove
/// @param name The name to lookup
/// @returns the constructed type for `name` or `nullptr` if not found
sem::Type* get_constructed(const std::string& name);
const ast::Type* get_constructed(const std::string& name);
/// Parses the `translation_unit` grammar element
void translation_unit();
@ -400,15 +400,15 @@ class ParserImpl {
Maybe<ast::StorageClass> variable_storage_decoration();
/// Parses a `type_alias` grammar element
/// @returns the type alias or nullptr on error
Maybe<typ::Alias> type_alias();
Maybe<ast::Alias*> type_alias();
/// Parses a `type_decl` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<typ::Type> type_decl();
Maybe<ast::Type*> type_decl();
/// Parses a `type_decl` grammar element with the given pre-parsed
/// decorations.
/// @param decos the list of decorations for the type.
/// @returns the parsed Type or nullptr if none matched.
Maybe<typ::Type> type_decl(ast::DecorationList& decos);
Maybe<ast::Type*> type_decl(ast::DecorationList& decos);
/// Parses a `storage_class` grammar element, erroring on parse failure.
/// @param use a description of what was being parsed if an error was raised.
/// @returns the storage class or StorageClass::kNone if none matched
@ -417,7 +417,7 @@ class ParserImpl {
/// `struct_decoration_decl*` provided as `decos`.
/// @returns the struct type or nullptr on error
/// @param decos the list of decorations for the struct declaration.
Maybe<typ::Struct> struct_decl(ast::DecorationList& decos);
Maybe<ast::Struct*> struct_decl(ast::DecorationList& decos);
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
/// @returns the struct members
Expect<ast::StructMemberList> expect_struct_body_decl();
@ -434,10 +434,10 @@ class ParserImpl {
Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
/// Parses a `texture_sampler_types` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<typ::Type> texture_sampler_types();
Maybe<ast::Type*> texture_sampler_types();
/// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<typ::Type> sampler_type();
Maybe<ast::Type*> sampler_type();
/// Parses a `multisampled_texture_type` grammar element
/// @returns returns the multisample texture dimension or kNone if none
/// matched.
@ -451,17 +451,17 @@ class ParserImpl {
Maybe<ast::TextureDimension> storage_texture_type();
/// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<typ::Type> depth_texture_type();
Maybe<ast::Type*> depth_texture_type();
/// Parses a 'texture_external_type' grammar element
/// @returns the parsed Type or nullptr if none matched
Maybe<typ::Type> external_texture_type();
Maybe<ast::Type*> external_texture_type();
/// Parses a `image_storage_type` grammar element
/// @param use a description of what was being parsed if an error was raised
/// @returns returns the image format or kNone if none matched.
Expect<ast::ImageFormat> expect_image_storage_type(const std::string& use);
/// Parses a `function_type_decl` grammar element
/// @returns the parsed type or nullptr otherwise
Maybe<typ::Type> function_type_decl();
Maybe<ast::Type*> function_type_decl();
/// Parses a `function_header` grammar element
/// @returns the parsed function header
Maybe<FunctionHeader> function_header();
@ -827,12 +827,12 @@ class ParserImpl {
/// Used to ensure that all decorations are consumed.
bool expect_decorations_consumed(const ast::DecorationList& list);
Expect<typ::Type> expect_type_decl_pointer(Token t);
Expect<typ::Type> expect_type_decl_vector(Token t);
Expect<typ::Type> expect_type_decl_array(Token t, ast::DecorationList decos);
Expect<typ::Type> expect_type_decl_matrix(Token t);
Expect<ast::Type*> expect_type_decl_pointer(Token t);
Expect<ast::Type*> expect_type_decl_vector(Token t);
Expect<ast::Type*> expect_type_decl_array(Token t, ast::DecorationList decos);
Expect<ast::Type*> expect_type_decl_matrix(Token t);
Expect<typ::Type> expect_type(const std::string& use);
Expect<ast::Type*> expect_type(const std::string& use);
Maybe<ast::Statement*> non_block_statement();
Maybe<ast::Statement*> for_header_initializer();
@ -858,7 +858,7 @@ class ParserImpl {
uint32_t sync_depth_ = 0;
std::vector<Token::Type> sync_tokens_;
int silence_errors_ = 0;
std::unordered_map<std::string, sem::Type*> registered_constructs_;
std::unordered_map<std::string, const ast::Type*> registered_constructs_;
ProgramBuilder builder_;
size_t max_errors_ = 25;
};

View File

@ -34,11 +34,11 @@ TEST_F(ParserImplTest, DepthTextureType_2d) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d);
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, DepthTextureType_2dArray) {
@ -47,11 +47,11 @@ TEST_F(ParserImplTest, DepthTextureType_2dArray) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2dArray);
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2dArray);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 23u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 23u}}));
}
TEST_F(ParserImplTest, DepthTextureType_Cube) {
@ -60,11 +60,11 @@ TEST_F(ParserImplTest, DepthTextureType_Cube) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::kCube);
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::kCube);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
@ -73,11 +73,11 @@ TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::kCubeArray);
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::kCubeArray);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 25u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 25u}}));
}
} // namespace

View File

@ -32,7 +32,7 @@ TEST_F(ParserImplTest, ExternalTextureType) {
auto t = p->external_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
} // namespace

View File

@ -30,7 +30,7 @@ TEST_F(ParserImplTest, FunctionHeader) {
ASSERT_EQ(f->params.size(), 2u);
EXPECT_EQ(f->params[0]->symbol(), p->builder().Symbols().Get("a"));
EXPECT_EQ(f->params[1]->symbol(), p->builder().Symbols().Get("b"));
EXPECT_TRUE(f->return_type->Is<sem::Void>());
EXPECT_TRUE(f->return_type->Is<ast::Void>());
}
TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
@ -42,7 +42,7 @@ TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
EXPECT_EQ(f->name, "main");
ASSERT_EQ(f->params.size(), 1u);
EXPECT_EQ(f->params[0]->symbol(), p->builder().Symbols().Get("a"));
EXPECT_TRUE(f->return_type->Is<sem::Void>());
EXPECT_TRUE(f->return_type->Is<ast::Void>());
}
TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
@ -54,7 +54,7 @@ TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
EXPECT_EQ(f->name, "main");
EXPECT_EQ(f->params.size(), 0u);
EXPECT_TRUE(f->return_type->Is<sem::F32>());
EXPECT_TRUE(f->return_type->Is<ast::F32>());
ASSERT_EQ(f->return_type_decorations.size(), 1u);
auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
ASSERT_TRUE(loc != nullptr);

View File

@ -22,28 +22,25 @@ namespace {
TEST_F(ParserImplTest, FunctionTypeDecl_Void) {
auto p = parser("void");
auto* v = p->builder().create<sem::Void>();
auto e = p->function_type_decl();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(e.value, v);
EXPECT_EQ(e.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 5u}}));
EXPECT_TRUE(e.value->Is<ast::Void>());
EXPECT_EQ(e.value->source().range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
TEST_F(ParserImplTest, FunctionTypeDecl_Type) {
auto p = parser("vec2<f32>");
auto* f32 = p->builder().create<sem::F32>();
auto* vec2 = p->builder().create<sem::Vector>(f32, 2);
auto e = p->function_type_decl();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(e.value, vec2);
EXPECT_EQ(e.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 10u}}));
ASSERT_TRUE(e.value->Is<ast::Vector>());
EXPECT_EQ(e.value->As<ast::Vector>()->size(), 2u);
EXPECT_TRUE(e.value->As<ast::Vector>()->type()->Is<ast::F32>());
EXPECT_EQ(e.value->source().range, (Source::Range{{1u, 1u}, {1u, 10u}}));
}
TEST_F(ParserImplTest, FunctionTypeDecl_InvalidType) {

View File

@ -34,10 +34,10 @@ TEST_F(ParserImplTest, SamplerType_Sampler) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>());
EXPECT_FALSE(t->As<sem::Sampler>()->IsComparison());
ASSERT_TRUE(t->Is<ast::Sampler>());
EXPECT_FALSE(t->As<ast::Sampler>()->IsComparison());
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, SamplerType_ComparisonSampler) {
@ -46,10 +46,10 @@ TEST_F(ParserImplTest, SamplerType_ComparisonSampler) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>());
EXPECT_TRUE(t->As<sem::Sampler>()->IsComparison());
ASSERT_TRUE(t->Is<ast::Sampler>());
EXPECT_TRUE(t->As<ast::Sampler>()->IsComparison());
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
} // namespace

View File

@ -36,12 +36,10 @@ struct S {
EXPECT_FALSE(s.errored);
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("S"));
ASSERT_EQ(s->impl()->members().size(), 2u);
EXPECT_EQ(s->impl()->members()[0]->symbol(),
p->builder().Symbols().Register("a"));
EXPECT_EQ(s->impl()->members()[1]->symbol(),
p->builder().Symbols().Register("b"));
ASSERT_EQ(s->name(), p->builder().Symbols().Register("S"));
ASSERT_EQ(s->members().size(), 2u);
EXPECT_EQ(s->members()[0]->symbol(), p->builder().Symbols().Register("a"));
EXPECT_EQ(s->members()[1]->symbol(), p->builder().Symbols().Register("b"));
}
TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
@ -60,14 +58,12 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
EXPECT_FALSE(s.errored);
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("B"));
ASSERT_EQ(s->impl()->members().size(), 2u);
EXPECT_EQ(s->impl()->members()[0]->symbol(),
p->builder().Symbols().Register("a"));
EXPECT_EQ(s->impl()->members()[1]->symbol(),
p->builder().Symbols().Register("b"));
ASSERT_EQ(s->impl()->decorations().size(), 1u);
EXPECT_TRUE(s->impl()->decorations()[0]->Is<ast::StructBlockDecoration>());
ASSERT_EQ(s->name(), p->builder().Symbols().Register("B"));
ASSERT_EQ(s->members().size(), 2u);
EXPECT_EQ(s->members()[0]->symbol(), p->builder().Symbols().Register("a"));
EXPECT_EQ(s->members()[1]->symbol(), p->builder().Symbols().Register("b"));
ASSERT_EQ(s->decorations().size(), 1u);
EXPECT_TRUE(s->decorations()[0]->Is<ast::StructBlockDecoration>());
}
TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
@ -87,15 +83,13 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
EXPECT_FALSE(s.errored);
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->impl()->name(), p->builder().Symbols().Register("S"));
ASSERT_EQ(s->impl()->members().size(), 2u);
EXPECT_EQ(s->impl()->members()[0]->symbol(),
p->builder().Symbols().Register("a"));
EXPECT_EQ(s->impl()->members()[1]->symbol(),
p->builder().Symbols().Register("b"));
ASSERT_EQ(s->impl()->decorations().size(), 2u);
EXPECT_TRUE(s->impl()->decorations()[0]->Is<ast::StructBlockDecoration>());
EXPECT_TRUE(s->impl()->decorations()[1]->Is<ast::StructBlockDecoration>());
ASSERT_EQ(s->name(), p->builder().Symbols().Register("S"));
ASSERT_EQ(s->members().size(), 2u);
EXPECT_EQ(s->members()[0]->symbol(), p->builder().Symbols().Register("a"));
EXPECT_EQ(s->members()[1]->symbol(), p->builder().Symbols().Register("b"));
ASSERT_EQ(s->decorations().size(), 2u);
EXPECT_TRUE(s->decorations()[0]->Is<ast::StructBlockDecoration>());
EXPECT_TRUE(s->decorations()[1]->Is<ast::StructBlockDecoration>());
}
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
@ -110,7 +104,7 @@ TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
EXPECT_FALSE(s.errored);
EXPECT_TRUE(s.matched);
ASSERT_NE(s.value, nullptr);
ASSERT_EQ(s->impl()->members().size(), 0u);
ASSERT_EQ(s->members().size(), 0u);
}
TEST_F(ParserImplTest, StructDecl_MissingIdent) {

View File

@ -57,7 +57,7 @@ TEST_F(ParserImplTest, GetRegisteredType) {
auto* alias = p->get_constructed("my_alias");
ASSERT_NE(alias, nullptr);
ASSERT_EQ(alias, ty.i32());
EXPECT_TRUE(alias->Is<ast::I32>());
}
TEST_F(ParserImplTest, GetUnregisteredType) {

View File

@ -38,9 +38,9 @@ TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>());
ASSERT_FALSE(t->As<sem::Sampler>()->IsComparison());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
ASSERT_TRUE(t->Is<ast::Sampler>());
ASSERT_FALSE(t->As<ast::Sampler>()->IsComparison());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
@ -50,9 +50,9 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>());
ASSERT_TRUE(t->As<sem::Sampler>()->IsComparison());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
ASSERT_TRUE(t->Is<ast::Sampler>());
ASSERT_TRUE(t->As<ast::Sampler>()->IsComparison());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
@ -62,10 +62,10 @@ TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
@ -75,11 +75,11 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::SampledTexture>());
ASSERT_TRUE(t->As<sem::SampledTexture>()->type()->Is<sem::F32>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::SampledTexture>());
ASSERT_TRUE(t->As<ast::SampledTexture>()->type()->Is<ast::F32>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
@ -89,11 +89,11 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::SampledTexture>());
ASSERT_TRUE(t->As<sem::SampledTexture>()->type()->Is<sem::I32>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::SampledTexture>());
ASSERT_TRUE(t->As<ast::SampledTexture>()->type()->Is<ast::I32>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
@ -103,11 +103,11 @@ TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::SampledTexture>());
ASSERT_TRUE(t->As<sem::SampledTexture>()->type()->Is<sem::U32>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k3d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::SampledTexture>());
ASSERT_TRUE(t->As<ast::SampledTexture>()->type()->Is<ast::U32>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k3d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 16u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
@ -157,11 +157,11 @@ TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_I32) {
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::MultisampledTexture>());
ASSERT_TRUE(t->As<sem::MultisampledTexture>()->type()->Is<sem::I32>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 29u}}));
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::MultisampledTexture>());
ASSERT_TRUE(t->As<ast::MultisampledTexture>()->type()->Is<ast::I32>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 29u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) {
@ -212,12 +212,12 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Readonly1dR8Unorm) {
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::StorageTexture>());
EXPECT_EQ(t->As<sem::StorageTexture>()->image_format(),
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR8Unorm);
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 28u}}));
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k1d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 28u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR16Float) {
@ -228,12 +228,12 @@ TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR16Float) {
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>());
ASSERT_TRUE(t->Is<sem::StorageTexture>());
EXPECT_EQ(t->As<sem::StorageTexture>()->image_format(),
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::StorageTexture>());
EXPECT_EQ(t->As<ast::StorageTexture>()->image_format(),
ast::ImageFormat::kR16Float);
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 29u}}));
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 29u}}));
}
TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType) {

View File

@ -22,19 +22,16 @@ namespace {
TEST_F(ParserImplTest, TypeDecl_ParsesType) {
auto p = parser("type a = i32");
auto* i32 = p->builder().create<sem::I32>();
auto t = p->type_alias();
EXPECT_FALSE(p->has_error());
EXPECT_FALSE(t.errored);
EXPECT_TRUE(t.matched);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Alias>());
auto* alias = t->As<sem::Alias>();
ASSERT_TRUE(alias->type()->Is<sem::I32>());
ASSERT_EQ(alias->type(), i32);
ASSERT_TRUE(t->Is<ast::Alias>());
auto* alias = t->As<ast::Alias>();
ASSERT_TRUE(alias->type()->Is<ast::I32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 13u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 13u}}));
}
TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
@ -48,16 +45,11 @@ TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
EXPECT_FALSE(t.errored);
EXPECT_TRUE(t.matched);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Alias>());
auto* alias = t->As<sem::Alias>();
ASSERT_TRUE(t.value->Is<ast::Alias>());
auto* alias = t.value->As<ast::Alias>();
EXPECT_EQ(p->builder().Symbols().NameFor(alias->symbol()), "a");
ASSERT_TRUE(alias->type()->Is<sem::StructType>());
auto* s = alias->type()->As<sem::StructType>();
EXPECT_EQ(s->impl()->name(), p->builder().Symbols().Get("B"));
EXPECT_EQ(s->impl()->name(), p->builder().Symbols().Get("B"));
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 11u}}));
EXPECT_TRUE(alias->type()->Is<ast::TypeName>());
EXPECT_EQ(alias->source().range, (Source::Range{{1u, 1u}, {1u, 11u}}));
}
TEST_F(ParserImplTest, TypeDecl_MissingIdent) {

View File

@ -37,18 +37,14 @@ TEST_F(ParserImplTest, TypeDecl_Identifier) {
auto p = parser("A");
auto& builder = p->builder();
auto* int_type = builder.create<sem::I32>();
auto* alias_type =
builder.create<sem::Alias>(builder.Symbols().Register("A"), int_type);
auto alias_type = builder.ty.alias("A", builder.ty.i32());
p->register_constructed("A", alias_type);
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
auto* type_name = t.value.ast->As<ast::TypeName>();
ASSERT_NE(t.value, nullptr) << p->error();
auto* type_name = t.value->As<ast::TypeName>();
ASSERT_NE(type_name, nullptr);
EXPECT_EQ(p->builder().Symbols().Get("A"), type_name->name());
EXPECT_EQ(type_name->source().range, (Source::Range{{1u, 1u}, {1u, 2u}}));
@ -68,46 +64,34 @@ TEST_F(ParserImplTest, TypeDecl_Identifier_NotFound) {
TEST_F(ParserImplTest, TypeDecl_Bool) {
auto p = parser("bool");
auto& builder = p->builder();
auto* bool_type = builder.create<sem::Bool>();
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
EXPECT_EQ(t.value, bool_type);
ASSERT_TRUE(t.value.ast->Is<ast::Bool>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 5u}}));
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_TRUE(t.value->Is<ast::Bool>());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
TEST_F(ParserImplTest, TypeDecl_F32) {
auto p = parser("f32");
auto& builder = p->builder();
auto* float_type = builder.create<sem::F32>();
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
EXPECT_EQ(t.value, float_type);
ASSERT_TRUE(t.value.ast->Is<ast::F32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_TRUE(t.value->Is<ast::F32>());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
TEST_F(ParserImplTest, TypeDecl_I32) {
auto p = parser("i32");
auto& builder = p->builder();
auto* int_type = builder.create<sem::I32>();
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
EXPECT_EQ(t.value, int_type);
ASSERT_TRUE(t.value.ast->Is<ast::I32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_TRUE(t.value->Is<ast::I32>());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
TEST_F(ParserImplTest, TypeDecl_U32) {
@ -116,9 +100,9 @@ TEST_F(ParserImplTest, TypeDecl_U32) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_TRUE(t.value.ast->Is<ast::U32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_TRUE(t.value->Is<ast::U32>());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
struct VecData {
@ -139,11 +123,11 @@ TEST_P(VecTest, Parse) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
EXPECT_TRUE(t.value.ast->Is<ast::Vector>());
EXPECT_EQ(t.value.ast->As<ast::Vector>()->size(), params.count);
EXPECT_EQ(t.value.ast->source().range, params.range);
EXPECT_TRUE(t.value->Is<ast::Vector>());
EXPECT_EQ(t.value->As<ast::Vector>()->size(), params.count);
EXPECT_EQ(t.value->source().range, params.range);
}
INSTANTIATE_TEST_SUITE_P(
ParserImplTest,
@ -229,14 +213,14 @@ TEST_F(ParserImplTest, TypeDecl_Ptr) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Pointer>());
ASSERT_TRUE(t.value->Is<ast::Pointer>());
auto* ptr = t.value.ast->As<ast::Pointer>();
auto* ptr = t.value->As<ast::Pointer>();
ASSERT_TRUE(ptr->type()->Is<ast::F32>());
ASSERT_EQ(ptr->storage_class(), ast::StorageClass::kFunction);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 19u}}));
}
TEST_F(ParserImplTest, TypeDecl_Ptr_ToVec) {
@ -244,18 +228,18 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_ToVec) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Pointer>());
ASSERT_TRUE(t.value->Is<ast::Pointer>());
auto* ptr = t.value.ast->As<ast::Pointer>();
auto* ptr = t.value->As<ast::Pointer>();
ASSERT_TRUE(ptr->type()->Is<ast::Vector>());
ASSERT_EQ(ptr->storage_class(), ast::StorageClass::kFunction);
auto* vec = ptr->type()->As<ast::Vector>();
ASSERT_EQ(vec->size(), 2u);
ASSERT_TRUE(vec->type()->Is<ast::F32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 25}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 25}}));
}
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingLessThan) {
@ -343,16 +327,16 @@ TEST_F(ParserImplTest, TypeDecl_Array) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_EQ(a->size(), 5u);
ASSERT_TRUE(a->type()->Is<ast::F32>());
EXPECT_EQ(a->decorations().size(), 0u);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 14u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 14u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_Stride) {
@ -360,11 +344,11 @@ TEST_F(ParserImplTest, TypeDecl_Array_Stride) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_FALSE(a->IsRuntimeArray());
ASSERT_EQ(a->size(), 5u);
ASSERT_TRUE(a->type()->Is<ast::F32>());
@ -373,7 +357,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_Stride) {
auto* stride = a->decorations()[0];
ASSERT_TRUE(stride->Is<ast::StrideDecoration>());
ASSERT_EQ(stride->As<ast::StrideDecoration>()->stride(), 16u);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 16u}, {1u, 29u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 16u}, {1u, 29u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Stride) {
@ -381,11 +365,11 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Stride) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type()->Is<ast::F32>());
@ -393,7 +377,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Stride) {
auto* stride = a->decorations()[0];
ASSERT_TRUE(stride->Is<ast::StrideDecoration>());
ASSERT_EQ(stride->As<ast::StrideDecoration>()->stride(), 16u);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 16u}, {1u, 26u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 16u}, {1u, 26u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_OneBlock) {
@ -401,11 +385,11 @@ TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_OneBlock) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type()->Is<ast::F32>());
@ -415,7 +399,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_OneBlock) {
EXPECT_EQ(decos[0]->As<ast::StrideDecoration>()->stride(), 16u);
EXPECT_TRUE(decos[1]->Is<ast::StrideDecoration>());
EXPECT_EQ(decos[1]->As<ast::StrideDecoration>()->stride(), 32u);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 28u}, {1u, 38u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 28u}, {1u, 38u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_MultipleBlocks) {
@ -423,11 +407,11 @@ TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_MultipleBlocks) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type()->Is<ast::F32>());
@ -437,7 +421,7 @@ TEST_F(ParserImplTest, TypeDecl_Array_MultipleDecorations_MultipleBlocks) {
EXPECT_EQ(decos[0]->As<ast::StrideDecoration>()->stride(), 16u);
EXPECT_TRUE(decos[1]->Is<ast::StrideDecoration>());
EXPECT_EQ(decos[1]->As<ast::StrideDecoration>()->stride(), 32u);
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 31u}, {1u, 41u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 31u}, {1u, 41u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_Decoration_MissingArray) {
@ -527,14 +511,14 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type()->Is<ast::U32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 11u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 11u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Vec) {
@ -542,14 +526,14 @@ TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Vec) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
ASSERT_TRUE(t.value.ast->Is<ast::Array>());
ASSERT_TRUE(t.value->Is<ast::Array>());
auto* a = t.value.ast->As<ast::Array>();
auto* a = t.value->As<ast::Array>();
ASSERT_TRUE(a->IsRuntimeArray());
ASSERT_TRUE(a->type()->is_unsigned_integer_vector());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, TypeDecl_Array_BadType) {
@ -641,13 +625,13 @@ TEST_P(MatrixTest, Parse) {
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
EXPECT_TRUE(t.value.ast->Is<ast::Matrix>());
auto* mat = t.value.ast->As<ast::Matrix>();
EXPECT_TRUE(t.value->Is<ast::Matrix>());
auto* mat = t.value->As<ast::Matrix>();
EXPECT_EQ(mat->rows(), params.rows);
EXPECT_EQ(mat->columns(), params.columns);
EXPECT_EQ(t.value.ast->source().range, params.range);
EXPECT_EQ(t.value->source().range, params.range);
}
INSTANTIATE_TEST_SUITE_P(
ParserImplTest,
@ -763,35 +747,26 @@ INSTANTIATE_TEST_SUITE_P(ParserImplTest,
TEST_F(ParserImplTest, TypeDecl_Sampler) {
auto p = parser("sampler");
auto& builder = p->builder();
auto type = builder.ty.sampler(ast::SamplerKind::kSampler);
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr) << p->error();
EXPECT_EQ(t.value, type);
ASSERT_TRUE(t.value.ast->Is<ast::Sampler>());
ASSERT_FALSE(t.value.ast->As<ast::Sampler>()->IsComparison());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
ASSERT_NE(t.value, nullptr) << p->error();
ASSERT_TRUE(t.value->Is<ast::Sampler>());
ASSERT_FALSE(t.value->As<ast::Sampler>()->IsComparison());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 8u}}));
}
TEST_F(ParserImplTest, TypeDecl_Texture) {
auto p = parser("texture_cube<f32>");
auto& builder = p->builder();
auto* type = builder.create<sem::SampledTexture>(ast::TextureDimension::kCube,
ty.f32());
auto t = p->type_decl();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value.ast, nullptr);
EXPECT_EQ(t.value, type);
ASSERT_TRUE(t.value.ast->Is<ast::Texture>());
ASSERT_TRUE(t.value.ast->Is<ast::SampledTexture>());
ASSERT_TRUE(t.value.ast->As<ast::SampledTexture>()->type()->Is<ast::F32>());
EXPECT_EQ(t.value.ast->source().range, (Source::Range{{1u, 1u}, {1u, 18u}}));
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t.value->Is<ast::Texture>());
ASSERT_TRUE(t.value->Is<ast::SampledTexture>());
ASSERT_TRUE(t.value->As<ast::SampledTexture>()->type()->Is<ast::F32>());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 18u}}));
}
} // namespace

View File

@ -27,10 +27,10 @@ TEST_F(ParserImplTest, VariableDecl_Parses) {
EXPECT_FALSE(v.errored);
EXPECT_EQ(v->name, "my_var");
EXPECT_NE(v->type, nullptr);
EXPECT_TRUE(v->type->Is<sem::F32>());
EXPECT_TRUE(v->type->Is<ast::F32>());
EXPECT_EQ(v->source.range, (Source::Range{{1u, 5u}, {1u, 11u}}));
EXPECT_EQ(v->type.ast->source().range, (Source::Range{{1u, 14u}, {1u, 17u}}));
EXPECT_EQ(v->type->source().range, (Source::Range{{1u, 14u}, {1u, 17u}}));
}
TEST_F(ParserImplTest, VariableDecl_MissingVar) {
@ -60,7 +60,7 @@ TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
EXPECT_FALSE(v.errored);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(v->name, "my_var");
EXPECT_TRUE(v->type->Is<sem::F32>());
EXPECT_TRUE(v->type->Is<ast::F32>());
EXPECT_EQ(v->storage_class, ast::StorageClass::kPrivate);
EXPECT_EQ(v->source.range.begin.line, 1u);

View File

@ -28,11 +28,10 @@ TEST_F(ParserImplTest, VariableIdentDecl_Parses) {
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<sem::F32>());
ASSERT_TRUE(decl->type->Is<ast::F32>());
EXPECT_EQ(decl->source.range, (Source::Range{{1u, 1u}, {1u, 7u}}));
EXPECT_EQ(decl->type.ast->source().range,
(Source::Range{{1u, 10u}, {1u, 13u}}));
EXPECT_EQ(decl->type->source().range, (Source::Range{{1u, 10u}, {1u, 13u}}));
}
TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent) {
@ -83,10 +82,10 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Read) {
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<sem::AccessControl>());
EXPECT_TRUE(decl->type->As<sem::AccessControl>()->IsReadOnly());
ASSERT_TRUE(decl->type->Is<ast::AccessControl>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadOnly());
ASSERT_TRUE(
decl->type->As<sem::AccessControl>()->type()->Is<sem::StorageTexture>());
decl->type->As<ast::AccessControl>()->type()->Is<ast::StorageTexture>());
}
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Write) {
@ -97,10 +96,10 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithTextureAccessDeco_Write) {
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<sem::AccessControl>());
EXPECT_TRUE(decl->type->As<sem::AccessControl>()->IsWriteOnly());
ASSERT_TRUE(decl->type->Is<ast::AccessControl>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsWriteOnly());
ASSERT_TRUE(
decl->type->As<sem::AccessControl>()->type()->Is<sem::StorageTexture>());
decl->type->As<ast::AccessControl>()->type()->Is<ast::StorageTexture>());
}
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) {
@ -123,8 +122,8 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) {
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<sem::AccessControl>());
EXPECT_TRUE(decl->type->As<sem::AccessControl>()->IsReadOnly());
ASSERT_TRUE(decl->type->Is<ast::AccessControl>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadOnly());
}
TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) {
@ -147,8 +146,8 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) {
ASSERT_FALSE(decl.errored);
ASSERT_EQ(decl->name, "my_var");
ASSERT_NE(decl->type, nullptr);
ASSERT_TRUE(decl->type->Is<sem::AccessControl>());
EXPECT_TRUE(decl->type->As<sem::AccessControl>()->IsReadWrite());
ASSERT_TRUE(decl->type->Is<ast::AccessControl>());
EXPECT_TRUE(decl->type->As<ast::AccessControl>()->IsReadWrite());
}
TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) {