// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #ifndef CARBON_TOOLCHAIN_PARSE_NODE_IDS_H_ #define CARBON_TOOLCHAIN_PARSE_NODE_IDS_H_ #include "toolchain/base/index_base.h" #include "toolchain/lex/token_index.h" #include "toolchain/parse/node_kind.h" namespace Carbon::Parse { // Represents an invalid node id of any type struct NoneNodeId {}; // A lightweight handle representing a node in the tree. // // Objects of this type are small and cheap to copy and store. They don't // contain any of the information about the node, and serve as a handle that // can be used with the underlying tree to query for detailed information. struct NodeId : public IdBase { static constexpr llvm::StringLiteral Label = "node"; // We give NodeId a bit in addition to TokenIndex in order to account for // virtual nodes, where a token may produce two nodes. static constexpr int32_t Bits = Lex::TokenIndex::Bits + 1; // The maximum ID, non-inclusive. static constexpr int Max = 1 << Bits; // A node ID with no value. static constexpr NoneNodeId None; constexpr explicit NodeId(int32_t index) : IdBase(index) { CARBON_DCHECK(index < Max, "Index out of range: {0}", index); } explicit(false) constexpr NodeId(NoneNodeId /*none*/) : IdBase(NoneIndex) {} }; // For looking up the type associated with a given id type. template struct NodeForId; // `Id` is a typed version of `NodeId` that references a node of kind // ``: template struct NodeIdForKind : public NodeId { // NOLINTNEXTLINE(readability-identifier-naming) static const NodeKind& Kind; // Provide a factory function for construction from `NodeId`. This doesn't // validate the type, so it's unsafe. static constexpr auto UnsafeMake(NodeId node_id) -> NodeIdForKind { return NodeIdForKind(node_id); } explicit(false) constexpr NodeIdForKind(NoneNodeId /*none*/) : NodeId(NoneIndex) {} private: // Private to prevent accidental explicit construction from an untyped // NodeId. explicit constexpr NodeIdForKind(NodeId node_id) : NodeId(node_id) {} }; template const NodeKind& NodeIdForKind::Kind = K; #define CARBON_PARSE_NODE_KIND(KindName) \ using KindName##Id = NodeIdForKind; #include "toolchain/parse/node_kind.def" // NodeId that matches any NodeKind whose `category()` overlaps with `Category`. template struct NodeIdInCategory : public NodeId { // Provide a factory function for construction from `NodeId`. This doesn't // validate the type, so it's unsafe. static constexpr auto UnsafeMake(NodeId node_id) -> NodeIdInCategory { return NodeIdInCategory(node_id); } // Support conversion from `NodeIdForKind` if Kind's category // overlaps with `Category`. template explicit(false) NodeIdInCategory(NodeIdForKind node_id) : NodeId(node_id) { CARBON_CHECK(Kind.category().HasAnyOf(Category)); } explicit(false) constexpr NodeIdInCategory(NoneNodeId /*none*/) : NodeId(NoneIndex) {} private: // Private to prevent accidental explicit construction from an untyped // NodeId. explicit constexpr NodeIdInCategory(NodeId node_id) : NodeId(node_id) {} }; // Aliases for `NodeIdInCategory` to describe particular categories of nodes. using AnyDeclId = NodeIdInCategory; using AnyExprId = NodeIdInCategory; using AnyImplAsId = NodeIdInCategory; using AnyMemberAccessId = NodeIdInCategory; using AnyModifierId = NodeIdInCategory; using AnyPatternId = NodeIdInCategory; using AnyStatementId = NodeIdInCategory; using AnyRequirementId = NodeIdInCategory; using AnyNonExprNameId = NodeIdInCategory; using AnyPackageNameId = NodeIdInCategory; // NodeId with kind that matches one of the `T::Kind`s. template requires(sizeof...(T)>= 2) struct NodeIdOneOf : public NodeId { private: // True if `OtherT` is one of `T`. template static constexpr bool Contains = (std::is_same{} || ...); // True if `NodeIdOneOf` is a subset of this `NodeIdOneOf`. template static constexpr bool IsSubset = false; template static constexpr bool IsSubset> = (Contains && ...); // Private to prevent accidental explicit construction from an untyped // NodeId. explicit constexpr NodeIdOneOf(NodeId node_id) : NodeId(node_id) {} public: // Provide a factory function for construction from `NodeId`. This doesn't // validate the type, so it's unsafe. static constexpr auto UnsafeMake(NodeId node_id) -> NodeIdOneOf { return NodeIdOneOf(node_id); } template requires(Contains>) explicit(false) NodeIdOneOf(NodeIdForKind node_id) : NodeId(node_id) {} template requires(IsSubset) explicit(false) NodeIdOneOf(OtherNodeIdOneOf node_id) : NodeId(node_id) {} explicit(false) constexpr NodeIdOneOf(NoneNodeId /*none*/) : NodeId(NoneIndex) {} }; using AnyClassDeclId = NodeIdOneOf; using AnyFunctionDeclId = NodeIdOneOf; using AnyImplDeclId = NodeIdOneOf; using AnyInterfaceDeclId = NodeIdOneOf; using AnyNamespaceId = NodeIdOneOf; using AnyPackagingDeclId = NodeIdOneOf; using AnyPointerDeferenceExprId = NodeIdOneOf; using AnyRuntimeBindingPatternName = NodeIdOneOf; // NodeId with kind that is anything but T::Kind. template struct NodeIdNot : public NodeId { constexpr explicit NodeIdNot(NodeId node_id) : NodeId(node_id) {} explicit(false) constexpr NodeIdNot(NoneNodeId /*none*/) : NodeId(NoneIndex) {} }; // Note that the support for extracting these types using the `Tree::Extract*` // functions is defined in `extract.cpp`. } // namespace Carbon::Parse #endif // CARBON_TOOLCHAIN_PARSE_NODE_IDS_H_

AltStyle によって変換されたページ (->オリジナル) /