• 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 #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