| // Copyright 2022 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_TINT_RESOLVER_SEM_HELPER_H_ |
| #define SRC_TINT_RESOLVER_SEM_HELPER_H_ |
| |
| #include <string> |
| |
| #include "src/tint/diagnostic/diagnostic.h" |
| #include "src/tint/program_builder.h" |
| #include "src/tint/resolver/dependency_graph.h" |
| #include "src/tint/utils/map.h" |
| |
| namespace tint::resolver { |
| |
| /// Helper class to retrieve sem information. |
| class SemHelper { |
| public: |
| /// Constructor |
| /// @param builder the program builder |
| explicit SemHelper(ProgramBuilder* builder); |
| ~SemHelper(); |
| |
| /// Get is a helper for obtaining the semantic node for the given AST node. |
| /// Raises an ICE and returns `nullptr` if there is no semantic node associated with the AST |
| /// node. |
| /// @param ast the ast node to get the sem for |
| /// @returns the sem node for @p ast |
| template <typename SEM = sem::Info::InferFromAST, typename AST = ast::Node> |
| auto* Get(const AST* ast) const { |
| using T = sem::Info::GetResultType<SEM, AST>; |
| auto* sem = builder_->Sem().Get(ast); |
| if (TINT_UNLIKELY(!sem)) { |
| TINT_ICE(Resolver, builder_->Diagnostics()) |
| << "AST node '" << ast->TypeInfo().name << "' had no semantic info\n" |
| << "At: " << ast->source << "\n" |
| << "Pointer: " << ast; |
| } |
| return const_cast<T*>(As<T>(sem)); |
| } |
| |
| /// GetVal is a helper for obtaining the semantic sem::ValueExpression for the given AST node. |
| /// Raises an error diagnostic and returns `nullptr` if the semantic node is not a |
| /// sem::ValueExpression. |
| /// @param ast the ast node to get the sem for |
| /// @returns the sem node for @p ast |
| template <typename AST = ast::Node> |
| auto* GetVal(const AST* ast) const { |
| return AsValue(Get(ast)); |
| } |
| |
| /// @param expr the semantic node |
| /// @returns one of: |
| /// * nullptr if @p expr is nullptr |
| /// * @p expr if the static pointer type already derives from sem::ValueExpression |
| /// * @p expr cast to sem::ValueExpression if the cast is successful |
| /// * nullptr if @p expr is not a sem::ValueExpression. In this case an error diagnostic is |
| /// raised. |
| template <typename EXPR> |
| auto* AsValue(EXPR* expr) const { |
| if constexpr (traits::IsTypeOrDerived<EXPR, sem::ValueExpression>) { |
| return expr; |
| } else { |
| if (TINT_LIKELY(expr)) { |
| if (auto* val = expr->template As<sem::ValueExpression>(); TINT_LIKELY(val)) { |
| return val; |
| } |
| ErrorExpectedValueExpr(expr); |
| } |
| return static_cast<sem::ValueExpression*>(nullptr); |
| } |
| } |
| |
| /// @returns the resolved type of the ast::Expression @p expr |
| /// @param expr the expression |
| type::Type* TypeOf(const ast::Expression* expr) const; |
| |
| /// @returns the type name of the given semantic type, unwrapping references. |
| /// @param ty the type to look up |
| std::string TypeNameOf(const type::Type* ty) const; |
| |
| /// @returns the type name of the given semantic type, without unwrapping references. |
| /// @param ty the type to look up |
| std::string RawTypeNameOf(const type::Type* ty) const; |
| |
| /// Raises an error diagnostic that the expression @p got was expected to be a |
| /// sem::ValueExpression, but the expression evaluated to something different. |
| /// @param expr the expression |
| void ErrorExpectedValueExpr(const sem::Expression* expr) const; |
| |
| private: |
| /// Adds the given error message to the diagnostics |
| void AddError(const std::string& msg, const Source& source) const; |
| |
| /// Adds the given warning message to the diagnostics |
| void AddWarning(const std::string& msg, const Source& source) const; |
| |
| /// Adds the given note message to the diagnostics |
| void AddNote(const std::string& msg, const Source& source) const; |
| |
| ProgramBuilder* builder_; |
| }; |
| |
| } // namespace tint::resolver |
| |
| #endif // SRC_TINT_RESOLVER_SEM_HELPER_H_ |