Index: libcxxabi/src/cxa_demangle.cpp =================================================================== --- libcxxabi/src/cxa_demangle.cpp +++ libcxxabi/src/cxa_demangle.cpp @@ -173,8 +173,49 @@ return printStr("TemplateParamKind::Template"); } } - void print(Node::Prec) { - // FIXME: Print Prec enumerator + void print(Node::Prec P) { + switch (P) { + case Node::Prec::Primary: + return printStr("Node::Prec::Primary"); + case Node::Prec::Postfix: + return printStr("Node::Prec::Postfix"); + case Node::Prec::Unary: + return printStr("Node::Prec::Unary"); + case Node::Prec::Cast: + return printStr("Node::Prec::Cast"); + case Node::Prec::PtrMem: + return printStr("Node::Prec::PtrMem"); + case Node::Prec::Multiplicative: + return printStr("Node::Prec::Multiplicative"); + case Node::Prec::Additive: + return printStr("Node::Prec::Additive"); + case Node::Prec::Shift: + return printStr("Node::Prec::Shift"); + case Node::Prec::Spaceship: + return printStr("Node::Prec::Spaceship"); + case Node::Prec::Relational: + return printStr("Node::Prec::Relational"); + case Node::Prec::Equality: + return printStr("Node::Prec::Equality"); + case Node::Prec::And: + return printStr("Node::Prec::And"); + case Node::Prec::Xor: + return printStr("Node::Prec::Xor"); + case Node::Prec::Ior: + return printStr("Node::Prec::Ior"); + case Node::Prec::AndIf: + return printStr("Node::Prec::AndIf"); + case Node::Prec::OrIf: + return printStr("Node::Prec::OrIf"); + case Node::Prec::Conditional: + return printStr("Node::Prec::Conditional"); + case Node::Prec::Assign: + return printStr("Node::Prec::Assign"); + case Node::Prec::Comma: + return printStr("Node::Prec::Comma"); + case Node::Prec::Default: + return printStr("Node::Prec::Default"); + } } void newLine() { Index: libcxxabi/src/demangle/ItaniumDemangle.h =================================================================== --- libcxxabi/src/demangle/ItaniumDemangle.h +++ libcxxabi/src/demangle/ItaniumDemangle.h @@ -538,7 +538,7 @@ const StringView Postfix; public: - PostfixQualifiedType(Node *Ty_, StringView Postfix_) + PostfixQualifiedType(const Node *Ty_, StringView Postfix_) : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} template void match(Fn F) const { F(Ty, Postfix); } @@ -1128,9 +1128,8 @@ const Node *Dimension; public: - VectorType(const Node *BaseType_, Node *Dimension_) - : Node(KVectorType), BaseType(BaseType_), - Dimension(Dimension_) {} + VectorType(const Node *BaseType_, const Node *Dimension_) + : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {} template void match(Fn F) const { F(BaseType, Dimension); } @@ -1927,7 +1926,8 @@ const StringView Postfix; public: - EnclosingExpr(StringView Prefix_, Node *Infix_, Prec Prec_ = Prec::Primary) + EnclosingExpr(StringView Prefix_, const Node *Infix_, + Prec Prec_ = Prec::Primary) : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} template void match(Fn F) const { @@ -2457,7 +2457,9 @@ FOR_EACH_NODE_KIND(SPECIALIZATION) #undef SPECIALIZATION +#ifndef LLVM_UNIT_TEST #undef FOR_EACH_NODE_KIND +#endif template struct AbstractManglingParser { const char *First; Index: llvm/include/llvm/Demangle/ItaniumDemangle.h =================================================================== --- llvm/include/llvm/Demangle/ItaniumDemangle.h +++ llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -538,7 +538,7 @@ const StringView Postfix; public: - PostfixQualifiedType(Node *Ty_, StringView Postfix_) + PostfixQualifiedType(const Node *Ty_, StringView Postfix_) : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} template void match(Fn F) const { F(Ty, Postfix); } @@ -1128,9 +1128,8 @@ const Node *Dimension; public: - VectorType(const Node *BaseType_, Node *Dimension_) - : Node(KVectorType), BaseType(BaseType_), - Dimension(Dimension_) {} + VectorType(const Node *BaseType_, const Node *Dimension_) + : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {} template void match(Fn F) const { F(BaseType, Dimension); } @@ -1927,7 +1926,8 @@ const StringView Postfix; public: - EnclosingExpr(StringView Prefix_, Node *Infix_, Prec Prec_ = Prec::Primary) + EnclosingExpr(StringView Prefix_, const Node *Infix_, + Prec Prec_ = Prec::Primary) : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} template void match(Fn F) const { @@ -2457,7 +2457,9 @@ FOR_EACH_NODE_KIND(SPECIALIZATION) #undef SPECIALIZATION +#ifndef LLVM_UNIT_TEST #undef FOR_EACH_NODE_KIND +#endif template struct AbstractManglingParser { const char *First; Index: llvm/lib/Demangle/ItaniumDemangle.cpp =================================================================== --- llvm/lib/Demangle/ItaniumDemangle.cpp +++ llvm/lib/Demangle/ItaniumDemangle.cpp @@ -172,9 +172,49 @@ return printStr("TemplateParamKind::Template"); } } - void print(llvm::itanium_demangle::Node::Prec) { - // Do nothing, the printing functions handle precedence with parentheses - // already. + void print(Node::Prec P) { + switch (P) { + case Node::Prec::Primary: + return printStr("Node::Prec::Primary"); + case Node::Prec::Postfix: + return printStr("Node::Prec::Postfix"); + case Node::Prec::Unary: + return printStr("Node::Prec::Unary"); + case Node::Prec::Cast: + return printStr("Node::Prec::Cast"); + case Node::Prec::PtrMem: + return printStr("Node::Prec::PtrMem"); + case Node::Prec::Multiplicative: + return printStr("Node::Prec::Multiplicative"); + case Node::Prec::Additive: + return printStr("Node::Prec::Additive"); + case Node::Prec::Shift: + return printStr("Node::Prec::Shift"); + case Node::Prec::Spaceship: + return printStr("Node::Prec::Spaceship"); + case Node::Prec::Relational: + return printStr("Node::Prec::Relational"); + case Node::Prec::Equality: + return printStr("Node::Prec::Equality"); + case Node::Prec::And: + return printStr("Node::Prec::And"); + case Node::Prec::Xor: + return printStr("Node::Prec::Xor"); + case Node::Prec::Ior: + return printStr("Node::Prec::Ior"); + case Node::Prec::AndIf: + return printStr("Node::Prec::AndIf"); + case Node::Prec::OrIf: + return printStr("Node::Prec::OrIf"); + case Node::Prec::Conditional: + return printStr("Node::Prec::Conditional"); + case Node::Prec::Assign: + return printStr("Node::Prec::Assign"); + case Node::Prec::Comma: + return printStr("Node::Prec::Comma"); + case Node::Prec::Default: + return printStr("Node::Prec::Default"); + } } void newLine() { Index: llvm/unittests/Demangle/ItaniumDemangleTest.cpp =================================================================== --- llvm/unittests/Demangle/ItaniumDemangleTest.cpp +++ llvm/unittests/Demangle/ItaniumDemangleTest.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#define LLVM_UNIT_TEST // Stop demangler undefing FOR_EACH_NODE_KIND #include "llvm/Demangle/ItaniumDemangle.h" #include "llvm/Support/Allocator.h" #include "gmock/gmock.h" @@ -34,6 +35,29 @@ }; } // namespace +namespace { +// Make sure the node matchers provide constructor parameters. This is a +// compilation test. +template struct Ctor { + template void operator()(Args &&...args) { + auto _ = NT(std::forward(args)...); + } +}; + +template void Visit(const NT *Node) { Node->match(Ctor{}); } +#define NOMATCHER(X) \ + template <> void Visit(const itanium_demangle::X *) {} +// Some nodes have no match member. +NOMATCHER(ForwardTemplateReference) +#undef NOMATCHER + +void __attribute__((used)) Visitor() { +#define CALL(X) Visit(static_cast(nullptr)); + FOR_EACH_NODE_KIND(CALL) +#undef CALL +} +} // namespace + TEST(ItaniumDemangle, MethodOverride) { struct TestParser : AbstractManglingParser { std::vector Types;