• 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.h"
16 
17 #include <utility>
18 
19 #include "src/demangler.h"
20 #include "src/resolver/resolver.h"
21 #include "src/sem/expression.h"
22 
23 namespace tint {
24 namespace {
25 
DefaultPrinter(const Program *)26 std::string DefaultPrinter(const Program*) {
27   return "<no program printer assigned>";
28 }
29 
30 }  // namespace
31 
32 Program::Printer Program::printer = DefaultPrinter;
33 
34 Program::Program() = default;
35 
Program(Program && program)36 Program::Program(Program&& program)
37     : id_(std::move(program.id_)),
38       types_(std::move(program.types_)),
39       ast_nodes_(std::move(program.ast_nodes_)),
40       sem_nodes_(std::move(program.sem_nodes_)),
41       ast_(std::move(program.ast_)),
42       sem_(std::move(program.sem_)),
43       symbols_(std::move(program.symbols_)),
44       diagnostics_(std::move(program.diagnostics_)),
45       transforms_applied_(std::move(program.transforms_applied_)),
46       is_valid_(program.is_valid_) {
47   program.AssertNotMoved();
48   program.moved_ = true;
49 }
50 
Program(ProgramBuilder && builder)51 Program::Program(ProgramBuilder&& builder) {
52   id_ = builder.ID();
53 
54   is_valid_ = builder.IsValid();
55   if (builder.ResolveOnBuild() && builder.IsValid()) {
56     resolver::Resolver resolver(&builder);
57     if (!resolver.Resolve()) {
58       is_valid_ = false;
59     }
60   }
61 
62   // The above must be called *before* the calls to std::move() below
63   types_ = std::move(builder.Types());
64   ast_nodes_ = std::move(builder.ASTNodes());
65   sem_nodes_ = std::move(builder.SemNodes());
66   ast_ = &builder.AST();  // ast::Module is actually a heap allocation.
67   sem_ = std::move(builder.Sem());
68   symbols_ = std::move(builder.Symbols());
69   diagnostics_.add(std::move(builder.Diagnostics()));
70   transforms_applied_ = builder.TransformsApplied();
71   builder.MarkAsMoved();
72 
73   if (!is_valid_ && !diagnostics_.contains_errors()) {
74     // If the builder claims to be invalid, then we really should have an error
75     // message generated. If we find a situation where the program is not valid
76     // and there are no errors reported, add one here.
77     diagnostics_.add_error(diag::System::Program, "invalid program generated");
78   }
79 }
80 
81 Program::~Program() = default;
82 
operator =(Program && program)83 Program& Program::operator=(Program&& program) {
84   program.AssertNotMoved();
85   program.moved_ = true;
86   moved_ = false;
87   id_ = std::move(program.id_);
88   types_ = std::move(program.types_);
89   ast_nodes_ = std::move(program.ast_nodes_);
90   sem_nodes_ = std::move(program.sem_nodes_);
91   ast_ = std::move(program.ast_);
92   sem_ = std::move(program.sem_);
93   symbols_ = std::move(program.symbols_);
94   diagnostics_ = std::move(program.diagnostics_);
95   transforms_applied_ = std::move(program.transforms_applied_);
96   is_valid_ = program.is_valid_;
97   return *this;
98 }
99 
Clone() const100 Program Program::Clone() const {
101   AssertNotMoved();
102   return Program(CloneAsBuilder());
103 }
104 
CloneAsBuilder() const105 ProgramBuilder Program::CloneAsBuilder() const {
106   AssertNotMoved();
107   ProgramBuilder out;
108   CloneContext(&out, this).Clone();
109   return out;
110 }
111 
IsValid() const112 bool Program::IsValid() const {
113   AssertNotMoved();
114   return is_valid_;
115 }
116 
TypeOf(const ast::Expression * expr) const117 const sem::Type* Program::TypeOf(const ast::Expression* expr) const {
118   auto* sem = Sem().Get(expr);
119   return sem ? sem->Type() : nullptr;
120 }
121 
TypeOf(const ast::Type * type) const122 const sem::Type* Program::TypeOf(const ast::Type* type) const {
123   return Sem().Get(type);
124 }
125 
TypeOf(const ast::TypeDecl * type_decl) const126 const sem::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
127   return Sem().Get(type_decl);
128 }
129 
AssertNotMoved() const130 void Program::AssertNotMoved() const {
131   TINT_ASSERT(Program, !moved_);
132 }
133 
134 }  // namespace tint
135