blob: 940a6ecfa0b42fdc2a005bd0a8de2a3ba90be096 [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// 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_TINT_PROGRAM_H_
16#define SRC_TINT_PROGRAM_H_
17
18#include <string>
19#include <unordered_set>
20
21#include "src/tint/ast/function.h"
Ben Clayton1e67e532023-05-24 23:07:36 +000022#include "src/tint/constant/manager.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000023#include "src/tint/program_id.h"
24#include "src/tint/sem/info.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000025#include "src/tint/symbol_table.h"
dan sinclair837b8042022-12-09 05:00:07 +000026#include "src/tint/type/manager.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000027
dan sinclair8155b9d2022-04-07 19:10:25 +000028// Forward Declarations
Ben Claytona7230f02022-04-11 14:37:21 +000029namespace tint {
30class CloneContext;
31} // namespace tint
dan sinclair8155b9d2022-04-07 19:10:25 +000032namespace tint::ast {
33class Module;
34} // namespace tint::ast
35
Ryan Harrisondbc13af2022-02-21 15:19:07 +000036namespace tint {
37
Ryan Harrisondbc13af2022-02-21 15:19:07 +000038/// Program holds the AST, Type information and SymbolTable for a tint program.
39class Program {
dan sinclair41e4d9a2022-05-01 14:40:55 +000040 public:
41 /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
42 using ASTNodeAllocator = utils::BlockAllocator<ast::Node>;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000043
dan sinclair41e4d9a2022-05-01 14:40:55 +000044 /// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
45 using SemNodeAllocator = utils::BlockAllocator<sem::Node>;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000046
dan sinclair41e4d9a2022-05-01 14:40:55 +000047 /// Constructor
48 Program();
Ryan Harrisondbc13af2022-02-21 15:19:07 +000049
dan sinclair41e4d9a2022-05-01 14:40:55 +000050 /// Move constructor
51 /// @param rhs the Program to move
52 Program(Program&& rhs);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000053
dan sinclair41e4d9a2022-05-01 14:40:55 +000054 /// Move constructor from builder
55 /// @param builder the builder used to construct the program
56 explicit Program(ProgramBuilder&& builder);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000057
dan sinclair41e4d9a2022-05-01 14:40:55 +000058 /// Destructor
59 ~Program();
Ryan Harrisondbc13af2022-02-21 15:19:07 +000060
dan sinclair41e4d9a2022-05-01 14:40:55 +000061 /// Move assignment operator
62 /// @param rhs the Program to move
63 /// @return this Program
64 Program& operator=(Program&& rhs);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000065
dan sinclair41e4d9a2022-05-01 14:40:55 +000066 /// @returns the unique identifier for this program
67 ProgramID ID() const { return id_; }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000068
Ben Clayton4a92a3c2022-07-18 20:50:02 +000069 /// @returns the last allocated (numerically highest) AST node identifier.
70 ast::NodeID HighestASTNodeID() const { return highest_node_id_; }
71
Ben Clayton1e67e532023-05-24 23:07:36 +000072 /// @returns a reference to the program's constants
73 const constant::Manager& Constants() const {
74 AssertNotMoved();
75 return constants_;
76 }
77
dan sinclair41e4d9a2022-05-01 14:40:55 +000078 /// @returns a reference to the program's types
dan sinclair837b8042022-12-09 05:00:07 +000079 const type::Manager& Types() const {
dan sinclair41e4d9a2022-05-01 14:40:55 +000080 AssertNotMoved();
Ben Clayton1e67e532023-05-24 23:07:36 +000081 return constants_.types;
dan sinclair41e4d9a2022-05-01 14:40:55 +000082 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000083
dan sinclair41e4d9a2022-05-01 14:40:55 +000084 /// @returns a reference to the program's AST nodes storage
85 const ASTNodeAllocator& ASTNodes() const {
86 AssertNotMoved();
87 return ast_nodes_;
88 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000089
dan sinclair41e4d9a2022-05-01 14:40:55 +000090 /// @returns a reference to the program's semantic nodes storage
91 const SemNodeAllocator& SemNodes() const {
92 AssertNotMoved();
93 return sem_nodes_;
94 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000095
dan sinclair41e4d9a2022-05-01 14:40:55 +000096 /// @returns a reference to the program's AST root Module
97 const ast::Module& AST() const {
98 AssertNotMoved();
99 return *ast_;
100 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000101
dan sinclair41e4d9a2022-05-01 14:40:55 +0000102 /// @returns a reference to the program's semantic info
103 const sem::Info& Sem() const {
104 AssertNotMoved();
105 return sem_;
106 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000107
dan sinclair41e4d9a2022-05-01 14:40:55 +0000108 /// @returns a reference to the program's SymbolTable
109 const SymbolTable& Symbols() const {
110 AssertNotMoved();
111 return symbols_;
112 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000113
dan sinclair41e4d9a2022-05-01 14:40:55 +0000114 /// @returns a reference to the program's diagnostics
115 const diag::List& Diagnostics() const {
116 AssertNotMoved();
117 return diagnostics_;
118 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000119
dan sinclair41e4d9a2022-05-01 14:40:55 +0000120 /// Performs a deep clone of this program.
121 /// The returned Program will contain no pointers to objects owned by this
122 /// Program, and so after calling, this Program can be safely destructed.
123 /// @return a new Program copied from this Program
124 Program Clone() const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000125
dan sinclair41e4d9a2022-05-01 14:40:55 +0000126 /// Performs a deep clone of this Program's AST nodes, types and symbols into
127 /// a new ProgramBuilder. Semantic nodes are not cloned, as these will be
128 /// rebuilt when the ProgramBuilder builds its Program.
129 /// The returned ProgramBuilder will contain no pointers to objects owned by
130 /// this Program, and so after calling, this Program can be safely destructed.
131 /// @return a new ProgramBuilder copied from this Program
132 ProgramBuilder CloneAsBuilder() const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000133
dan sinclair41e4d9a2022-05-01 14:40:55 +0000134 /// @returns true if the program has no error diagnostics and is not missing
135 /// information
136 bool IsValid() const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000137
dan sinclair41e4d9a2022-05-01 14:40:55 +0000138 /// Helper for returning the resolved semantic type of the expression `expr`.
139 /// @param expr the AST expression
140 /// @return the resolved semantic type for the expression, or nullptr if the
141 /// expression has no resolved type.
dan sinclair5f764d82022-12-08 00:32:27 +0000142 const type::Type* TypeOf(const ast::Expression* expr) const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000143
Ben Clayton971318f2023-02-14 13:52:43 +0000144 /// Helper for returning the resolved semantic type of the variable `var`.
145 /// @param var the AST variable
146 /// @return the resolved semantic type for the variable, or nullptr if the
147 /// variable has no resolved type.
148 const type::Type* TypeOf(const ast::Variable* var) const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000149
dan sinclair41e4d9a2022-05-01 14:40:55 +0000150 /// Helper for returning the resolved semantic type of the AST type
151 /// declaration `type_decl`.
152 /// @param type_decl the AST type declaration
153 /// @return the resolved semantic type for the type declaration, or nullptr if
154 /// the type declaration has no resolved type.
dan sinclair5f764d82022-12-08 00:32:27 +0000155 const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000156
dan sinclair41e4d9a2022-05-01 14:40:55 +0000157 /// A function that can be used to print a program
158 using Printer = std::string (*)(const Program*);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000159
dan sinclair41e4d9a2022-05-01 14:40:55 +0000160 /// The Program printer used for testing and debugging.
161 static Printer printer;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000162
dan sinclair41e4d9a2022-05-01 14:40:55 +0000163 private:
164 Program(const Program&) = delete;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000165
dan sinclair41e4d9a2022-05-01 14:40:55 +0000166 /// Asserts that the program has not been moved.
167 void AssertNotMoved() const;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000168
dan sinclair41e4d9a2022-05-01 14:40:55 +0000169 ProgramID id_;
Ben Clayton4a92a3c2022-07-18 20:50:02 +0000170 ast::NodeID highest_node_id_;
Ben Clayton1e67e532023-05-24 23:07:36 +0000171 constant::Manager constants_;
dan sinclair41e4d9a2022-05-01 14:40:55 +0000172 ASTNodeAllocator ast_nodes_;
173 SemNodeAllocator sem_nodes_;
174 ast::Module* ast_ = nullptr;
175 sem::Info sem_;
176 SymbolTable symbols_{id_};
177 diag::List diagnostics_;
178 bool is_valid_ = false; // Not valid until it is built
179 bool moved_ = false;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000180};
181
182/// @param program the Program
183/// @returns the ProgramID of the Program
184inline ProgramID ProgramIDOf(const Program* program) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000185 return program->ID();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000186}
187
188} // namespace tint
189
190#endif // SRC_TINT_PROGRAM_H_