|  | // Copyright 2021 The Tint Authors. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | #ifndef SRC_PROGRAM_H_ | 
|  | #define SRC_PROGRAM_H_ | 
|  |  | 
|  | #include <string> | 
|  | #include <unordered_set> | 
|  |  | 
|  | #include "src/ast/function.h" | 
|  | #include "src/program_id.h" | 
|  | #include "src/sem/info.h" | 
|  | #include "src/sem/type_manager.h" | 
|  | #include "src/symbol_table.h" | 
|  |  | 
|  | namespace tint { | 
|  |  | 
|  | // Forward declarations | 
|  | class CloneContext; | 
|  |  | 
|  | namespace ast { | 
|  |  | 
|  | class Module; | 
|  |  | 
|  | }  // namespace ast | 
|  |  | 
|  | /// Program holds the AST, Type information and SymbolTable for a tint program. | 
|  | class Program { | 
|  | public: | 
|  | /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node> | 
|  | using ASTNodeAllocator = BlockAllocator<ast::Node>; | 
|  |  | 
|  | /// SemNodeAllocator is an alias to BlockAllocator<sem::Node> | 
|  | using SemNodeAllocator = BlockAllocator<sem::Node>; | 
|  |  | 
|  | /// Constructor | 
|  | Program(); | 
|  |  | 
|  | /// Move constructor | 
|  | /// @param rhs the Program to move | 
|  | Program(Program&& rhs); | 
|  |  | 
|  | /// Move constructor from builder | 
|  | /// @param builder the builder used to construct the program | 
|  | explicit Program(ProgramBuilder&& builder); | 
|  |  | 
|  | /// Destructor | 
|  | ~Program(); | 
|  |  | 
|  | /// Move assignment operator | 
|  | /// @param rhs the Program to move | 
|  | /// @return this Program | 
|  | Program& operator=(Program&& rhs); | 
|  |  | 
|  | /// @returns the unique identifier for this program | 
|  | ProgramID ID() const { return id_; } | 
|  |  | 
|  | /// @returns a reference to the program's types | 
|  | const sem::Manager& Types() const { | 
|  | AssertNotMoved(); | 
|  | return types_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's AST nodes storage | 
|  | const ASTNodeAllocator& ASTNodes() const { | 
|  | AssertNotMoved(); | 
|  | return ast_nodes_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's semantic nodes storage | 
|  | const SemNodeAllocator& SemNodes() const { | 
|  | AssertNotMoved(); | 
|  | return sem_nodes_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's AST root Module | 
|  | const ast::Module& AST() const { | 
|  | AssertNotMoved(); | 
|  | return *ast_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's semantic info | 
|  | const sem::Info& Sem() const { | 
|  | AssertNotMoved(); | 
|  | return sem_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's SymbolTable | 
|  | const SymbolTable& Symbols() const { | 
|  | AssertNotMoved(); | 
|  | return symbols_; | 
|  | } | 
|  |  | 
|  | /// @returns a reference to the program's diagnostics | 
|  | const diag::List& Diagnostics() const { | 
|  | AssertNotMoved(); | 
|  | return diagnostics_; | 
|  | } | 
|  |  | 
|  | /// Performs a deep clone of this program. | 
|  | /// The returned Program will contain no pointers to objects owned by this | 
|  | /// Program, and so after calling, this Program can be safely destructed. | 
|  | /// @return a new Program copied from this Program | 
|  | Program Clone() const; | 
|  |  | 
|  | /// Performs a deep clone of this Program's AST nodes, types and symbols into | 
|  | /// a new ProgramBuilder. Semantic nodes are not cloned, as these will be | 
|  | /// rebuilt when the ProgramBuilder builds its Program. | 
|  | /// The returned ProgramBuilder will contain no pointers to objects owned by | 
|  | /// this Program, and so after calling, this Program can be safely destructed. | 
|  | /// @return a new ProgramBuilder copied from this Program | 
|  | ProgramBuilder CloneAsBuilder() const; | 
|  |  | 
|  | /// @returns true if the program has no error diagnostics and is not missing | 
|  | /// information | 
|  | bool IsValid() const; | 
|  |  | 
|  | /// @return the TypeInfo pointers of all transforms that have been applied to | 
|  | /// this program. | 
|  | std::unordered_set<const TypeInfo*> TransformsApplied() const { | 
|  | return transforms_applied_; | 
|  | } | 
|  |  | 
|  | /// @param transform the TypeInfo of the transform | 
|  | /// @returns true if the transform with the given TypeInfo was applied to the | 
|  | /// Program | 
|  | bool HasTransformApplied(const TypeInfo* transform) const { | 
|  | return transforms_applied_.count(transform); | 
|  | } | 
|  |  | 
|  | /// @returns true if the transform of type `T` was applied. | 
|  | template <typename T> | 
|  | bool HasTransformApplied() const { | 
|  | return HasTransformApplied(&TypeInfo::Of<T>()); | 
|  | } | 
|  |  | 
|  | /// Helper for returning the resolved semantic type of the expression `expr`. | 
|  | /// @param expr the AST expression | 
|  | /// @return the resolved semantic type for the expression, or nullptr if the | 
|  | /// expression has no resolved type. | 
|  | const sem::Type* TypeOf(const ast::Expression* expr) const; | 
|  |  | 
|  | /// Helper for returning the resolved semantic type of the AST type `type`. | 
|  | /// @param type the AST type | 
|  | /// @return the resolved semantic type for the type, or nullptr if the type | 
|  | /// has no resolved type. | 
|  | const sem::Type* TypeOf(const ast::Type* type) const; | 
|  |  | 
|  | /// Helper for returning the resolved semantic type of the AST type | 
|  | /// declaration `type_decl`. | 
|  | /// @param type_decl the AST type declaration | 
|  | /// @return the resolved semantic type for the type declaration, or nullptr if | 
|  | /// the type declaration has no resolved type. | 
|  | const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const; | 
|  |  | 
|  | /// A function that can be used to print a program | 
|  | using Printer = std::string (*)(const Program*); | 
|  |  | 
|  | /// The Program printer used for testing and debugging. | 
|  | static Printer printer; | 
|  |  | 
|  | private: | 
|  | Program(const Program&) = delete; | 
|  |  | 
|  | /// Asserts that the program has not been moved. | 
|  | void AssertNotMoved() const; | 
|  |  | 
|  | ProgramID id_; | 
|  | sem::Manager types_; | 
|  | ASTNodeAllocator ast_nodes_; | 
|  | SemNodeAllocator sem_nodes_; | 
|  | ast::Module* ast_ = nullptr; | 
|  | sem::Info sem_; | 
|  | SymbolTable symbols_{id_}; | 
|  | diag::List diagnostics_; | 
|  | std::unordered_set<const TypeInfo*> transforms_applied_; | 
|  | bool is_valid_ = false;  // Not valid until it is built | 
|  | bool moved_ = false; | 
|  | }; | 
|  |  | 
|  | /// @param program the Program | 
|  | /// @returns the ProgramID of the Program | 
|  | inline ProgramID ProgramIDOf(const Program* program) { | 
|  | return program->ID(); | 
|  | } | 
|  |  | 
|  | }  // namespace tint | 
|  |  | 
|  | #endif  // SRC_PROGRAM_H_ |