diff --git a/BUILD.gn b/BUILD.gn index dc730a9664..079bbd17f9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -378,9 +378,13 @@ source_set("libtint_core_src") { "src/reader/reader.cc", "src/reader/reader.h", "src/scope_stack.h", + "src/semantic/expression.h", "src/semantic/info.h", "src/semantic/node.h", + "src/semantic/sem_expression.cc", "src/semantic/sem_info.cc", + "src/semantic/sem_node.cc", + "src/semantic/type_mappings.h", "src/source.cc", "src/source.h", "src/symbol.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba9685fd5a..465e16fe4f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -192,9 +192,13 @@ set(TINT_LIB_SRCS reader/reader.cc reader/reader.h scope_stack.h + semantic/expression.h semantic/info.h semantic/node.h + semantic/sem_expression.cc semantic/sem_info.cc + semantic/sem_node.cc + semantic/type_mappings.h source.cc source.h symbol.cc @@ -451,7 +455,6 @@ if(${TINT_BUILD_TESTS}) inspector/inspector_test.cc namer_test.cc program_test.cc - program_builder_test.cc scope_stack_test.cc symbol_table_test.cc symbol_test.cc diff --git a/src/castable.h b/src/castable.h index 1eb2cbc8e0..afda1e088f 100644 --- a/src/castable.h +++ b/src/castable.h @@ -62,6 +62,9 @@ class ClassID { /// @see Castable class CastableBase { public: + /// Copy constructor + CastableBase(const CastableBase&) = default; + /// Move constructor CastableBase(CastableBase&&) = default; diff --git a/src/semantic/expression.h b/src/semantic/expression.h new file mode 100644 index 0000000000..40b15e4c28 --- /dev/null +++ b/src/semantic/expression.h @@ -0,0 +1,50 @@ +// 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_SEMANTIC_EXPRESSION_H_ +#define SRC_SEMANTIC_EXPRESSION_H_ + +#include "src/semantic/node.h" + +#include "src/semantic/type_mappings.h" + +namespace tint { + +// Forward declarations +namespace type { + +class Type; + +} // namespace type + +namespace semantic { + +/// Expression holds the semantic information for expression nodes. +class Expression : public Castable { + public: + /// Constructor + /// @param type the resolved type of the expression + explicit Expression(type::Type* type); + + /// @return the resolved type of the expression + type::Type* Type() const { return type_; } + + private: + type::Type* const type_; +}; + +} // namespace semantic +} // namespace tint + +#endif // SRC_SEMANTIC_EXPRESSION_H_ diff --git a/src/semantic/info.h b/src/semantic/info.h index 4b36b2fca9..6e478ff256 100644 --- a/src/semantic/info.h +++ b/src/semantic/info.h @@ -15,11 +15,23 @@ #ifndef SRC_SEMANTIC_INFO_H_ #define SRC_SEMANTIC_INFO_H_ +#include + +#include + +#include "src/semantic/node.h" +#include "src/semantic/type_mappings.h" + namespace tint { +// Forward declarations +namespace ast { +class Node; +} // namespace ast + namespace semantic { -/// Info will hold all the resolved semantic information for a Program. +/// Info holds all the resolved semantic information for a Program. class Info { public: /// Constructor @@ -36,6 +48,28 @@ class Info { /// @return this Program Info& operator=(Info&& rhs); + /// Get looks up the semantic information for the AST node `ast_node`. + /// @param ast_node the AST node + /// @returns a pointer to the semantic node if found, otherwise nullptr + template > + const SEM* Get(const AST* ast_node) const { + auto it = ast_to_sem_.find(ast_node); + if (it == ast_to_sem_.end()) { + return nullptr; + } + return it->second->template As(); + } + + /// Add registers the semantic node `sem_node` for the AST node `ast_node`. + /// @param ast_node the AST node + /// @param sem_node the semantic node + template + void Add(const AST* ast_node, const SemanticNodeTypeFor* sem_node) { + // Check there's no semantic info already existing for the node + assert(Get(ast_node) == nullptr); + ast_to_sem_.emplace(ast_node, sem_node); + } + /// Wrap returns a new Info created with the contents of `inner`. /// The Info returned by Wrap is intended to temporarily extend the contents /// of an existing immutable Info. @@ -44,9 +78,13 @@ class Info { /// @param inner the immutable Info to extend /// @return the Info that wraps `inner` static Info Wrap(const Info& inner) { - (void)inner; - return Info(); + Info out; + out.ast_to_sem_ = inner.ast_to_sem_; + return out; } + + private: + std::unordered_map ast_to_sem_; }; } // namespace semantic diff --git a/src/semantic/sem_expression.cc b/src/semantic/sem_expression.cc new file mode 100644 index 0000000000..52d13f75cd --- /dev/null +++ b/src/semantic/sem_expression.cc @@ -0,0 +1,27 @@ +// 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. + +#include "src/semantic/expression.h" + +#include "src/type/type.h" + +TINT_INSTANTIATE_CLASS_ID(tint::semantic::Expression); + +namespace tint { +namespace semantic { + +Expression::Expression(type::Type* type) : type_(type->UnwrapIfNeeded()) {} + +} // namespace semantic +} // namespace tint diff --git a/src/semantic/sem_node.cc b/src/semantic/sem_node.cc new file mode 100644 index 0000000000..84be5ab9b8 --- /dev/null +++ b/src/semantic/sem_node.cc @@ -0,0 +1,25 @@ +// 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. + +#include "src/semantic/node.h" + +TINT_INSTANTIATE_CLASS_ID(tint::semantic::Node); + +namespace tint { +namespace semantic { + +Node::~Node() = default; + +} // namespace semantic +} // namespace tint diff --git a/src/semantic/type_mappings.h b/src/semantic/type_mappings.h new file mode 100644 index 0000000000..4c59bd3163 --- /dev/null +++ b/src/semantic/type_mappings.h @@ -0,0 +1,53 @@ +// 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_SEMANTIC_TYPE_MAPPINGS_H_ +#define SRC_SEMANTIC_TYPE_MAPPINGS_H_ + +#include + +namespace tint { + +// Forward declarations +namespace ast { + +class Expression; + +} // namespace ast + +namespace semantic { + +class Expression; + +/// TypeMappings is a struct that holds dummy `operator()` methods that's used +/// by SemanticNodeTypeFor to map AST node types to their corresponding semantic +/// node types. +/// The standard operator overload resolving rules will be used to infer the +/// return type based on the argument type. +struct TypeMappings { + //! @cond Doxygen_Suppress + semantic::Expression* operator()(ast::Expression*); + //! @endcond +}; + +/// SemanticNodeTypeFor resolves to the appropriate semantic::Node type for the +/// AST node type `AST`. +template +using SemanticNodeTypeFor = typename std::remove_pointer()))>::type; + +} // namespace semantic +} // namespace tint + +#endif // SRC_SEMANTIC_TYPE_MAPPINGS_H_