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