• 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 "gtest/gtest-spi.h"
16 #include "src/ast/test_helper.h"
17 #include "src/clone_context.h"
18 
19 namespace tint {
20 namespace ast {
21 namespace {
22 
23 using ModuleTest = TestHelper;
24 
TEST_F(ModuleTest,Creation)25 TEST_F(ModuleTest, Creation) {
26   EXPECT_EQ(Program(std::move(*this)).AST().Functions().size(), 0u);
27 }
28 
TEST_F(ModuleTest,LookupFunction)29 TEST_F(ModuleTest, LookupFunction) {
30   auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
31                     ast::DecorationList{});
32 
33   Program program(std::move(*this));
34   EXPECT_EQ(func,
35             program.AST().Functions().Find(program.Symbols().Get("main")));
36 }
37 
TEST_F(ModuleTest,LookupFunctionMissing)38 TEST_F(ModuleTest, LookupFunctionMissing) {
39   Program program(std::move(*this));
40   EXPECT_EQ(nullptr,
41             program.AST().Functions().Find(program.Symbols().Get("Missing")));
42 }
43 
TEST_F(ModuleTest,Assert_Null_GlobalVariable)44 TEST_F(ModuleTest, Assert_Null_GlobalVariable) {
45   EXPECT_FATAL_FAILURE(
46       {
47         ProgramBuilder builder;
48         builder.AST().AddGlobalVariable(nullptr);
49       },
50       "internal compiler error");
51 }
52 
TEST_F(ModuleTest,Assert_Null_TypeDecl)53 TEST_F(ModuleTest, Assert_Null_TypeDecl) {
54   EXPECT_FATAL_FAILURE(
55       {
56         ProgramBuilder builder;
57         builder.AST().AddTypeDecl(nullptr);
58       },
59       "internal compiler error");
60 }
61 
TEST_F(ModuleTest,Assert_DifferentProgramID_Function)62 TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
63   EXPECT_FATAL_FAILURE(
64       {
65         ProgramBuilder b1;
66         ProgramBuilder b2;
67         b1.AST().AddFunction(b2.create<ast::Function>(
68             b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
69             b2.Block(), DecorationList{}, DecorationList{}));
70       },
71       "internal compiler error");
72 }
73 
TEST_F(ModuleTest,Assert_DifferentProgramID_GlobalVariable)74 TEST_F(ModuleTest, Assert_DifferentProgramID_GlobalVariable) {
75   EXPECT_FATAL_FAILURE(
76       {
77         ProgramBuilder b1;
78         ProgramBuilder b2;
79         b1.AST().AddGlobalVariable(
80             b2.Var("var", b2.ty.i32(), ast::StorageClass::kPrivate));
81       },
82       "internal compiler error");
83 }
84 
TEST_F(ModuleTest,Assert_Null_Function)85 TEST_F(ModuleTest, Assert_Null_Function) {
86   EXPECT_FATAL_FAILURE(
87       {
88         ProgramBuilder builder;
89         builder.AST().AddFunction(nullptr);
90       },
91       "internal compiler error");
92 }
93 
TEST_F(ModuleTest,CloneOrder)94 TEST_F(ModuleTest, CloneOrder) {
95   // Create a program with a function, alias decl and var decl.
96   Program p = [] {
97     ProgramBuilder b;
98     b.Func("F", {}, b.ty.void_(), {});
99     b.Alias("A", b.ty.u32());
100     b.Global("V", b.ty.i32(), ast::StorageClass::kPrivate);
101     return Program(std::move(b));
102   }();
103 
104   // Clone the program, using ReplaceAll() to create new module-scope
105   // declarations. We want to test that these are added just before the
106   // declaration that triggered the ReplaceAll().
107   ProgramBuilder cloned;
108   CloneContext ctx(&cloned, &p);
109   ctx.ReplaceAll([&](const ast::Function*) -> const ast::Function* {
110     ctx.dst->Alias("inserted_before_F", cloned.ty.u32());
111     return nullptr;
112   });
113   ctx.ReplaceAll([&](const ast::Alias*) -> const ast::Alias* {
114     ctx.dst->Alias("inserted_before_A", cloned.ty.u32());
115     return nullptr;
116   });
117   ctx.ReplaceAll([&](const ast::Variable*) -> const ast::Variable* {
118     ctx.dst->Alias("inserted_before_V", cloned.ty.u32());
119     return nullptr;
120   });
121   ctx.Clone();
122 
123   auto& decls = cloned.AST().GlobalDeclarations();
124   ASSERT_EQ(decls.size(), 6u);
125   EXPECT_TRUE(decls[1]->Is<ast::Function>());
126   EXPECT_TRUE(decls[3]->Is<ast::Alias>());
127   EXPECT_TRUE(decls[5]->Is<ast::Variable>());
128 
129   ASSERT_TRUE(decls[0]->Is<ast::Alias>());
130   ASSERT_TRUE(decls[2]->Is<ast::Alias>());
131   ASSERT_TRUE(decls[4]->Is<ast::Alias>());
132 
133   ASSERT_EQ(cloned.Symbols().NameFor(decls[0]->As<ast::Alias>()->name),
134             "inserted_before_F");
135   ASSERT_EQ(cloned.Symbols().NameFor(decls[2]->As<ast::Alias>()->name),
136             "inserted_before_A");
137   ASSERT_EQ(cloned.Symbols().NameFor(decls[4]->As<ast::Alias>()->name),
138             "inserted_before_V");
139 }
140 
141 }  // namespace
142 }  // namespace ast
143 }  // namespace tint
144