mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-27 08:30:10 +01:00
This patch tries to make everything adhere to the Google declaration order. This is tricky as there doesn't appear to be a `clang-tidy` check that helps us here at all. One of the complex cases are the `enum`-wrapping classes we use. These need to have a *public* conversion operator to the nested `enum` type to support `switch` statements and the like. However, this makes it impossible to fully respect the Google declaration order. We need to define the enum type before the public API in order to use it in contexts like the conversion operator. Even defining out-of-line won't help avoid this. It is weird to have a type in the public API that is private, but again this is only intended to be used for implicit conversions within a `switch` statement or a `case` label. In one case, we had the non-conforming order of declaration. I've added a comment to explain why there. In the other case, the conversion operator is actually *private* rather than public, which doesn't actually work in practice. I've made this public and moved the declaration order to match with a matching comment.
75 lines
2.6 KiB
C++
75 lines
2.6 KiB
C++
// 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 PARSER_PARSE_NODE_KIND_H_
|
|
#define PARSER_PARSE_NODE_KIND_H_
|
|
|
|
#include <cstdint>
|
|
#include <iterator>
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// 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 "parser/parse_node_kind.def"
|
|
};
|
|
|
|
public:
|
|
// The formatting for this macro is weird due to a `clang-format` bug. 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); \
|
|
}
|
|
#include "parser/parse_node_kind.def"
|
|
|
|
// The default constructor is deleted as objects of this type should always be
|
|
// constructed using the above factory functions for each unique kind.
|
|
ParseNodeKind() = delete;
|
|
|
|
auto operator==(const ParseNodeKind& rhs) const -> bool {
|
|
return kind == rhs.kind;
|
|
}
|
|
auto operator!=(const ParseNodeKind& rhs) const -> bool {
|
|
return kind != rhs.kind;
|
|
}
|
|
|
|
// Gets a friendly name for the token for logging or debugging.
|
|
[[nodiscard]] auto GetName() 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.
|
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
constexpr operator KindEnum() const { return kind; }
|
|
|
|
private:
|
|
constexpr explicit ParseNodeKind(KindEnum k) : kind(k) {}
|
|
|
|
KindEnum kind;
|
|
};
|
|
|
|
// We expect the parse node kind to fit compactly into 8 bits.
|
|
static_assert(sizeof(ParseNodeKind) == 1, "Kind objects include padding!");
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // PARSER_PARSE_NODE_KIND_H_
|