• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/reader/wgsl/parser_impl_test_helper.h"
16 
17 namespace tint {
18 namespace reader {
19 namespace wgsl {
20 namespace {
21 
TEST_F(ParserImplTest,FunctionHeader)22 TEST_F(ParserImplTest, FunctionHeader) {
23   auto p = parser("fn main(a : i32, b: f32)");
24   auto f = p->function_header();
25   ASSERT_FALSE(p->has_error()) << p->error();
26   EXPECT_TRUE(f.matched);
27   EXPECT_FALSE(f.errored);
28 
29   EXPECT_EQ(f->name, "main");
30   ASSERT_EQ(f->params.size(), 2u);
31   EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get("a"));
32   EXPECT_EQ(f->params[1]->symbol, p->builder().Symbols().Get("b"));
33   EXPECT_TRUE(f->return_type->Is<ast::Void>());
34 }
35 
TEST_F(ParserImplTest,FunctionHeader_TrailingComma)36 TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
37   auto p = parser("fn main(a :i32,)");
38   auto f = p->function_header();
39   EXPECT_TRUE(f.matched);
40   EXPECT_FALSE(f.errored);
41 
42   EXPECT_EQ(f->name, "main");
43   ASSERT_EQ(f->params.size(), 1u);
44   EXPECT_EQ(f->params[0]->symbol, p->builder().Symbols().Get("a"));
45   EXPECT_TRUE(f->return_type->Is<ast::Void>());
46 }
47 
TEST_F(ParserImplTest,FunctionHeader_DecoratedReturnType)48 TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType) {
49   auto p = parser("fn main() -> [[location(1)]] f32");
50   auto f = p->function_header();
51   ASSERT_FALSE(p->has_error()) << p->error();
52   EXPECT_TRUE(f.matched);
53   EXPECT_FALSE(f.errored);
54 
55   EXPECT_EQ(f->name, "main");
56   EXPECT_EQ(f->params.size(), 0u);
57   EXPECT_TRUE(f->return_type->Is<ast::F32>());
58   ASSERT_EQ(f->return_type_decorations.size(), 1u);
59   auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
60   ASSERT_TRUE(loc != nullptr);
61   EXPECT_EQ(loc->value, 1u);
62 }
63 
TEST_F(ParserImplTest,FunctionHeader_InvariantReturnType)64 TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
65   auto p = parser("fn main() -> [[invariant]] f32");
66   auto f = p->function_header();
67   ASSERT_FALSE(p->has_error()) << p->error();
68   EXPECT_TRUE(f.matched);
69   EXPECT_FALSE(f.errored);
70 
71   EXPECT_EQ(f->name, "main");
72   EXPECT_EQ(f->params.size(), 0u);
73   EXPECT_TRUE(f->return_type->Is<ast::F32>());
74   ASSERT_EQ(f->return_type_decorations.size(), 1u);
75   EXPECT_TRUE(f->return_type_decorations[0]->Is<ast::InvariantDecoration>());
76 }
77 
TEST_F(ParserImplTest,FunctionHeader_DecoratedReturnType_WithArrayStride)78 TEST_F(ParserImplTest, FunctionHeader_DecoratedReturnType_WithArrayStride) {
79   auto p = parser("fn main() -> [[location(1), stride(16)]] array<f32, 4>");
80   auto f = p->function_header();
81   ASSERT_FALSE(p->has_error()) << p->error();
82   EXPECT_TRUE(f.matched);
83   EXPECT_FALSE(f.errored);
84 
85   EXPECT_EQ(f->name, "main");
86   EXPECT_EQ(f->params.size(), 0u);
87   ASSERT_EQ(f->return_type_decorations.size(), 1u);
88   auto* loc = f->return_type_decorations[0]->As<ast::LocationDecoration>();
89   ASSERT_TRUE(loc != nullptr);
90   EXPECT_EQ(loc->value, 1u);
91 
92   auto* array_type = f->return_type->As<ast::Array>();
93   ASSERT_EQ(array_type->decorations.size(), 1u);
94   auto* stride = array_type->decorations[0]->As<ast::StrideDecoration>();
95   ASSERT_TRUE(stride != nullptr);
96   EXPECT_EQ(stride->stride, 16u);
97 }
98 
TEST_F(ParserImplTest,FunctionHeader_MissingIdent)99 TEST_F(ParserImplTest, FunctionHeader_MissingIdent) {
100   auto p = parser("fn ()");
101   auto f = p->function_header();
102   EXPECT_FALSE(f.matched);
103   EXPECT_TRUE(f.errored);
104   EXPECT_TRUE(p->has_error());
105   EXPECT_EQ(p->error(), "1:4: expected identifier for function declaration");
106 }
107 
TEST_F(ParserImplTest,FunctionHeader_InvalidIdent)108 TEST_F(ParserImplTest, FunctionHeader_InvalidIdent) {
109   auto p = parser("fn 133main() -> i32");
110   auto f = p->function_header();
111   EXPECT_FALSE(f.matched);
112   EXPECT_TRUE(f.errored);
113   EXPECT_TRUE(p->has_error());
114   EXPECT_EQ(p->error(), "1:4: expected identifier for function declaration");
115 }
116 
TEST_F(ParserImplTest,FunctionHeader_MissingParenLeft)117 TEST_F(ParserImplTest, FunctionHeader_MissingParenLeft) {
118   auto p = parser("fn main) -> i32");
119   auto f = p->function_header();
120   EXPECT_FALSE(f.matched);
121   EXPECT_TRUE(f.errored);
122   EXPECT_TRUE(p->has_error());
123   EXPECT_EQ(p->error(), "1:8: expected '(' for function declaration");
124 }
125 
TEST_F(ParserImplTest,FunctionHeader_InvalidParamList)126 TEST_F(ParserImplTest, FunctionHeader_InvalidParamList) {
127   auto p = parser("fn main(a :i32, ,) -> i32");
128   auto f = p->function_header();
129   EXPECT_FALSE(f.matched);
130   EXPECT_TRUE(f.errored);
131   EXPECT_TRUE(p->has_error());
132   EXPECT_EQ(p->error(), "1:17: expected ')' for function declaration");
133 }
134 
TEST_F(ParserImplTest,FunctionHeader_MissingParenRight)135 TEST_F(ParserImplTest, FunctionHeader_MissingParenRight) {
136   auto p = parser("fn main( -> i32");
137   auto f = p->function_header();
138   EXPECT_FALSE(f.matched);
139   EXPECT_TRUE(f.errored);
140   EXPECT_TRUE(p->has_error());
141   EXPECT_EQ(p->error(), "1:10: expected ')' for function declaration");
142 }
143 
TEST_F(ParserImplTest,FunctionHeader_MissingReturnType)144 TEST_F(ParserImplTest, FunctionHeader_MissingReturnType) {
145   auto p = parser("fn main() ->");
146   auto f = p->function_header();
147   EXPECT_FALSE(f.matched);
148   EXPECT_TRUE(f.errored);
149   EXPECT_TRUE(p->has_error());
150   EXPECT_EQ(p->error(), "1:13: unable to determine function return type");
151 }
152 
153 }  // namespace
154 }  // namespace wgsl
155 }  // namespace reader
156 }  // namespace tint
157