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 "gtest/gtest-spi.h"
16 #include "src/ast/override_decoration.h"
17 #include "src/ast/test_helper.h"
18
19 namespace tint {
20 namespace ast {
21 namespace {
22
23 using VariableTest = TestHelper;
24
TEST_F(VariableTest,Creation)25 TEST_F(VariableTest, Creation) {
26 auto* v = Var("my_var", ty.i32(), StorageClass::kFunction);
27
28 EXPECT_EQ(v->symbol, Symbol(1, ID()));
29 EXPECT_EQ(v->declared_storage_class, StorageClass::kFunction);
30 EXPECT_TRUE(v->type->Is<ast::I32>());
31 EXPECT_EQ(v->source.range.begin.line, 0u);
32 EXPECT_EQ(v->source.range.begin.column, 0u);
33 EXPECT_EQ(v->source.range.end.line, 0u);
34 EXPECT_EQ(v->source.range.end.column, 0u);
35 }
36
TEST_F(VariableTest,CreationWithSource)37 TEST_F(VariableTest, CreationWithSource) {
38 auto* v = Var(
39 Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}},
40 "i", ty.f32(), StorageClass::kPrivate, nullptr, DecorationList{});
41
42 EXPECT_EQ(v->symbol, Symbol(1, ID()));
43 EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
44 EXPECT_TRUE(v->type->Is<ast::F32>());
45 EXPECT_EQ(v->source.range.begin.line, 27u);
46 EXPECT_EQ(v->source.range.begin.column, 4u);
47 EXPECT_EQ(v->source.range.end.line, 27u);
48 EXPECT_EQ(v->source.range.end.column, 5u);
49 }
50
TEST_F(VariableTest,CreationEmpty)51 TEST_F(VariableTest, CreationEmpty) {
52 auto* v = Var(
53 Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}},
54 "a_var", ty.i32(), StorageClass::kWorkgroup, nullptr, DecorationList{});
55
56 EXPECT_EQ(v->symbol, Symbol(1, ID()));
57 EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
58 EXPECT_TRUE(v->type->Is<ast::I32>());
59 EXPECT_EQ(v->source.range.begin.line, 27u);
60 EXPECT_EQ(v->source.range.begin.column, 4u);
61 EXPECT_EQ(v->source.range.end.line, 27u);
62 EXPECT_EQ(v->source.range.end.column, 7u);
63 }
64
TEST_F(VariableTest,Assert_MissingSymbol)65 TEST_F(VariableTest, Assert_MissingSymbol) {
66 EXPECT_FATAL_FAILURE(
67 {
68 ProgramBuilder b;
69 b.Var("", b.ty.i32(), StorageClass::kNone);
70 },
71 "internal compiler error");
72 }
73
TEST_F(VariableTest,Assert_DifferentProgramID_Symbol)74 TEST_F(VariableTest, Assert_DifferentProgramID_Symbol) {
75 EXPECT_FATAL_FAILURE(
76 {
77 ProgramBuilder b1;
78 ProgramBuilder b2;
79 b1.Var(b2.Sym("x"), b1.ty.f32(), StorageClass::kNone);
80 },
81 "internal compiler error");
82 }
83
TEST_F(VariableTest,Assert_DifferentProgramID_Constructor)84 TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
85 EXPECT_FATAL_FAILURE(
86 {
87 ProgramBuilder b1;
88 ProgramBuilder b2;
89 b1.Var("x", b1.ty.f32(), StorageClass::kNone, b2.Expr(1.2f));
90 },
91 "internal compiler error");
92 }
93
TEST_F(VariableTest,WithDecorations)94 TEST_F(VariableTest, WithDecorations) {
95 auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
96 DecorationList{
97 create<LocationDecoration>(1),
98 create<BuiltinDecoration>(Builtin::kPosition),
99 create<OverrideDecoration>(1200),
100 });
101
102 auto& decorations = var->decorations;
103 EXPECT_TRUE(ast::HasDecoration<ast::LocationDecoration>(decorations));
104 EXPECT_TRUE(ast::HasDecoration<ast::BuiltinDecoration>(decorations));
105 EXPECT_TRUE(ast::HasDecoration<ast::OverrideDecoration>(decorations));
106
107 auto* location = ast::GetDecoration<ast::LocationDecoration>(decorations);
108 ASSERT_NE(nullptr, location);
109 EXPECT_EQ(1u, location->value);
110 }
111
TEST_F(VariableTest,BindingPoint)112 TEST_F(VariableTest, BindingPoint) {
113 auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
114 DecorationList{
115 create<BindingDecoration>(2),
116 create<GroupDecoration>(1),
117 });
118 EXPECT_TRUE(var->BindingPoint());
119 ASSERT_NE(var->BindingPoint().binding, nullptr);
120 ASSERT_NE(var->BindingPoint().group, nullptr);
121 EXPECT_EQ(var->BindingPoint().binding->value, 2u);
122 EXPECT_EQ(var->BindingPoint().group->value, 1u);
123 }
124
TEST_F(VariableTest,BindingPointoDecorations)125 TEST_F(VariableTest, BindingPointoDecorations) {
126 auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
127 DecorationList{});
128 EXPECT_FALSE(var->BindingPoint());
129 EXPECT_EQ(var->BindingPoint().group, nullptr);
130 EXPECT_EQ(var->BindingPoint().binding, nullptr);
131 }
132
TEST_F(VariableTest,BindingPointMissingGroupDecoration)133 TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
134 auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
135 DecorationList{
136 create<BindingDecoration>(2),
137 });
138 EXPECT_FALSE(var->BindingPoint());
139 ASSERT_NE(var->BindingPoint().binding, nullptr);
140 EXPECT_EQ(var->BindingPoint().binding->value, 2u);
141 EXPECT_EQ(var->BindingPoint().group, nullptr);
142 }
143
TEST_F(VariableTest,BindingPointMissingBindingDecoration)144 TEST_F(VariableTest, BindingPointMissingBindingDecoration) {
145 auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
146 DecorationList{create<GroupDecoration>(1)});
147 EXPECT_FALSE(var->BindingPoint());
148 ASSERT_NE(var->BindingPoint().group, nullptr);
149 EXPECT_EQ(var->BindingPoint().group->value, 1u);
150 EXPECT_EQ(var->BindingPoint().binding, nullptr);
151 }
152
153 } // namespace
154 } // namespace ast
155 } // namespace tint
156