• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/program_builder.h"
16 
17 #include "src/ast/assignment_statement.h"
18 #include "src/ast/call_statement.h"
19 #include "src/ast/variable_decl_statement.h"
20 #include "src/debug.h"
21 #include "src/demangler.h"
22 #include "src/sem/expression.h"
23 #include "src/sem/variable.h"
24 
25 namespace tint {
26 
27 ProgramBuilder::VarOptionals::~VarOptionals() = default;
28 
ProgramBuilder()29 ProgramBuilder::ProgramBuilder()
30     : id_(ProgramID::New()),
31       ast_(ast_nodes_.Create<ast::Module>(id_, Source{})) {}
32 
ProgramBuilder(ProgramBuilder && rhs)33 ProgramBuilder::ProgramBuilder(ProgramBuilder&& rhs)
34     : id_(std::move(rhs.id_)),
35       types_(std::move(rhs.types_)),
36       ast_nodes_(std::move(rhs.ast_nodes_)),
37       sem_nodes_(std::move(rhs.sem_nodes_)),
38       ast_(rhs.ast_),
39       sem_(std::move(rhs.sem_)),
40       symbols_(std::move(rhs.symbols_)),
41       diagnostics_(std::move(rhs.diagnostics_)),
42       transforms_applied_(std::move(rhs.transforms_applied_)) {
43   rhs.MarkAsMoved();
44 }
45 
46 ProgramBuilder::~ProgramBuilder() = default;
47 
operator =(ProgramBuilder && rhs)48 ProgramBuilder& ProgramBuilder::operator=(ProgramBuilder&& rhs) {
49   rhs.MarkAsMoved();
50   AssertNotMoved();
51   id_ = std::move(rhs.id_);
52   types_ = std::move(rhs.types_);
53   ast_nodes_ = std::move(rhs.ast_nodes_);
54   sem_nodes_ = std::move(rhs.sem_nodes_);
55   ast_ = rhs.ast_;
56   sem_ = std::move(rhs.sem_);
57   symbols_ = std::move(rhs.symbols_);
58   diagnostics_ = std::move(rhs.diagnostics_);
59   transforms_applied_ = std::move(rhs.transforms_applied_);
60   return *this;
61 }
62 
Wrap(const Program * program)63 ProgramBuilder ProgramBuilder::Wrap(const Program* program) {
64   ProgramBuilder builder;
65   builder.id_ = program->ID();
66   builder.types_ = sem::Manager::Wrap(program->Types());
67   builder.ast_ = builder.create<ast::Module>(
68       program->AST().source, program->AST().GlobalDeclarations());
69   builder.sem_ = sem::Info::Wrap(program->Sem());
70   builder.symbols_ = program->Symbols();
71   builder.diagnostics_ = program->Diagnostics();
72   builder.transforms_applied_ = program->TransformsApplied();
73   return builder;
74 }
75 
IsValid() const76 bool ProgramBuilder::IsValid() const {
77   return !diagnostics_.contains_errors();
78 }
79 
MarkAsMoved()80 void ProgramBuilder::MarkAsMoved() {
81   AssertNotMoved();
82   moved_ = true;
83 }
84 
AssertNotMoved() const85 void ProgramBuilder::AssertNotMoved() const {
86   if (moved_) {
87     TINT_ICE(ProgramBuilder, const_cast<ProgramBuilder*>(this)->diagnostics_)
88         << "Attempting to use ProgramBuilder after it has been moved";
89   }
90 }
91 
TypeOf(const ast::Expression * expr) const92 const sem::Type* ProgramBuilder::TypeOf(const ast::Expression* expr) const {
93   auto* sem = Sem().Get(expr);
94   return sem ? sem->Type() : nullptr;
95 }
96 
TypeOf(const ast::Variable * var) const97 const sem::Type* ProgramBuilder::TypeOf(const ast::Variable* var) const {
98   auto* sem = Sem().Get(var);
99   return sem ? sem->Type() : nullptr;
100 }
101 
TypeOf(const ast::Type * type) const102 const sem::Type* ProgramBuilder::TypeOf(const ast::Type* type) const {
103   return Sem().Get(type);
104 }
105 
TypeOf(const ast::TypeDecl * type_decl) const106 const sem::Type* ProgramBuilder::TypeOf(const ast::TypeDecl* type_decl) const {
107   return Sem().Get(type_decl);
108 }
109 
Of(const ast::TypeDecl * decl) const110 const ast::TypeName* ProgramBuilder::TypesBuilder::Of(
111     const ast::TypeDecl* decl) const {
112   return type_name(decl->name);
113 }
114 
TypesBuilder(ProgramBuilder * pb)115 ProgramBuilder::TypesBuilder::TypesBuilder(ProgramBuilder* pb) : builder(pb) {}
116 
WrapInStatement(const ast::Expression * expr)117 const ast::Statement* ProgramBuilder::WrapInStatement(
118     const ast::Expression* expr) {
119   // Create a temporary variable of inferred type from expr.
120   return Decl(Const(symbols_.New(), nullptr, expr));
121 }
122 
WrapInStatement(const ast::Variable * v)123 const ast::VariableDeclStatement* ProgramBuilder::WrapInStatement(
124     const ast::Variable* v) {
125   return create<ast::VariableDeclStatement>(v);
126 }
127 
WrapInStatement(const ast::Statement * stmt)128 const ast::Statement* ProgramBuilder::WrapInStatement(
129     const ast::Statement* stmt) {
130   return stmt;
131 }
132 
WrapInFunction(const ast::StatementList stmts)133 const ast::Function* ProgramBuilder::WrapInFunction(
134     const ast::StatementList stmts) {
135   return Func("test_function", {}, ty.void_(), std::move(stmts),
136               {create<ast::StageDecoration>(ast::PipelineStage::kCompute),
137                WorkgroupSize(1, 1, 1)});
138 }
139 
140 }  // namespace tint
141