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

View File

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

View File

@ -34,11 +34,11 @@ TEST_F(ParserImplTest, DepthTextureType_2d) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>()); ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2d); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_FALSE(p->has_error()); 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) { TEST_F(ParserImplTest, DepthTextureType_2dArray) {
@ -47,11 +47,11 @@ TEST_F(ParserImplTest, DepthTextureType_2dArray) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>()); ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::k2dArray); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2dArray);
EXPECT_FALSE(p->has_error()); 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) { TEST_F(ParserImplTest, DepthTextureType_Cube) {
@ -60,11 +60,11 @@ TEST_F(ParserImplTest, DepthTextureType_Cube) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>()); ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::kCube); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::kCube);
EXPECT_FALSE(p->has_error()); 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) { TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
@ -73,11 +73,11 @@ TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Texture>()); ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<sem::DepthTexture>()); ASSERT_TRUE(t->Is<ast::DepthTexture>());
EXPECT_EQ(t->As<sem::Texture>()->dim(), ast::TextureDimension::kCubeArray); EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::kCubeArray);
EXPECT_FALSE(p->has_error()); 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 } // namespace

View File

@ -32,7 +32,7 @@ TEST_F(ParserImplTest, ExternalTextureType) {
auto t = p->external_texture_type(); auto t = p->external_texture_type();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); 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 } // namespace

View File

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

View File

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

View File

@ -34,10 +34,10 @@ TEST_F(ParserImplTest, SamplerType_Sampler) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>()); ASSERT_TRUE(t->Is<ast::Sampler>());
EXPECT_FALSE(t->As<sem::Sampler>()->IsComparison()); EXPECT_FALSE(t->As<ast::Sampler>()->IsComparison());
EXPECT_FALSE(p->has_error()); 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) { TEST_F(ParserImplTest, SamplerType_ComparisonSampler) {
@ -46,10 +46,10 @@ TEST_F(ParserImplTest, SamplerType_ComparisonSampler) {
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored); EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr); ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<sem::Sampler>()); ASSERT_TRUE(t->Is<ast::Sampler>());
EXPECT_TRUE(t->As<sem::Sampler>()->IsComparison()); EXPECT_TRUE(t->As<ast::Sampler>()->IsComparison());
EXPECT_FALSE(p->has_error()); 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 } // namespace

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,10 +27,10 @@ TEST_F(ParserImplTest, VariableDecl_Parses) {
EXPECT_FALSE(v.errored); EXPECT_FALSE(v.errored);
EXPECT_EQ(v->name, "my_var"); EXPECT_EQ(v->name, "my_var");
EXPECT_NE(v->type, nullptr); 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->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) { TEST_F(ParserImplTest, VariableDecl_MissingVar) {
@ -60,7 +60,7 @@ TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
EXPECT_FALSE(v.errored); EXPECT_FALSE(v.errored);
EXPECT_FALSE(p->has_error()); EXPECT_FALSE(p->has_error());
EXPECT_EQ(v->name, "my_var"); 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->storage_class, ast::StorageClass::kPrivate);
EXPECT_EQ(v->source.range.begin.line, 1u); EXPECT_EQ(v->source.range.begin.line, 1u);

View File

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