diff --git a/toolchain/parse/extract.cpp b/toolchain/parse/extract.cpp index ac1846124efe..a31c34926e12 100644 --- a/toolchain/parse/extract.cpp +++ b/toolchain/parse/extract.cpp @@ -87,38 +87,20 @@ struct Extractable> { static auto Extract(const Tree* tree, Tree::SiblingIterator& it, Tree::SiblingIterator end, ErrorBuilder* trace) -> std::optional> { - if (trace) { - *trace << "NodeIdInCategory"; - // TODO: Make NodeCategory printable instead. - if (!Category) { - *trace << " "; - } -#define CARBON_NODE_CATEGORY(Name) \ - if (!!(Category & NodeCategory::Name)) { \ - *trace << " " #Name; \ - } - CARBON_NODE_CATEGORY(Decl); - CARBON_NODE_CATEGORY(Expr); - CARBON_NODE_CATEGORY(Modifier); - CARBON_NODE_CATEGORY(NameComponent); - CARBON_NODE_CATEGORY(Pattern); - CARBON_NODE_CATEGORY(Statement); -#undef CARBON_NODE_CATEGORY - } - if (it == end || !(tree->node_kind(*it).category() & Category)) { if (trace) { + *trace << "NodeIdInCategory " << Category << " error: "; if (it == end) { - *trace << " error: no more children\n"; + *trace << "no more children\n"; } else { - *trace << " error: kind " << tree->node_kind(*it) - << " doesn't match\n"; + *trace << "kind " << tree->node_kind(*it) << " doesn't match\n"; } } return std::nullopt; } if (trace) { - *trace << ": kind " << tree->node_kind(*it) << " consumed\n"; + *trace << "NodeIdInCategory " << Category << ": kind " + << tree->node_kind(*it) << " consumed\n"; } return NodeIdInCategory(*it++); } diff --git a/toolchain/parse/node_kind.cpp b/toolchain/parse/node_kind.cpp index 27acda93d7ea..72a122f8de3a 100644 --- a/toolchain/parse/node_kind.cpp +++ b/toolchain/parse/node_kind.cpp @@ -5,10 +5,33 @@ #include "toolchain/parse/node_kind.h" #include "common/check.h" +#include "llvm/ADT/StringExtras.h" #include "toolchain/parse/typed_nodes.h" namespace Carbon::Parse { +auto operator<<(llvm::raw_ostream& output, NodeCategory category) + -> llvm::raw_ostream& { + if (!category) { + output << ""; + } else { + llvm::ListSeparator sep("|"); + +#define CARBON_NODE_CATEGORY(Name) \ + if (!!(category & NodeCategory::Name)) { \ + output << sep << #Name; \ + } + CARBON_NODE_CATEGORY(Decl); + CARBON_NODE_CATEGORY(Expr); + CARBON_NODE_CATEGORY(Modifier); + CARBON_NODE_CATEGORY(NameComponent); + CARBON_NODE_CATEGORY(Pattern); + CARBON_NODE_CATEGORY(Statement); +#undef CARBON_NODE_CATEGORY + } + return output; +} + CARBON_DEFINE_ENUM_CLASS_NAMES(NodeKind) = { #define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CLASS_NAME_STRING(Name) #include "toolchain/parse/node_kind.def" diff --git a/toolchain/parse/node_kind.h b/toolchain/parse/node_kind.h index 18c88659ec55..f85e7e6bf48f 100644 --- a/toolchain/parse/node_kind.h +++ b/toolchain/parse/node_kind.h @@ -35,6 +35,9 @@ inline auto operator!(NodeCategory k) -> bool { return !static_cast(k); } +auto operator<<(llvm::raw_ostream& output, NodeCategory category) + -> llvm::raw_ostream&; + CARBON_DEFINE_RAW_ENUM_CLASS(NodeKind, uint8_t) { #define CARBON_PARSE_NODE_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name) #include "toolchain/parse/node_kind.def"