1 //===------------------ ItaniumDemangleTest.cpp ---------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Demangle/ItaniumDemangle.h"
10 #include "llvm/Support/Allocator.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 #include <cstdlib>
14 #include <vector>
15 
16 using namespace llvm;
17 using namespace llvm::itanium_demangle;
18 
19 namespace {
20 class TestAllocator {
21   BumpPtrAllocator Alloc;
22 
23 public:
24   void reset() { Alloc.Reset(); }
25 
26   template <typename T, typename... Args> T *makeNode(Args &&... args) {
27     return new (Alloc.Allocate(sizeof(T), alignof(T)))
28         T(std::forward<Args>(args)...);
29   }
30 
31   void *allocateNodeArray(size_t sz) {
32     return Alloc.Allocate(sizeof(Node *) * sz, alignof(Node *));
33   }
34 };
35 } // namespace
36 
37 TEST(ItaniumDemangle, MethodOverride) {
38   struct TestParser : AbstractManglingParser<TestParser, TestAllocator> {
39     std::vector<char> Types;
40 
41     TestParser(const char *Str)
42         : AbstractManglingParser(Str, Str + strlen(Str)) {}
43 
44     Node *parseType() {
45       Types.push_back(*First);
46       return AbstractManglingParser<TestParser, TestAllocator>::parseType();
47     }
48   };
49 
50   TestParser Parser("_Z1fIiEjl");
51   ASSERT_NE(nullptr, Parser.parse());
52   EXPECT_THAT(Parser.Types, testing::ElementsAre('i', 'j', 'l'));
53 }
54 
55 static std::string toString(OutputBuffer &OB) {
56   StringView SV = OB;
57   return {SV.begin(), SV.end()};
58 }
59 
60 TEST(ItaniumDemangle, HalfType) {
61   struct TestParser : AbstractManglingParser<TestParser, TestAllocator> {
62     std::vector<std::string> Types;
63 
64     TestParser(const char *Str)
65         : AbstractManglingParser(Str, Str + strlen(Str)) {}
66 
67     Node *parseType() {
68       OutputBuffer OB;
69       Node *N = AbstractManglingParser<TestParser, TestAllocator>::parseType();
70       N->printLeft(OB);
71       StringView Name = N->getBaseName();
72       if (!Name.empty())
73         Types.push_back(std::string(Name.begin(), Name.end()));
74       else
75         Types.push_back(toString(OB));
76       std::free(OB.getBuffer());
77       return N;
78     }
79   };
80 
81   // void f(A<_Float16>, _Float16);
82   TestParser Parser("_Z1f1AIDF16_EDF16_");
83   ASSERT_NE(nullptr, Parser.parse());
84   EXPECT_THAT(Parser.Types, testing::ElementsAre("_Float16", "A", "_Float16"));
85 }
86