xref: /llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp (revision 7c59e8001a3b66be545a890a26ad8a24a6c9fe4b)
1f4c15824SPavel Labath //===------------------ ItaniumDemangleTest.cpp ---------------------------===//
2f4c15824SPavel Labath //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f4c15824SPavel Labath //
7f4c15824SPavel Labath //===----------------------------------------------------------------------===//
8f4c15824SPavel Labath 
9f4c15824SPavel Labath #include "llvm/Demangle/ItaniumDemangle.h"
10f4c15824SPavel Labath #include "llvm/Support/Allocator.h"
11f4c15824SPavel Labath #include "gmock/gmock.h"
12f4c15824SPavel Labath #include "gtest/gtest.h"
13f4c15824SPavel Labath #include <cstdlib>
14*7c59e800SNick Desaulniers #include <string_view>
15f4c15824SPavel Labath #include <vector>
16f4c15824SPavel Labath 
17f4c15824SPavel Labath using namespace llvm;
18f4c15824SPavel Labath using namespace llvm::itanium_demangle;
19f4c15824SPavel Labath 
20f4c15824SPavel Labath namespace {
21f4c15824SPavel Labath class TestAllocator {
22f4c15824SPavel Labath   BumpPtrAllocator Alloc;
23f4c15824SPavel Labath 
24f4c15824SPavel Labath public:
reset()25f4c15824SPavel Labath   void reset() { Alloc.Reset(); }
26f4c15824SPavel Labath 
makeNode(Args &&...args)27f4c15824SPavel Labath   template <typename T, typename... Args> T *makeNode(Args &&... args) {
28f4c15824SPavel Labath     return new (Alloc.Allocate(sizeof(T), alignof(T)))
29f4c15824SPavel Labath         T(std::forward<Args>(args)...);
30f4c15824SPavel Labath   }
31f4c15824SPavel Labath 
allocateNodeArray(size_t sz)32f4c15824SPavel Labath   void *allocateNodeArray(size_t sz) {
33f4c15824SPavel Labath     return Alloc.Allocate(sizeof(Node *) * sz, alignof(Node *));
34f4c15824SPavel Labath   }
35f4c15824SPavel Labath };
36f4c15824SPavel Labath } // namespace
37f4c15824SPavel Labath 
38d7692c0fSNathan Sidwell namespace NodeMatcher {
39abffdd88SNathan Sidwell // Make sure the node matchers provide constructor parameters. This is a
40abffdd88SNathan Sidwell // compilation test.
41abffdd88SNathan Sidwell template <typename NT> struct Ctor {
operator ()NodeMatcher::Ctor42abffdd88SNathan Sidwell   template <typename... Args> void operator()(Args &&...args) {
43abffdd88SNathan Sidwell     auto _ = NT(std::forward<Args>(args)...);
44abffdd88SNathan Sidwell   }
45abffdd88SNathan Sidwell };
46abffdd88SNathan Sidwell 
Visit(const NT * Node)47abffdd88SNathan Sidwell template <typename NT> void Visit(const NT *Node) { Node->match(Ctor<NT>{}); }
48abffdd88SNathan Sidwell #define NOMATCHER(X)                                                           \
49abffdd88SNathan Sidwell   template <> void Visit<itanium_demangle::X>(const itanium_demangle::X *) {}
50abffdd88SNathan Sidwell // Some nodes have no match member.
NOMATCHER(ForwardTemplateReference)51abffdd88SNathan Sidwell NOMATCHER(ForwardTemplateReference)
52abffdd88SNathan Sidwell #undef NOMATCHER
53abffdd88SNathan Sidwell 
54d7692c0fSNathan Sidwell void Visitor() {
55abffdd88SNathan Sidwell #define NODE(X) Visit(static_cast<const itanium_demangle::X *>(nullptr));
56abffdd88SNathan Sidwell #include "llvm/Demangle/ItaniumNodes.def"
57abffdd88SNathan Sidwell }
58d7692c0fSNathan Sidwell } // namespace NodeMatcher
59abffdd88SNathan Sidwell 
60c47bcf9aSNathan Sidwell // Verify Operator table is ordered
TEST(ItaniumDemangle,OperatorOrdering)61c47bcf9aSNathan Sidwell TEST(ItaniumDemangle, OperatorOrdering) {
62c47bcf9aSNathan Sidwell   struct TestParser : AbstractManglingParser<TestParser, TestAllocator> {};
63c47bcf9aSNathan Sidwell   for (const auto *Op = &TestParser::Ops[0];
64c47bcf9aSNathan Sidwell        Op != &TestParser::Ops[TestParser::NumOps - 1]; Op++)
65c47bcf9aSNathan Sidwell     ASSERT_LT(Op[0], Op[1]);
66c47bcf9aSNathan Sidwell }
67c47bcf9aSNathan Sidwell 
TEST(ItaniumDemangle,MethodOverride)68f4c15824SPavel Labath TEST(ItaniumDemangle, MethodOverride) {
69f4c15824SPavel Labath   struct TestParser : AbstractManglingParser<TestParser, TestAllocator> {
70f4c15824SPavel Labath     std::vector<char> Types;
71f4c15824SPavel Labath 
72f4c15824SPavel Labath     TestParser(const char *Str)
73f4c15824SPavel Labath         : AbstractManglingParser(Str, Str + strlen(Str)) {}
74f4c15824SPavel Labath 
75f4c15824SPavel Labath     Node *parseType() {
76f4c15824SPavel Labath       Types.push_back(*First);
77f4c15824SPavel Labath       return AbstractManglingParser<TestParser, TestAllocator>::parseType();
78f4c15824SPavel Labath     }
79f4c15824SPavel Labath   };
80f4c15824SPavel Labath 
81f4c15824SPavel Labath   TestParser Parser("_Z1fIiEjl");
82f4c15824SPavel Labath   ASSERT_NE(nullptr, Parser.parse());
83f4c15824SPavel Labath   EXPECT_THAT(Parser.Types, testing::ElementsAre('i', 'j', 'l'));
84f4c15824SPavel Labath }
8592ac146bSWang, Pengfei 
toString(OutputBuffer & OB)862e97236aSLuís Ferreira static std::string toString(OutputBuffer &OB) {
87*7c59e800SNick Desaulniers   std::string_view SV = OB;
881066e397SNathan Sidwell   return {SV.begin(), SV.end()};
8992ac146bSWang, Pengfei }
9092ac146bSWang, Pengfei 
TEST(ItaniumDemangle,HalfType)9192ac146bSWang, Pengfei TEST(ItaniumDemangle, HalfType) {
9292ac146bSWang, Pengfei   struct TestParser : AbstractManglingParser<TestParser, TestAllocator> {
9392ac146bSWang, Pengfei     std::vector<std::string> Types;
9492ac146bSWang, Pengfei 
9592ac146bSWang, Pengfei     TestParser(const char *Str)
9692ac146bSWang, Pengfei         : AbstractManglingParser(Str, Str + strlen(Str)) {}
9792ac146bSWang, Pengfei 
9892ac146bSWang, Pengfei     Node *parseType() {
992e97236aSLuís Ferreira       OutputBuffer OB;
10092ac146bSWang, Pengfei       Node *N = AbstractManglingParser<TestParser, TestAllocator>::parseType();
1012e97236aSLuís Ferreira       N->printLeft(OB);
102*7c59e800SNick Desaulniers       std::string_view Name = N->getBaseName();
10392ac146bSWang, Pengfei       if (!Name.empty())
10492ac146bSWang, Pengfei         Types.push_back(std::string(Name.begin(), Name.end()));
10592ac146bSWang, Pengfei       else
1062e97236aSLuís Ferreira         Types.push_back(toString(OB));
1072e97236aSLuís Ferreira       std::free(OB.getBuffer());
10892ac146bSWang, Pengfei       return N;
10992ac146bSWang, Pengfei     }
11092ac146bSWang, Pengfei   };
11192ac146bSWang, Pengfei 
11292ac146bSWang, Pengfei   // void f(A<_Float16>, _Float16);
11392ac146bSWang, Pengfei   TestParser Parser("_Z1f1AIDF16_EDF16_");
11492ac146bSWang, Pengfei   ASSERT_NE(nullptr, Parser.parse());
11592ac146bSWang, Pengfei   EXPECT_THAT(Parser.Types, testing::ElementsAre("_Float16", "A", "_Float16"));
11692ac146bSWang, Pengfei }
117