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 #ifndef SRC_PROGRAM_H_
16 #define SRC_PROGRAM_H_
17
18 #include <string>
19 #include <unordered_set>
20
21 #include "src/ast/function.h"
22 #include "src/program_id.h"
23 #include "src/sem/info.h"
24 #include "src/sem/type_manager.h"
25 #include "src/symbol_table.h"
26
27 namespace tint {
28
29 // Forward declarations
30 class CloneContext;
31
32 namespace ast {
33
34 class Module;
35
36 } // namespace ast
37
38 /// Program holds the AST, Type information and SymbolTable for a tint program.
39 class Program {
40 public:
41 /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
42 using ASTNodeAllocator = BlockAllocator<ast::Node>;
43
44 /// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
45 using SemNodeAllocator = BlockAllocator<sem::Node>;
46
47 /// Constructor
48 Program();
49
50 /// Move constructor
51 /// @param rhs the Program to move
52 Program(Program&& rhs);
53
54 /// Move constructor from builder
55 /// @param builder the builder used to construct the program
56 explicit Program(ProgramBuilder&& builder);
57
58 /// Destructor
59 ~Program();
60
61 /// Move assignment operator
62 /// @param rhs the Program to move
63 /// @return this Program
64 Program& operator=(Program&& rhs);
65
66 /// @returns the unique identifier for this program
ID()67 ProgramID ID() const { return id_; }
68
69 /// @returns a reference to the program's types
Types()70 const sem::Manager& Types() const {
71 AssertNotMoved();
72 return types_;
73 }
74
75 /// @returns a reference to the program's AST nodes storage
ASTNodes()76 const ASTNodeAllocator& ASTNodes() const {
77 AssertNotMoved();
78 return ast_nodes_;
79 }
80
81 /// @returns a reference to the program's semantic nodes storage
SemNodes()82 const SemNodeAllocator& SemNodes() const {
83 AssertNotMoved();
84 return sem_nodes_;
85 }
86
87 /// @returns a reference to the program's AST root Module
AST()88 const ast::Module& AST() const {
89 AssertNotMoved();
90 return *ast_;
91 }
92
93 /// @returns a reference to the program's semantic info
Sem()94 const sem::Info& Sem() const {
95 AssertNotMoved();
96 return sem_;
97 }
98
99 /// @returns a reference to the program's SymbolTable
Symbols()100 const SymbolTable& Symbols() const {
101 AssertNotMoved();
102 return symbols_;
103 }
104
105 /// @returns a reference to the program's diagnostics
Diagnostics()106 const diag::List& Diagnostics() const {
107 AssertNotMoved();
108 return diagnostics_;
109 }
110
111 /// Performs a deep clone of this program.
112 /// The returned Program will contain no pointers to objects owned by this
113 /// Program, and so after calling, this Program can be safely destructed.
114 /// @return a new Program copied from this Program
115 Program Clone() const;
116
117 /// Performs a deep clone of this Program's AST nodes, types and symbols into
118 /// a new ProgramBuilder. Semantic nodes are not cloned, as these will be
119 /// rebuilt when the ProgramBuilder builds its Program.
120 /// The returned ProgramBuilder will contain no pointers to objects owned by
121 /// this Program, and so after calling, this Program can be safely destructed.
122 /// @return a new ProgramBuilder copied from this Program
123 ProgramBuilder CloneAsBuilder() const;
124
125 /// @returns true if the program has no error diagnostics and is not missing
126 /// information
127 bool IsValid() const;
128
129 /// @return the TypeInfo pointers of all transforms that have been applied to
130 /// this program.
TransformsApplied()131 std::unordered_set<const TypeInfo*> TransformsApplied() const {
132 return transforms_applied_;
133 }
134
135 /// @param transform the TypeInfo of the transform
136 /// @returns true if the transform with the given TypeInfo was applied to the
137 /// Program
HasTransformApplied(const TypeInfo * transform)138 bool HasTransformApplied(const TypeInfo* transform) const {
139 return transforms_applied_.count(transform);
140 }
141
142 /// @returns true if the transform of type `T` was applied.
143 template <typename T>
HasTransformApplied()144 bool HasTransformApplied() const {
145 return HasTransformApplied(&TypeInfo::Of<T>());
146 }
147
148 /// Helper for returning the resolved semantic type of the expression `expr`.
149 /// @param expr the AST expression
150 /// @return the resolved semantic type for the expression, or nullptr if the
151 /// expression has no resolved type.
152 const sem::Type* TypeOf(const ast::Expression* expr) const;
153
154 /// Helper for returning the resolved semantic type of the AST type `type`.
155 /// @param type the AST type
156 /// @return the resolved semantic type for the type, or nullptr if the type
157 /// has no resolved type.
158 const sem::Type* TypeOf(const ast::Type* type) const;
159
160 /// Helper for returning the resolved semantic type of the AST type
161 /// declaration `type_decl`.
162 /// @param type_decl the AST type declaration
163 /// @return the resolved semantic type for the type declaration, or nullptr if
164 /// the type declaration has no resolved type.
165 const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const;
166
167 /// A function that can be used to print a program
168 using Printer = std::string (*)(const Program*);
169
170 /// The Program printer used for testing and debugging.
171 static Printer printer;
172
173 private:
174 Program(const Program&) = delete;
175
176 /// Asserts that the program has not been moved.
177 void AssertNotMoved() const;
178
179 ProgramID id_;
180 sem::Manager types_;
181 ASTNodeAllocator ast_nodes_;
182 SemNodeAllocator sem_nodes_;
183 ast::Module* ast_ = nullptr;
184 sem::Info sem_;
185 SymbolTable symbols_{id_};
186 diag::List diagnostics_;
187 std::unordered_set<const TypeInfo*> transforms_applied_;
188 bool is_valid_ = false; // Not valid until it is built
189 bool moved_ = false;
190 };
191
192 /// @param program the Program
193 /// @returns the ProgramID of the Program
ProgramIDOf(const Program * program)194 inline ProgramID ProgramIDOf(const Program* program) {
195 return program->ID();
196 }
197
198 } // namespace tint
199
200 #endif // SRC_PROGRAM_H_
201