Switch ParseNodeKind to EnumBase (#2510)

This shouldn't have any behavior change, it's just using #2504
This commit is contained in:
Jon Ross-Perkins
2023-01-05 13:33:32 -08:00
committed by GitHub
parent 0af5c55f55
commit 97634a5e91
6 changed files with 128 additions and 211 deletions
+12 -49
View File
@@ -5,58 +5,22 @@
#ifndef CARBON_TOOLCHAIN_PARSER_PARSE_NODE_KIND_H_
#define CARBON_TOOLCHAIN_PARSER_PARSE_NODE_KIND_H_
#include <cstdint>
#include <iterator>
#include "common/ostream.h"
#include "llvm/ADT/StringRef.h"
#include "toolchain/common/enum_base.h"
namespace Carbon {
CARBON_DEFINE_RAW_ENUM_CLASS(ParseNodeKind, uint8_t){
#define CARBON_PARSE_NODE_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name)
#include "toolchain/parser/parse_node_kind.def"
};
// A class wrapping an enumeration of the different kinds of nodes in the parse
// tree.
//
// Rather than using a raw enumerator for each distinct kind of node produced by
// the parser, we wrap the enumerator in a class to expose a more rich API
// including bidirectional mappings to string spellings of the different kinds
// and any relevant classification.
//
// Instances of this type should always be created using the `constexpr` static
// member functions. These instances are designed specifically to be usable in
// `case` labels of `switch` statements just like an enumerator would.
class ParseNodeKind {
// Note that this must be declared earlier in the class so that its type can
// be used, for example in the conversion operator.
enum class KindEnum : uint8_t {
#define CARBON_PARSE_NODE_KIND(Name) Name,
#include "toolchain/parser/parse_node_kind.def"
};
class ParseNodeKind : public CARBON_ENUM_BASE(ParseNodeKind) {
public:
// `clang-format` has a bug with spacing around `->` returns in macros. See
// https://bugs.llvm.org/show_bug.cgi?id=48320 for details.
#define CARBON_PARSE_NODE_KIND(Name) \
static constexpr auto Name()->ParseNodeKind { \
return ParseNodeKind(KindEnum::Name); \
}
#define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CONSTANT_DECLARATION(Name)
#include "toolchain/parser/parse_node_kind.def"
// The default constructor is deleted because objects of this type should
// always be constructed using the above factory functions for each unique
// kind.
ParseNodeKind() = delete;
// Gets a friendly name for the token for logging or debugging.
[[nodiscard]] auto name() const -> llvm::StringRef;
// Enable conversion to our private enum, including in a `constexpr` context,
// to enable usage in `switch` and `case`. The enum remains private and
// nothing else should be using this function.
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr operator KindEnum() const { return kind_; }
void Print(llvm::raw_ostream& out) const { out << name(); }
// Returns true if the node is bracketed; otherwise, child_count is used.
auto has_bracket() const -> bool;
@@ -67,13 +31,12 @@ class ParseNodeKind {
// Returns the number of children that the node must have, often 0. Requires
// that has_bracket is false.
auto child_count() const -> int32_t;
private:
constexpr explicit ParseNodeKind(KindEnum k) : kind_(k) {}
KindEnum kind_;
};
#define CARBON_PARSE_NODE_KIND(Name) \
CARBON_ENUM_CONSTANT_DEFINITION(ParseNodeKind, Name)
#include "toolchain/parser/parse_node_kind.def"
// We expect the parse node kind to fit compactly into 8 bits.
static_assert(sizeof(ParseNodeKind) == 1, "Kind objects include padding!");