1 //===------------------ ItaniumDemangleTest.cpp ---------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Demangle/ItaniumDemangle.h"
10 #include "llvm/Support/Allocator.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
14 #include <string_view>
18 using namespace llvm::itanium_demangle
;
22 BumpPtrAllocator Alloc
;
25 void reset() { Alloc
.Reset(); }
27 template <typename T
, typename
... Args
> T
*makeNode(Args
&&... args
) {
28 return new (Alloc
.Allocate(sizeof(T
), alignof(T
)))
29 T(std::forward
<Args
>(args
)...);
32 void *allocateNodeArray(size_t sz
) {
33 return Alloc
.Allocate(sizeof(Node
*) * sz
, alignof(Node
*));
38 namespace NodeMatcher
{
39 // Make sure the node matchers provide constructor parameters. This is a
41 template <typename NT
> struct Ctor
{
42 template <typename
... Args
> void operator()(Args
&&...args
) {
43 auto _
= NT(std::forward
<Args
>(args
)...);
47 template <typename NT
> void Visit(const NT
*Node
) { Node
->match(Ctor
<NT
>{}); }
48 #define NOMATCHER(X) \
49 template <> void Visit<itanium_demangle::X>(const itanium_demangle::X *) {}
50 // Some nodes have no match member.
51 NOMATCHER(ForwardTemplateReference
)
55 #define NODE(X) Visit(static_cast<const itanium_demangle::X *>(nullptr));
56 #include "llvm/Demangle/ItaniumNodes.def"
58 } // namespace NodeMatcher
60 // Verify Operator table is ordered
61 TEST(ItaniumDemangle
, OperatorOrdering
) {
62 struct TestParser
: AbstractManglingParser
<TestParser
, TestAllocator
> {};
63 for (const auto *Op
= &TestParser::Ops
[0];
64 Op
!= &TestParser::Ops
[TestParser::NumOps
- 1]; Op
++)
65 ASSERT_LT(Op
[0], Op
[1]);
68 TEST(ItaniumDemangle
, MethodOverride
) {
69 struct TestParser
: AbstractManglingParser
<TestParser
, TestAllocator
> {
70 std::vector
<char> Types
;
72 TestParser(const char *Str
)
73 : AbstractManglingParser(Str
, Str
+ strlen(Str
)) {}
76 Types
.push_back(*First
);
77 return AbstractManglingParser
<TestParser
, TestAllocator
>::parseType();
81 TestParser
Parser("_Z1fIiEjl");
82 ASSERT_NE(nullptr, Parser
.parse());
83 EXPECT_THAT(Parser
.Types
, testing::ElementsAre('i', 'j', 'l'));
86 static std::string
toString(OutputBuffer
&OB
) {
87 std::string_view SV
= OB
;
88 return {SV
.begin(), SV
.end()};
91 TEST(ItaniumDemangle
, HalfType
) {
92 struct TestParser
: AbstractManglingParser
<TestParser
, TestAllocator
> {
93 std::vector
<std::string
> Types
;
95 TestParser(const char *Str
)
96 : AbstractManglingParser(Str
, Str
+ strlen(Str
)) {}
100 Node
*N
= AbstractManglingParser
<TestParser
, TestAllocator
>::parseType();
102 std::string_view Name
= N
->getBaseName();
104 Types
.push_back(std::string(Name
.begin(), Name
.end()));
106 Types
.push_back(toString(OB
));
107 std::free(OB
.getBuffer());
112 // void f(A<_Float16>, _Float16);
113 TestParser
Parser("_Z1f1AIDF16_EDF16_");
114 ASSERT_NE(nullptr, Parser
.parse());
115 EXPECT_THAT(Parser
.Types
, testing::ElementsAre("_Float16", "A", "_Float16"));