Coverage Report

Created: 2026-10-28 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/llvm-project/libcxxabi/src/demangle/ItaniumDemangle.h
Line
Count
Source
1
//===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===//
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
// Generic itanium demangler library.
10
// There are two copies of this file in the source tree.  The one under
11
// libcxxabi is the original and the one under llvm is the copy.  Use
12
// cp-to-llvm.sh to update the copy.  See README.txt for more details.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef DEMANGLE_ITANIUMDEMANGLE_H
17
#define DEMANGLE_ITANIUMDEMANGLE_H
18
19
#include "DemangleConfig.h"
20
#include "StringViewExtras.h"
21
#include "Utility.h"
22
#include <algorithm>
23
#include <cctype>
24
#include <cstdint>
25
#include <cstdio>
26
#include <cstdlib>
27
#include <cstring>
28
#include <limits>
29
#include <new>
30
#include <string_view>
31
#include <type_traits>
32
#include <utility>
33
34
#if defined(__clang__)
35
#pragma clang diagnostic push
36
#pragma clang diagnostic ignored "-Wunused-template"
37
#endif
38
39
DEMANGLE_NAMESPACE_BEGIN
40
41
template <class T, size_t N> class PODSmallVector {
42
  static_assert(std::is_trivially_copyable<T>::value,
43
                "T is required to be a trivially copyable type");
44
  static_assert(std::is_trivially_default_constructible<T>::value,
45
                "T is required to be trivially default constructible");
46
  static_assert(N > 0, "PODSmallVector requires a non-zero inline capacity");
47
  T *First = nullptr;
48
  T *Last = nullptr;
49
  T *Cap = nullptr;
50
  T Inline[N] = {};
51
52
116k
  bool isInline() const { return First == Inline; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::isInline() const
Line
Count
Source
52
22
  bool isInline() const { return First == Inline; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::isInline() const
Line
Count
Source
52
49.9k
  bool isInline() const { return First == Inline; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::isInline() const
Line
Count
Source
52
65.8k
  bool isInline() const { return First == Inline; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::isInline() const
Line
Count
Source
52
346
  bool isInline() const { return First == Inline; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::isInline() const
53
54
1.49k
  void clearInline() {
55
1.49k
    First = Inline;
56
1.49k
    Last = Inline;
57
1.49k
    Cap = Inline + N;
58
1.49k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::clearInline()
Line
Count
Source
54
1.41k
  void clearInline() {
55
1.41k
    First = Inline;
56
1.41k
    Last = Inline;
57
1.41k
    Cap = Inline + N;
58
1.41k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::clearInline()
Line
Count
Source
54
85
  void clearInline() {
55
85
    First = Inline;
56
85
    Last = Inline;
57
85
    Cap = Inline + N;
58
85
  }
59
60
1.76k
  void reserve(size_t NewCap) {
61
1.76k
    size_t S = size();
62
1.76k
    if (isInline()) {
63
1.33k
      auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
64
1.33k
      if (Tmp == nullptr)
65
0
        std::abort();
66
1.33k
      std::copy(First, Last, Tmp);
67
1.33k
      First = Tmp;
68
1.33k
    } else {
69
431
      First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
70
431
      if (First == nullptr)
71
0
        std::abort();
72
431
    }
73
1.76k
    Last = First + S;
74
1.76k
    Cap = First + NewCap;
75
1.76k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::reserve(unsigned long)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::reserve(unsigned long)
Line
Count
Source
60
1.32k
  void reserve(size_t NewCap) {
61
1.32k
    size_t S = size();
62
1.32k
    if (isInline()) {
63
1.27k
      auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
64
1.27k
      if (Tmp == nullptr)
65
0
        std::abort();
66
1.27k
      std::copy(First, Last, Tmp);
67
1.27k
      First = Tmp;
68
1.27k
    } else {
69
53
      First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
70
53
      if (First == nullptr)
71
0
        std::abort();
72
53
    }
73
1.32k
    Last = First + S;
74
1.32k
    Cap = First + NewCap;
75
1.32k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::reserve(unsigned long)
Line
Count
Source
60
136
  void reserve(size_t NewCap) {
61
136
    size_t S = size();
62
136
    if (isInline()) {
63
29
      auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
64
29
      if (Tmp == nullptr)
65
0
        std::abort();
66
29
      std::copy(First, Last, Tmp);
67
29
      First = Tmp;
68
107
    } else {
69
107
      First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
70
107
      if (First == nullptr)
71
0
        std::abort();
72
107
    }
73
136
    Last = First + S;
74
136
    Cap = First + NewCap;
75
136
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::reserve(unsigned long)
Line
Count
Source
60
302
  void reserve(size_t NewCap) {
61
302
    size_t S = size();
62
302
    if (isInline()) {
63
31
      auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
64
31
      if (Tmp == nullptr)
65
0
        std::abort();
66
31
      std::copy(First, Last, Tmp);
67
31
      First = Tmp;
68
271
    } else {
69
271
      First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
70
271
      if (First == nullptr)
71
0
        std::abort();
72
271
    }
73
302
    Last = First + S;
74
302
    Cap = First + NewCap;
75
302
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::reserve(unsigned long)
76
77
public:
78
36.6k
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::PODSmallVector()
Line
Count
Source
78
44
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::PODSmallVector()
Line
Count
Source
78
26.8k
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::PODSmallVector()
Line
Count
Source
78
9.74k
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::PODSmallVector()
Line
Count
Source
78
22
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::PODSmallVector()
79
80
  PODSmallVector(const PODSmallVector &) = delete;
81
  PODSmallVector &operator=(const PODSmallVector &) = delete;
82
83
  PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
84
    if (Other.isInline()) {
85
      std::copy(Other.begin(), Other.end(), First);
86
      Last = First + Other.size();
87
      Other.clear();
88
      return;
89
    }
90
91
    First = Other.First;
92
    Last = Other.Last;
93
    Cap = Other.Cap;
94
    Other.clearInline();
95
  }
96
97
38.8k
  PODSmallVector &operator=(PODSmallVector &&Other) {
98
38.8k
    if (Other.isInline()) {
99
36.1k
      if (!isInline()) {
100
42
        std::free(First);
101
42
        clearInline();
102
42
      }
103
36.1k
      std::copy(Other.begin(), Other.end(), First);
104
36.1k
      Last = First + Other.size();
105
36.1k
      Other.clear();
106
36.1k
      return *this;
107
36.1k
    }
108
109
2.71k
    if (isInline()) {
110
1.45k
      First = Other.First;
111
1.45k
      Last = Other.Last;
112
1.45k
      Cap = Other.Cap;
113
1.45k
      Other.clearInline();
114
1.45k
      return *this;
115
1.45k
    }
116
117
1.26k
    std::swap(First, Other.First);
118
1.26k
    std::swap(Last, Other.Last);
119
1.26k
    std::swap(Cap, Other.Cap);
120
1.26k
    Other.clear();
121
1.26k
    return *this;
122
2.71k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::operator=((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>&&)
Line
Count
Source
97
19.4k
  PODSmallVector &operator=(PODSmallVector &&Other) {
98
19.4k
    if (Other.isInline()) {
99
16.7k
      if (!isInline()) {
100
13
        std::free(First);
101
13
        clearInline();
102
13
      }
103
16.7k
      std::copy(Other.begin(), Other.end(), First);
104
16.7k
      Last = First + Other.size();
105
16.7k
      Other.clear();
106
16.7k
      return *this;
107
16.7k
    }
108
109
2.66k
    if (isInline()) {
110
1.40k
      First = Other.First;
111
1.40k
      Last = Other.Last;
112
1.40k
      Cap = Other.Cap;
113
1.40k
      Other.clearInline();
114
1.40k
      return *this;
115
1.40k
    }
116
117
1.26k
    std::swap(First, Other.First);
118
1.26k
    std::swap(Last, Other.Last);
119
1.26k
    std::swap(Cap, Other.Cap);
120
1.26k
    Other.clear();
121
1.26k
    return *this;
122
2.66k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::operator=((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>&&)
Line
Count
Source
97
19.4k
  PODSmallVector &operator=(PODSmallVector &&Other) {
98
19.4k
    if (Other.isInline()) {
99
19.3k
      if (!isInline()) {
100
29
        std::free(First);
101
29
        clearInline();
102
29
      }
103
19.3k
      std::copy(Other.begin(), Other.end(), First);
104
19.3k
      Last = First + Other.size();
105
19.3k
      Other.clear();
106
19.3k
      return *this;
107
19.3k
    }
108
109
56
    if (isInline()) {
110
56
      First = Other.First;
111
56
      Last = Other.Last;
112
56
      Cap = Other.Cap;
113
56
      Other.clearInline();
114
56
      return *this;
115
56
    }
116
117
0
    std::swap(First, Other.First);
118
0
    std::swap(Last, Other.Last);
119
0
    std::swap(Cap, Other.Cap);
120
0
    Other.clear();
121
0
    return *this;
122
56
  }
123
124
  // NOLINTNEXTLINE(readability-identifier-naming)
125
3.79M
  void push_back(const T &Elem) {
126
3.79M
    if (Last == Cap)
127
1.76k
      reserve(size() * 2);
128
3.79M
    *Last++ = Elem;
129
3.79M
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::push_back((anonymous namespace)::itanium_demangle::ForwardTemplateReference* const&)
Line
Count
Source
125
2
  void push_back(const T &Elem) {
126
2
    if (Last == Cap)
127
0
      reserve(size() * 2);
128
2
    *Last++ = Elem;
129
2
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::push_back((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>* const&)
Line
Count
Source
125
19.9k
  void push_back(const T &Elem) {
126
19.9k
    if (Last == Cap)
127
1.32k
      reserve(size() * 2);
128
19.9k
    *Last++ = Elem;
129
19.9k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::push_back((anonymous namespace)::itanium_demangle::Node* const&)
Line
Count
Source
125
120k
  void push_back(const T &Elem) {
126
120k
    if (Last == Cap)
127
136
      reserve(size() * 2);
128
120k
    *Last++ = Elem;
129
120k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::push_back((anonymous namespace)::itanium_demangle::Node* const&)
Line
Count
Source
125
3.64M
  void push_back(const T &Elem) {
126
3.64M
    if (Last == Cap)
127
302
      reserve(size() * 2);
128
3.64M
    *Last++ = Elem;
129
3.64M
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::push_back((anonymous namespace)::itanium_demangle::Node const* const&)
130
131
  // NOLINTNEXTLINE(readability-identifier-naming)
132
435
  void pop_back() {
133
435
    DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
134
435
    --Last;
135
435
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::pop_back()
Line
Count
Source
132
324
  void pop_back() {
133
324
    DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
134
324
    --Last;
135
324
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::pop_back()
Line
Count
Source
132
111
  void pop_back() {
133
111
    DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
134
111
    --Last;
135
111
  }
136
137
153k
  void shrinkToSize(size_t Index) {
138
153k
    DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
139
153k
    Last = First + Index;
140
153k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::shrinkToSize(unsigned long)
Line
Count
Source
137
17.0k
  void shrinkToSize(size_t Index) {
138
17.0k
    DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
139
17.0k
    Last = First + Index;
140
17.0k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::shrinkToSize(unsigned long)
Line
Count
Source
137
6.33k
  void shrinkToSize(size_t Index) {
138
6.33k
    DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
139
6.33k
    Last = First + Index;
140
6.33k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::shrinkToSize(unsigned long)
Line
Count
Source
137
129k
  void shrinkToSize(size_t Index) {
138
129k
    DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
139
129k
    Last = First + Index;
140
129k
  }
141
142
316k
  T *begin() { return First; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::begin()
Line
Count
Source
142
135k
  T *begin() { return First; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::begin()
Line
Count
Source
142
46.1k
  T *begin() { return First; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::begin()
Line
Count
Source
142
135k
  T *begin() { return First; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::begin()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::begin()
143
165k
  T *end() { return Last; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::end()
Line
Count
Source
143
16.7k
  T *end() { return Last; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::end()
Line
Count
Source
143
19.3k
  T *end() { return Last; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::end()
Line
Count
Source
143
129k
  T *end() { return Last; }
144
145
5.52k
  bool empty() const { return First == Last; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::empty() const
Line
Count
Source
145
5.51k
  bool empty() const { return First == Last; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::empty() const
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::empty() const
Line
Count
Source
145
1
  bool empty() const { return First == Last; }
146
1.38M
  size_t size() const { return static_cast<size_t>(Last - First); }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::size() const
Line
Count
Source
146
339k
  size_t size() const { return static_cast<size_t>(Last - First); }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::size() const
Line
Count
Source
146
73.5k
  size_t size() const { return static_cast<size_t>(Last - First); }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::size() const
Line
Count
Source
146
20.6k
  size_t size() const { return static_cast<size_t>(Last - First); }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::size() const
Line
Count
Source
146
949k
  size_t size() const { return static_cast<size_t>(Last - First); }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::size() const
147
  T &back() {
148
    DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
149
    return *(Last - 1);
150
  }
151
150k
  T &operator[](size_t Index) {
152
150k
    DEMANGLE_ASSERT(Index < size(), "Invalid access!");
153
150k
    return *(begin() + Index);
154
150k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::operator[](unsigned long)
Line
Count
Source
151
118k
  T &operator[](size_t Index) {
152
118k
    DEMANGLE_ASSERT(Index < size(), "Invalid access!");
153
118k
    return *(begin() + Index);
154
118k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::operator[](unsigned long)
Line
Count
Source
151
26.7k
  T &operator[](size_t Index) {
152
26.7k
    DEMANGLE_ASSERT(Index < size(), "Invalid access!");
153
26.7k
    return *(begin() + Index);
154
26.7k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::operator[](unsigned long)
Line
Count
Source
151
5.41k
  T &operator[](size_t Index) {
152
5.41k
    DEMANGLE_ASSERT(Index < size(), "Invalid access!");
153
5.41k
    return *(begin() + Index);
154
5.41k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::operator[](unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::operator[](unsigned long)
155
63.8k
  void clear() { Last = First; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::clear()
Line
Count
Source
155
32.0k
  void clear() { Last = First; }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::clear()
Line
Count
Source
155
31.8k
  void clear() { Last = First; }
156
157
36.6k
  ~PODSmallVector() {
158
36.6k
    if (!isInline())
159
1.29k
      std::free(First);
160
36.6k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::~PODSmallVector()
Line
Count
Source
157
22
  ~PODSmallVector() {
158
22
    if (!isInline())
159
0
      std::free(First);
160
22
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::~PODSmallVector()
Line
Count
Source
157
9.74k
  ~PODSmallVector() {
158
9.74k
    if (!isInline())
159
1.26k
      std::free(First);
160
9.74k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::~PODSmallVector()
Line
Count
Source
157
26.8k
  ~PODSmallVector() {
158
26.8k
    if (!isInline())
159
0
      std::free(First);
160
26.8k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::~PODSmallVector()
Line
Count
Source
157
44
  ~PODSmallVector() {
158
44
    if (!isInline())
159
31
      std::free(First);
160
44
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::~PODSmallVector()
161
};
162
163
class NodeArray;
164
165
// Base class of all AST nodes. The AST is built by the parser, then is
166
// traversed by the printLeft/Right functions to produce a demangled string.
167
class Node {
168
public:
169
  enum Kind : uint8_t {
170
#define NODE(NodeKind) K##NodeKind,
171
#include "ItaniumNodes.def"
172
  };
173
174
  /// Three-way bool to track a cached value. Unknown is possible if this node
175
  /// has an unexpanded parameter pack below it that may affect this cache.
176
  enum class Cache : uint8_t { Yes, No, Unknown, };
177
178
  /// Operator precedence for expression nodes. Used to determine required
179
  /// parens in expression emission.
180
  enum class Prec : uint8_t {
181
    Primary,
182
    Postfix,
183
    Unary,
184
    Cast,
185
    PtrMem,
186
    Multiplicative,
187
    Additive,
188
    Shift,
189
    Spaceship,
190
    Relational,
191
    Equality,
192
    And,
193
    Xor,
194
    Ior,
195
    AndIf,
196
    OrIf,
197
    Conditional,
198
    Assign,
199
    Comma,
200
    Default,
201
  };
202
203
private:
204
  Kind K;
205
206
  Prec Precedence : 6;
207
208
protected:
209
  /// Tracks if this node has a component on its right side, in which case we
210
  /// need to call printRight.
211
  Cache RHSComponentCache : 2;
212
213
  /// Track if this node is a (possibly qualified) array type. This can affect
214
  /// how we format the output string.
215
  Cache ArrayCache : 2;
216
217
  /// Track if this node is a (possibly qualified) function type. This can
218
  /// affect how we format the output string.
219
  Cache FunctionCache : 2;
220
221
public:
222
  Node(Kind K_, Prec Precedence_ = Prec::Primary,
223
       Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
224
       Cache FunctionCache_ = Cache::No)
225
3.68M
      : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
226
3.68M
        ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
227
  Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
228
       Cache FunctionCache_ = Cache::No)
229
590k
      : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
230
590k
             FunctionCache_) {}
231
232
  /// Visit the most-derived object corresponding to this object.
233
  template<typename Fn> void visit(Fn F) const;
234
235
  // The following function is provided by all derived classes:
236
  //
237
  // Call F with arguments that, when passed to the constructor of this node,
238
  // would construct an equivalent node.
239
  //template<typename Fn> void match(Fn F) const;
240
241
0
  bool hasRHSComponent(OutputBuffer &OB) const {
242
0
    if (RHSComponentCache != Cache::Unknown)
243
0
      return RHSComponentCache == Cache::Yes;
244
0
    return hasRHSComponentSlow(OB);
245
0
  }
246
247
22
  bool hasArray(OutputBuffer &OB) const {
248
22
    if (ArrayCache != Cache::Unknown)
249
22
      return ArrayCache == Cache::Yes;
250
0
    return hasArraySlow(OB);
251
22
  }
252
253
21
  bool hasFunction(OutputBuffer &OB) const {
254
21
    if (FunctionCache != Cache::Unknown)
255
21
      return FunctionCache == Cache::Yes;
256
0
    return hasFunctionSlow(OB);
257
21
  }
258
259
212k
  Kind getKind() const { return K; }
260
261
197
  Prec getPrecedence() const { return Precedence; }
262
584k
  Cache getRHSComponentCache() const { return RHSComponentCache; }
263
429k
  Cache getArrayCache() const { return ArrayCache; }
264
429k
  Cache getFunctionCache() const { return FunctionCache; }
265
266
0
  virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
267
0
  virtual bool hasArraySlow(OutputBuffer &) const { return false; }
268
0
  virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
269
270
  // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
271
  // get at a node that actually represents some concrete syntax.
272
0
  virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
273
274
  // Print this node as an expression operand, surrounding it in parentheses if
275
  // its precedence is [Strictly] weaker than P.
276
  void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
277
197
                      bool StrictlyWorse = false) const {
278
197
    bool Paren =
279
197
        unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
280
197
    if (Paren)
281
0
      OB.printOpen();
282
197
    print(OB);
283
197
    if (Paren)
284
0
      OB.printClose();
285
197
  }
286
287
221
  void print(OutputBuffer &OB) const {
288
221
    OB.printLeft(*this);
289
221
    if (RHSComponentCache != Cache::No)
290
1
      OB.printRight(*this);
291
221
  }
292
293
  // Print an initializer list of this type. Returns true if we printed a custom
294
  // representation, false if nothing has been printed and the default
295
  // representation should be used.
296
0
  virtual bool printInitListAsType(OutputBuffer &, const NodeArray &) const {
297
0
    return false;
298
0
  }
299
300
0
  virtual std::string_view getBaseName() const { return {}; }
301
302
  // Silence compiler warnings, this dtor will never be called.
303
0
  virtual ~Node() = default;
304
305
#ifndef NDEBUG
306
  DEMANGLE_DUMP_METHOD void dump() const;
307
#endif
308
309
private:
310
  friend class OutputBuffer;
311
312
  // Print the "left" side of this Node into OutputBuffer.
313
  //
314
  // Note, should only be called from OutputBuffer implementations.
315
  // Call \ref OutputBuffer::printLeft instead.
316
  virtual void printLeft(OutputBuffer &) const = 0;
317
318
  // Print the "right". This distinction is necessary to represent C++ types
319
  // that appear on the RHS of their subtype, such as arrays or functions.
320
  // Since most types don't have such a component, provide a default
321
  // implementation.
322
  //
323
  // Note, should only be called from OutputBuffer implementations.
324
  // Call \ref OutputBuffer::printRight instead.
325
0
  virtual void printRight(OutputBuffer &) const {}
326
};
327
328
class NodeArray {
329
  Node **Elements;
330
  size_t NumElements;
331
332
public:
333
6.10k
  NodeArray() : Elements(nullptr), NumElements(0) {}
334
  NodeArray(Node **Elements_, size_t NumElements_)
335
129k
      : Elements(Elements_), NumElements(NumElements_) {}
336
337
8.25k
  bool empty() const { return NumElements == 0; }
338
0
  size_t size() const { return NumElements; }
339
340
4.13k
  Node **begin() const { return Elements; }
341
4.13k
  Node **end() const { return Elements + NumElements; }
342
343
0
  Node *operator[](size_t Idx) const { return Elements[Idx]; }
344
345
1
  void printWithComma(OutputBuffer &OB) const {
346
1
    bool FirstElement = true;
347
198
    for (size_t Idx = 0; Idx != NumElements; ++Idx) {
348
197
      size_t BeforeComma = OB.getCurrentPosition();
349
197
      if (!FirstElement)
350
196
        OB += ", ";
351
197
      size_t AfterComma = OB.getCurrentPosition();
352
197
      Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
353
354
      // Elements[Idx] is an empty parameter pack expansion, we should erase the
355
      // comma we just printed.
356
197
      if (AfterComma == OB.getCurrentPosition()) {
357
0
        OB.setCurrentPosition(BeforeComma);
358
0
        continue;
359
0
      }
360
361
197
      FirstElement = false;
362
197
    }
363
1
  }
364
365
  // Print an array of integer literals as a string literal. Returns whether we
366
  // could do so.
367
  bool printAsString(OutputBuffer &OB) const;
368
};
369
370
struct NodeArrayNode : Node {
371
  NodeArray Array;
372
25.3k
  NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
373
374
0
  template<typename Fn> void match(Fn F) const { F(Array); }
375
376
0
  void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
377
};
378
379
class DotSuffix final : public Node {
380
  const Node *Prefix;
381
  const std::string_view Suffix;
382
383
public:
384
  DotSuffix(const Node *Prefix_, std::string_view Suffix_)
385
1
      : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
386
387
0
  template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
388
389
1
  void printLeft(OutputBuffer &OB) const override {
390
1
    Prefix->print(OB);
391
1
    OB += " (";
392
1
    OB += Suffix;
393
1
    OB += ")";
394
1
  }
395
};
396
397
class VendorExtQualType final : public Node {
398
  const Node *Ty;
399
  std::string_view Ext;
400
  const Node *TA;
401
402
public:
403
  VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
404
4.02k
      : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
405
406
0
  const Node *getTy() const { return Ty; }
407
0
  std::string_view getExt() const { return Ext; }
408
0
  const Node *getTA() const { return TA; }
409
410
0
  template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
411
412
0
  void printLeft(OutputBuffer &OB) const override {
413
0
    Ty->print(OB);
414
0
    OB += " ";
415
0
    OB += Ext;
416
0
    if (TA != nullptr)
417
0
      TA->print(OB);
418
0
  }
419
};
420
421
enum FunctionRefQual : unsigned char {
422
  FrefQualNone,
423
  FrefQualLValue,
424
  FrefQualRValue,
425
};
426
427
enum Qualifiers {
428
  QualNone = 0,
429
  QualConst = 0x1,
430
  QualVolatile = 0x2,
431
  QualRestrict = 0x4,
432
};
433
434
382k
inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
435
382k
  return Q1 = static_cast<Qualifiers>(Q1 | Q2);
436
382k
}
437
438
class QualType final : public Node {
439
protected:
440
  const Qualifiers Quals;
441
  const Node *Child;
442
443
0
  void printQuals(OutputBuffer &OB) const {
444
0
    if (Quals & QualConst)
445
0
      OB += " const";
446
0
    if (Quals & QualVolatile)
447
0
      OB += " volatile";
448
0
    if (Quals & QualRestrict)
449
0
      OB += " restrict";
450
0
  }
451
452
public:
453
  QualType(const Node *Child_, Qualifiers Quals_)
454
376k
      : Node(KQualType, Child_->getRHSComponentCache(), Child_->getArrayCache(),
455
376k
             Child_->getFunctionCache()),
456
376k
        Quals(Quals_), Child(Child_) {}
457
458
0
  Qualifiers getQuals() const { return Quals; }
459
0
  const Node *getChild() const { return Child; }
460
461
0
  template<typename Fn> void match(Fn F) const { F(Child, Quals); }
462
463
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
464
0
    return Child->hasRHSComponent(OB);
465
0
  }
466
0
  bool hasArraySlow(OutputBuffer &OB) const override {
467
0
    return Child->hasArray(OB);
468
0
  }
469
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
470
0
    return Child->hasFunction(OB);
471
0
  }
472
473
0
  void printLeft(OutputBuffer &OB) const override {
474
0
    OB.printLeft(*Child);
475
0
    printQuals(OB);
476
0
  }
477
478
0
  void printRight(OutputBuffer &OB) const override { OB.printRight(*Child); }
479
};
480
481
class ConversionOperatorType final : public Node {
482
  const Node *Ty;
483
484
public:
485
  ConversionOperatorType(const Node *Ty_)
486
107
      : Node(KConversionOperatorType), Ty(Ty_) {}
487
488
0
  template<typename Fn> void match(Fn F) const { F(Ty); }
489
490
1
  void printLeft(OutputBuffer &OB) const override {
491
1
    OB += "operator ";
492
1
    Ty->print(OB);
493
1
  }
494
};
495
496
class PostfixQualifiedType final : public Node {
497
  const Node *Ty;
498
  const std::string_view Postfix;
499
500
public:
501
  PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
502
13.6k
      : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
503
504
0
  template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
505
506
2
  void printLeft(OutputBuffer &OB) const override {
507
2
    OB.printLeft(*Ty);
508
2
    OB += Postfix;
509
2
  }
510
};
511
512
class NameType final : public Node {
513
  const std::string_view Name;
514
515
public:
516
2.78M
  NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
517
518
0
  template<typename Fn> void match(Fn F) const { F(Name); }
519
520
0
  std::string_view getName() const { return Name; }
521
1.83k
  std::string_view getBaseName() const override { return Name; }
522
523
218
  void printLeft(OutputBuffer &OB) const override { OB += Name; }
524
};
525
526
class BitIntType final : public Node {
527
  const Node *Size;
528
  bool Signed;
529
530
public:
531
  BitIntType(const Node *Size_, bool Signed_)
532
1.87k
      : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
533
534
0
  template <typename Fn> void match(Fn F) const { F(Size, Signed); }
535
536
0
  void printLeft(OutputBuffer &OB) const override {
537
0
    if (!Signed)
538
0
      OB += "unsigned ";
539
0
    OB += "_BitInt";
540
0
    OB.printOpen();
541
0
    Size->printAsOperand(OB);
542
0
    OB.printClose();
543
0
  }
544
};
545
546
class ElaboratedTypeSpefType : public Node {
547
  std::string_view Kind;
548
  Node *Child;
549
public:
550
  ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
551
69
      : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
552
553
0
  template<typename Fn> void match(Fn F) const { F(Kind, Child); }
554
555
0
  void printLeft(OutputBuffer &OB) const override {
556
0
    OB += Kind;
557
0
    OB += ' ';
558
0
    Child->print(OB);
559
0
  }
560
};
561
562
class TransformedType : public Node {
563
  std::string_view Transform;
564
  Node *BaseType;
565
public:
566
  TransformedType(std::string_view Transform_, Node *BaseType_)
567
0
      : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
568
569
0
  template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
570
571
0
  void printLeft(OutputBuffer &OB) const override {
572
0
    OB += Transform;
573
0
    OB += '(';
574
0
    BaseType->print(OB);
575
0
    OB += ')';
576
0
  }
577
};
578
579
struct AbiTagAttr : Node {
580
  Node *Base;
581
  std::string_view Tag;
582
583
  AbiTagAttr(Node *Base_, std::string_view Tag_)
584
4
      : Node(KAbiTagAttr, Base_->getRHSComponentCache(), Base_->getArrayCache(),
585
4
             Base_->getFunctionCache()),
586
4
        Base(Base_), Tag(Tag_) {}
587
588
0
  template<typename Fn> void match(Fn F) const { F(Base, Tag); }
589
590
0
  std::string_view getBaseName() const override { return Base->getBaseName(); }
591
592
0
  void printLeft(OutputBuffer &OB) const override {
593
0
    OB.printLeft(*Base);
594
0
    OB += "[abi:";
595
0
    OB += Tag;
596
0
    OB += "]";
597
0
  }
598
};
599
600
class EnableIfAttr : public Node {
601
  NodeArray Conditions;
602
public:
603
  EnableIfAttr(NodeArray Conditions_)
604
0
      : Node(KEnableIfAttr), Conditions(Conditions_) {}
605
606
0
  template<typename Fn> void match(Fn F) const { F(Conditions); }
607
608
0
  void printLeft(OutputBuffer &OB) const override {
609
0
    OB += " [enable_if:";
610
0
    Conditions.printWithComma(OB);
611
0
    OB += ']';
612
0
  }
613
};
614
615
class ObjCProtoName : public Node {
616
  const Node *Ty;
617
  std::string_view Protocol;
618
619
public:
620
  ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
621
3
      : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
622
623
0
  template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
624
625
0
  bool isObjCObject() const {
626
0
    return Ty->getKind() == KNameType &&
627
0
           static_cast<const NameType *>(Ty)->getName() == "objc_object";
628
0
  }
629
630
0
  std::string_view getProtocol() const { return Protocol; }
631
632
0
  void printLeft(OutputBuffer &OB) const override {
633
0
    Ty->print(OB);
634
0
    OB += "<";
635
0
    OB += Protocol;
636
0
    OB += ">";
637
0
  }
638
};
639
640
class PointerType final : public Node {
641
  const Node *Pointee;
642
643
public:
644
  PointerType(const Node *Pointee_)
645
76.7k
      : Node(KPointerType, Pointee_->getRHSComponentCache()),
646
76.7k
        Pointee(Pointee_) {}
647
648
0
  const Node *getPointee() const { return Pointee; }
649
650
0
  template<typename Fn> void match(Fn F) const { F(Pointee); }
651
652
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
653
0
    return Pointee->hasRHSComponent(OB);
654
0
  }
655
656
1
  void printLeft(OutputBuffer &OB) const override {
657
    // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
658
1
    if (Pointee->getKind() != KObjCProtoName ||
659
1
        !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
660
1
      OB.printLeft(*Pointee);
661
1
      if (Pointee->hasArray(OB))
662
0
        OB += " ";
663
1
      if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
664
0
        OB += "(";
665
1
      OB += "*";
666
1
    } else {
667
0
      const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
668
0
      OB += "id<";
669
0
      OB += objcProto->getProtocol();
670
0
      OB += ">";
671
0
    }
672
1
  }
673
674
0
  void printRight(OutputBuffer &OB) const override {
675
0
    if (Pointee->getKind() != KObjCProtoName ||
676
0
        !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
677
0
      if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
678
0
        OB += ")";
679
0
      OB.printRight(*Pointee);
680
0
    }
681
0
  }
682
};
683
684
enum class ReferenceKind {
685
  LValue,
686
  RValue,
687
};
688
689
// Represents either a LValue or an RValue reference type.
690
class ReferenceType : public Node {
691
  const Node *Pointee;
692
  ReferenceKind RK;
693
694
  mutable bool Printing = false;
695
696
  // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
697
  // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
698
  // other combination collapses to a lvalue ref.
699
  //
700
  // A combination of a TemplateForwardReference and a back-ref Substitution
701
  // from an ill-formed string may have created a cycle; use cycle detection to
702
  // avoid looping forever.
703
0
  std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
704
0
    auto SoFar = std::make_pair(RK, Pointee);
705
    // Track the chain of nodes for the Floyd's 'tortoise and hare'
706
    // cycle-detection algorithm, since getSyntaxNode(S) is impure
707
0
    PODSmallVector<const Node *, 8> Prev;
708
0
    for (;;) {
709
0
      const Node *SN = SoFar.second->getSyntaxNode(OB);
710
0
      if (SN->getKind() != KReferenceType)
711
0
        break;
712
0
      auto *RT = static_cast<const ReferenceType *>(SN);
713
0
      SoFar.second = RT->Pointee;
714
0
      SoFar.first = std::min(SoFar.first, RT->RK);
715
716
      // The middle of Prev is the 'slow' pointer moving at half speed
717
0
      Prev.push_back(SoFar.second);
718
0
      if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
719
        // Cycle detected
720
0
        SoFar.second = nullptr;
721
0
        break;
722
0
      }
723
0
    }
724
0
    return SoFar;
725
0
  }
726
727
public:
728
  ReferenceType(const Node *Pointee_, ReferenceKind RK_)
729
75.9k
      : Node(KReferenceType, Pointee_->getRHSComponentCache()),
730
75.9k
        Pointee(Pointee_), RK(RK_) {}
731
732
0
  template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
733
734
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
735
0
    return Pointee->hasRHSComponent(OB);
736
0
  }
737
738
0
  void printLeft(OutputBuffer &OB) const override {
739
0
    if (Printing)
740
0
      return;
741
0
    ScopedOverride<bool> SavePrinting(Printing, true);
742
0
    std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
743
0
    if (!Collapsed.second)
744
0
      return;
745
0
    OB.printLeft(*Collapsed.second);
746
0
    if (Collapsed.second->hasArray(OB))
747
0
      OB += " ";
748
0
    if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
749
0
      OB += "(";
750
751
0
    OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
752
0
  }
753
0
  void printRight(OutputBuffer &OB) const override {
754
0
    if (Printing)
755
0
      return;
756
0
    ScopedOverride<bool> SavePrinting(Printing, true);
757
0
    std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
758
0
    if (!Collapsed.second)
759
0
      return;
760
0
    if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
761
0
      OB += ")";
762
0
    OB.printRight(*Collapsed.second);
763
0
  }
764
};
765
766
class PointerToMemberType final : public Node {
767
  const Node *ClassType;
768
  const Node *MemberType;
769
770
public:
771
  PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
772
3.00k
      : Node(KPointerToMemberType, MemberType_->getRHSComponentCache()),
773
3.00k
        ClassType(ClassType_), MemberType(MemberType_) {}
774
775
0
  template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
776
777
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
778
0
    return MemberType->hasRHSComponent(OB);
779
0
  }
780
781
20
  void printLeft(OutputBuffer &OB) const override {
782
20
    OB.printLeft(*MemberType);
783
20
    if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
784
0
      OB += "(";
785
20
    else
786
20
      OB += " ";
787
20
    ClassType->print(OB);
788
20
    OB += "::*";
789
20
  }
790
791
0
  void printRight(OutputBuffer &OB) const override {
792
0
    if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
793
0
      OB += ")";
794
0
    OB.printRight(*MemberType);
795
0
  }
796
};
797
798
class ArrayType final : public Node {
799
  const Node *Base;
800
  Node *Dimension;
801
802
public:
803
  ArrayType(const Node *Base_, Node *Dimension_)
804
7.38k
      : Node(KArrayType,
805
7.38k
             /*RHSComponentCache=*/Cache::Yes,
806
7.38k
             /*ArrayCache=*/Cache::Yes),
807
7.38k
        Base(Base_), Dimension(Dimension_) {}
808
809
0
  template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
810
811
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
812
0
  bool hasArraySlow(OutputBuffer &) const override { return true; }
813
814
0
  void printLeft(OutputBuffer &OB) const override { OB.printLeft(*Base); }
815
816
0
  void printRight(OutputBuffer &OB) const override {
817
0
    if (OB.back() != ']')
818
0
      OB += " ";
819
0
    OB += "[";
820
0
    if (Dimension)
821
0
      Dimension->print(OB);
822
0
    OB += "]";
823
0
    OB.printRight(*Base);
824
0
  }
825
826
  bool printInitListAsType(OutputBuffer &OB,
827
0
                           const NodeArray &Elements) const override {
828
0
    if (Base->getKind() == KNameType &&
829
0
        static_cast<const NameType *>(Base)->getName() == "char") {
830
0
      return Elements.printAsString(OB);
831
0
    }
832
0
    return false;
833
0
  }
834
};
835
836
class FunctionType final : public Node {
837
  const Node *Ret;
838
  NodeArray Params;
839
  Qualifiers CVQuals;
840
  FunctionRefQual RefQual;
841
  const Node *ExceptionSpec;
842
843
public:
844
  FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
845
               FunctionRefQual RefQual_, const Node *ExceptionSpec_)
846
26.9k
      : Node(KFunctionType,
847
26.9k
             /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
848
26.9k
             /*FunctionCache=*/Cache::Yes),
849
26.9k
        Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
850
26.9k
        ExceptionSpec(ExceptionSpec_) {}
851
852
0
  template<typename Fn> void match(Fn F) const {
853
0
    F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
854
0
  }
855
856
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
857
0
  bool hasFunctionSlow(OutputBuffer &) const override { return true; }
858
859
  // Handle C++'s ... quirky decl grammar by using the left & right
860
  // distinction. Consider:
861
  //   int (*f(float))(char) {}
862
  // f is a function that takes a float and returns a pointer to a function
863
  // that takes a char and returns an int. If we're trying to print f, start
864
  // by printing out the return types's left, then print our parameters, then
865
  // finally print right of the return type.
866
0
  void printLeft(OutputBuffer &OB) const override {
867
0
    OB.printLeft(*Ret);
868
0
    OB += " ";
869
0
  }
870
871
0
  void printRight(OutputBuffer &OB) const override {
872
0
    OB.printOpen();
873
0
    Params.printWithComma(OB);
874
0
    OB.printClose();
875
0
    OB.printRight(*Ret);
876
877
0
    if (CVQuals & QualConst)
878
0
      OB += " const";
879
0
    if (CVQuals & QualVolatile)
880
0
      OB += " volatile";
881
0
    if (CVQuals & QualRestrict)
882
0
      OB += " restrict";
883
884
0
    if (RefQual == FrefQualLValue)
885
0
      OB += " &";
886
0
    else if (RefQual == FrefQualRValue)
887
0
      OB += " &&";
888
889
0
    if (ExceptionSpec != nullptr) {
890
0
      OB += ' ';
891
0
      ExceptionSpec->print(OB);
892
0
    }
893
0
  }
894
};
895
896
class NoexceptSpec : public Node {
897
  const Node *E;
898
public:
899
107
  NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
900
901
0
  template<typename Fn> void match(Fn F) const { F(E); }
902
903
0
  void printLeft(OutputBuffer &OB) const override {
904
0
    OB += "noexcept";
905
0
    OB.printOpen();
906
0
    E->printAsOperand(OB);
907
0
    OB.printClose();
908
0
  }
909
};
910
911
class DynamicExceptionSpec : public Node {
912
  NodeArray Types;
913
public:
914
  DynamicExceptionSpec(NodeArray Types_)
915
0
      : Node(KDynamicExceptionSpec), Types(Types_) {}
916
917
0
  template<typename Fn> void match(Fn F) const { F(Types); }
918
919
0
  void printLeft(OutputBuffer &OB) const override {
920
0
    OB += "throw";
921
0
    OB.printOpen();
922
0
    Types.printWithComma(OB);
923
0
    OB.printClose();
924
0
  }
925
};
926
927
/// Represents the explicitly named object parameter.
928
/// E.g.,
929
/// \code{.cpp}
930
///   struct Foo {
931
///     void bar(this Foo && self);
932
///   };
933
/// \endcode
934
class ExplicitObjectParameter final : public Node {
935
  Node *Base;
936
937
public:
938
  ExplicitObjectParameter(Node *Base_)
939
0
      : Node(KExplicitObjectParameter), Base(Base_) {
940
0
    DEMANGLE_ASSERT(
941
0
        Base != nullptr,
942
0
        "Creating an ExplicitObjectParameter without a valid Base Node.");
943
0
  }
944
945
0
  template <typename Fn> void match(Fn F) const { F(Base); }
946
947
0
  void printLeft(OutputBuffer &OB) const override {
948
0
    OB += "this ";
949
0
    Base->print(OB);
950
0
  }
951
};
952
953
class FunctionEncoding final : public Node {
954
  const Node *Ret;
955
  const Node *Name;
956
  NodeArray Params;
957
  const Node *Attrs;
958
  const Node *Requires;
959
  Qualifiers CVQuals;
960
  FunctionRefQual RefQual;
961
962
public:
963
  FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
964
                   const Node *Attrs_, const Node *Requires_,
965
                   Qualifiers CVQuals_, FunctionRefQual RefQual_)
966
2.62k
      : Node(KFunctionEncoding,
967
2.62k
             /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
968
2.62k
             /*FunctionCache=*/Cache::Yes),
969
2.62k
        Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
970
2.62k
        Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
971
972
0
  template<typename Fn> void match(Fn F) const {
973
0
    F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
974
0
  }
975
976
0
  Qualifiers getCVQuals() const { return CVQuals; }
977
0
  FunctionRefQual getRefQual() const { return RefQual; }
978
0
  NodeArray getParams() const { return Params; }
979
0
  const Node *getReturnType() const { return Ret; }
980
0
  const Node *getAttrs() const { return Attrs; }
981
0
  const Node *getRequires() const { return Requires; }
982
983
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
984
0
  bool hasFunctionSlow(OutputBuffer &) const override { return true; }
985
986
0
  const Node *getName() const { return Name; }
987
988
1
  void printLeft(OutputBuffer &OB) const override {
989
1
    if (Ret) {
990
0
      OB.printLeft(*Ret);
991
0
      if (!Ret->hasRHSComponent(OB))
992
0
        OB += " ";
993
0
    }
994
995
1
    Name->print(OB);
996
1
  }
997
998
1
  void printRight(OutputBuffer &OB) const override {
999
1
    OB.printOpen();
1000
1
    Params.printWithComma(OB);
1001
1
    OB.printClose();
1002
1003
1
    if (Ret)
1004
0
      OB.printRight(*Ret);
1005
1006
1
    if (CVQuals & QualConst)
1007
0
      OB += " const";
1008
1
    if (CVQuals & QualVolatile)
1009
0
      OB += " volatile";
1010
1
    if (CVQuals & QualRestrict)
1011
0
      OB += " restrict";
1012
1013
1
    if (RefQual == FrefQualLValue)
1014
0
      OB += " &";
1015
1
    else if (RefQual == FrefQualRValue)
1016
0
      OB += " &&";
1017
1018
1
    if (Attrs != nullptr)
1019
0
      Attrs->print(OB);
1020
1021
1
    if (Requires != nullptr) {
1022
0
      OB += " requires ";
1023
0
      Requires->print(OB);
1024
0
    }
1025
1
  }
1026
};
1027
1028
class LiteralOperator : public Node {
1029
  const Node *OpName;
1030
1031
public:
1032
  LiteralOperator(const Node *OpName_)
1033
113
      : Node(KLiteralOperator), OpName(OpName_) {}
1034
1035
0
  template<typename Fn> void match(Fn F) const { F(OpName); }
1036
1037
0
  void printLeft(OutputBuffer &OB) const override {
1038
0
    OB += "operator\"\" ";
1039
0
    OpName->print(OB);
1040
0
  }
1041
};
1042
1043
class SpecialName final : public Node {
1044
  const std::string_view Special;
1045
  const Node *Child;
1046
1047
public:
1048
  SpecialName(std::string_view Special_, const Node *Child_)
1049
32
      : Node(KSpecialName), Special(Special_), Child(Child_) {}
1050
1051
0
  template<typename Fn> void match(Fn F) const { F(Special, Child); }
1052
1053
0
  void printLeft(OutputBuffer &OB) const override {
1054
0
    OB += Special;
1055
0
    Child->print(OB);
1056
0
  }
1057
};
1058
1059
class CtorVtableSpecialName final : public Node {
1060
  const Node *FirstType;
1061
  const Node *SecondType;
1062
1063
public:
1064
  CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1065
0
      : Node(KCtorVtableSpecialName),
1066
0
        FirstType(FirstType_), SecondType(SecondType_) {}
1067
1068
0
  template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1069
1070
0
  void printLeft(OutputBuffer &OB) const override {
1071
0
    OB += "construction vtable for ";
1072
0
    FirstType->print(OB);
1073
0
    OB += "-in-";
1074
0
    SecondType->print(OB);
1075
0
  }
1076
};
1077
1078
struct NestedName : Node {
1079
  Node *Qual;
1080
  Node *Name;
1081
1082
  NestedName(Node *Qual_, Node *Name_)
1083
4.01k
      : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1084
1085
0
  template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1086
1087
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1088
1089
0
  void printLeft(OutputBuffer &OB) const override {
1090
0
    Qual->print(OB);
1091
0
    OB += "::";
1092
0
    Name->print(OB);
1093
0
  }
1094
};
1095
1096
struct MemberLikeFriendName : Node {
1097
  Node *Qual;
1098
  Node *Name;
1099
1100
  MemberLikeFriendName(Node *Qual_, Node *Name_)
1101
0
      : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1102
1103
0
  template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1104
1105
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1106
1107
0
  void printLeft(OutputBuffer &OB) const override {
1108
0
    Qual->print(OB);
1109
0
    OB += "::friend ";
1110
0
    Name->print(OB);
1111
0
  }
1112
};
1113
1114
struct ModuleName : Node {
1115
  ModuleName *Parent;
1116
  Node *Name;
1117
  bool IsPartition;
1118
1119
  ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1120
3
      : Node(KModuleName), Parent(Parent_), Name(Name_),
1121
3
        IsPartition(IsPartition_) {}
1122
1123
0
  template <typename Fn> void match(Fn F) const {
1124
0
    F(Parent, Name, IsPartition);
1125
0
  }
1126
1127
0
  void printLeft(OutputBuffer &OB) const override {
1128
0
    if (Parent)
1129
0
      Parent->print(OB);
1130
0
    if (Parent || IsPartition)
1131
0
      OB += IsPartition ? ':' : '.';
1132
0
    Name->print(OB);
1133
0
  }
1134
};
1135
1136
struct ModuleEntity : Node {
1137
  ModuleName *Module;
1138
  Node *Name;
1139
1140
  ModuleEntity(ModuleName *Module_, Node *Name_)
1141
3
      : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1142
1143
0
  template <typename Fn> void match(Fn F) const { F(Module, Name); }
1144
1145
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1146
1147
0
  void printLeft(OutputBuffer &OB) const override {
1148
0
    Name->print(OB);
1149
0
    OB += '@';
1150
0
    Module->print(OB);
1151
0
  }
1152
};
1153
1154
struct LocalName : Node {
1155
  Node *Encoding;
1156
  Node *Entity;
1157
1158
  LocalName(Node *Encoding_, Node *Entity_)
1159
2.85k
      : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1160
1161
0
  template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1162
1163
0
  void printLeft(OutputBuffer &OB) const override {
1164
0
    Encoding->print(OB);
1165
0
    OB += "::";
1166
0
    Entity->print(OB);
1167
0
  }
1168
};
1169
1170
class QualifiedName final : public Node {
1171
  // qualifier::name
1172
  const Node *Qualifier;
1173
  const Node *Name;
1174
1175
public:
1176
  QualifiedName(const Node *Qualifier_, const Node *Name_)
1177
4.09k
      : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1178
1179
0
  template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1180
1181
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1182
1183
0
  void printLeft(OutputBuffer &OB) const override {
1184
0
    Qualifier->print(OB);
1185
0
    OB += "::";
1186
0
    Name->print(OB);
1187
0
  }
1188
};
1189
1190
class VectorType final : public Node {
1191
  const Node *BaseType;
1192
  const Node *Dimension;
1193
1194
public:
1195
  VectorType(const Node *BaseType_, const Node *Dimension_)
1196
40.7k
      : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1197
1198
0
  const Node *getBaseType() const { return BaseType; }
1199
0
  const Node *getDimension() const { return Dimension; }
1200
1201
0
  template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1202
1203
0
  void printLeft(OutputBuffer &OB) const override {
1204
0
    BaseType->print(OB);
1205
0
    OB += " vector[";
1206
0
    if (Dimension)
1207
0
      Dimension->print(OB);
1208
0
    OB += "]";
1209
0
  }
1210
};
1211
1212
class PixelVectorType final : public Node {
1213
  const Node *Dimension;
1214
1215
public:
1216
  PixelVectorType(const Node *Dimension_)
1217
24.0k
      : Node(KPixelVectorType), Dimension(Dimension_) {}
1218
1219
0
  template<typename Fn> void match(Fn F) const { F(Dimension); }
1220
1221
0
  void printLeft(OutputBuffer &OB) const override {
1222
    // FIXME: This should demangle as "vector pixel".
1223
0
    OB += "pixel vector[";
1224
0
    Dimension->print(OB);
1225
0
    OB += "]";
1226
0
  }
1227
};
1228
1229
class BinaryFPType final : public Node {
1230
  const Node *Dimension;
1231
1232
public:
1233
  BinaryFPType(const Node *Dimension_)
1234
1.61k
      : Node(KBinaryFPType), Dimension(Dimension_) {}
1235
1236
0
  template<typename Fn> void match(Fn F) const { F(Dimension); }
1237
1238
0
  void printLeft(OutputBuffer &OB) const override {
1239
0
    OB += "_Float";
1240
0
    Dimension->print(OB);
1241
0
  }
1242
};
1243
1244
enum class TemplateParamKind { Type, NonType, Template };
1245
1246
/// An invented name for a template parameter for which we don't have a
1247
/// corresponding template argument.
1248
///
1249
/// This node is created when parsing the <lambda-sig> for a lambda with
1250
/// explicit template arguments, which might be referenced in the parameter
1251
/// types appearing later in the <lambda-sig>.
1252
class SyntheticTemplateParamName final : public Node {
1253
  TemplateParamKind Kind;
1254
  unsigned Index;
1255
1256
public:
1257
  SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1258
21.8k
      : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1259
1260
0
  template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1261
1262
0
  void printLeft(OutputBuffer &OB) const override {
1263
0
    switch (Kind) {
1264
0
    case TemplateParamKind::Type:
1265
0
      OB += "$T";
1266
0
      break;
1267
0
    case TemplateParamKind::NonType:
1268
0
      OB += "$N";
1269
0
      break;
1270
0
    case TemplateParamKind::Template:
1271
0
      OB += "$TT";
1272
0
      break;
1273
0
    }
1274
0
    if (Index > 0)
1275
0
      OB << Index - 1;
1276
0
  }
1277
};
1278
1279
class TemplateParamQualifiedArg final : public Node {
1280
  Node *Param;
1281
  Node *Arg;
1282
1283
public:
1284
  TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1285
1
      : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1286
1287
0
  template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1288
1289
0
  Node *getArg() { return Arg; }
1290
1291
0
  void printLeft(OutputBuffer &OB) const override {
1292
    // Don't print Param to keep the output consistent.
1293
0
    Arg->print(OB);
1294
0
  }
1295
};
1296
1297
/// A template type parameter declaration, 'typename T'.
1298
class TypeTemplateParamDecl final : public Node {
1299
  Node *Name;
1300
1301
public:
1302
  TypeTemplateParamDecl(Node *Name_)
1303
12.7k
      : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1304
1305
0
  template<typename Fn> void match(Fn F) const { F(Name); }
1306
1307
0
  void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1308
1309
0
  void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1310
};
1311
1312
/// A constrained template type parameter declaration, 'C<U> T'.
1313
class ConstrainedTypeTemplateParamDecl final : public Node {
1314
  Node *Constraint;
1315
  Node *Name;
1316
1317
public:
1318
  ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1319
0
      : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1320
0
        Constraint(Constraint_), Name(Name_) {}
1321
1322
0
  template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1323
1324
0
  void printLeft(OutputBuffer &OB) const override {
1325
0
    Constraint->print(OB);
1326
0
    OB += " ";
1327
0
  }
1328
1329
0
  void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1330
};
1331
1332
/// A non-type template parameter declaration, 'int N'.
1333
class NonTypeTemplateParamDecl final : public Node {
1334
  Node *Name;
1335
  Node *Type;
1336
1337
public:
1338
  NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1339
264
      : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1340
1341
0
  template<typename Fn> void match(Fn F) const { F(Name, Type); }
1342
1343
0
  void printLeft(OutputBuffer &OB) const override {
1344
0
    OB.printLeft(*Type);
1345
0
    if (!Type->hasRHSComponent(OB))
1346
0
      OB += " ";
1347
0
  }
1348
1349
0
  void printRight(OutputBuffer &OB) const override {
1350
0
    Name->print(OB);
1351
0
    OB.printRight(*Type);
1352
0
  }
1353
};
1354
1355
/// A template template parameter declaration,
1356
/// 'template<typename T> typename N'.
1357
class TemplateTemplateParamDecl final : public Node {
1358
  Node *Name;
1359
  NodeArray Params;
1360
  Node *Requires;
1361
1362
public:
1363
  TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1364
8.82k
      : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1365
8.82k
        Params(Params_), Requires(Requires_) {}
1366
1367
0
  template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1368
1369
0
  void printLeft(OutputBuffer &OB) const override {
1370
0
    ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1371
0
    OB += "template<";
1372
0
    Params.printWithComma(OB);
1373
0
    OB += "> typename ";
1374
0
  }
1375
1376
0
  void printRight(OutputBuffer &OB) const override {
1377
0
    Name->print(OB);
1378
0
    if (Requires != nullptr) {
1379
0
      OB += " requires ";
1380
0
      Requires->print(OB);
1381
0
    }
1382
0
  }
1383
};
1384
1385
/// A template parameter pack declaration, 'typename ...T'.
1386
class TemplateParamPackDecl final : public Node {
1387
  Node *Param;
1388
1389
public:
1390
  TemplateParamPackDecl(Node *Param_)
1391
229
      : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1392
1393
0
  template<typename Fn> void match(Fn F) const { F(Param); }
1394
1395
0
  void printLeft(OutputBuffer &OB) const override {
1396
0
    OB.printLeft(*Param);
1397
0
    OB += "...";
1398
0
  }
1399
1400
0
  void printRight(OutputBuffer &OB) const override { OB.printRight(*Param); }
1401
};
1402
1403
/// An unexpanded parameter pack (either in the expression or type context). If
1404
/// this AST is correct, this node will have a ParameterPackExpansion node above
1405
/// it.
1406
///
1407
/// This node is created when some <template-args> are found that apply to an
1408
/// <encoding>, and is stored in the TemplateParams table. In order for this to
1409
/// appear in the final AST, it has to referenced via a <template-param> (ie,
1410
/// T_).
1411
class ParameterPack final : public Node {
1412
  NodeArray Data;
1413
1414
  // Setup OutputBuffer for a pack expansion, unless we're already expanding
1415
  // one.
1416
0
  void initializePackExpansion(OutputBuffer &OB) const {
1417
0
    if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1418
0
      OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1419
0
      OB.CurrentPackIndex = 0;
1420
0
    }
1421
0
  }
1422
1423
public:
1424
1.37k
  ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1425
1.37k
    ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1426
1.37k
    if (std::all_of(Data.begin(), Data.end(),
1427
52.9k
                    [](Node *P) { return P->getArrayCache() == Cache::No; }))
1428
1.37k
      ArrayCache = Cache::No;
1429
1.37k
    if (std::all_of(Data.begin(), Data.end(),
1430
52.9k
                    [](Node *P) { return P->getFunctionCache() == Cache::No; }))
1431
1.31k
      FunctionCache = Cache::No;
1432
52.9k
    if (std::all_of(Data.begin(), Data.end(), [](Node *P) {
1433
52.9k
          return P->getRHSComponentCache() == Cache::No;
1434
52.9k
        }))
1435
1.31k
      RHSComponentCache = Cache::No;
1436
1.37k
  }
1437
1438
0
  template<typename Fn> void match(Fn F) const { F(Data); }
1439
1440
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1441
0
    initializePackExpansion(OB);
1442
0
    size_t Idx = OB.CurrentPackIndex;
1443
0
    return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1444
0
  }
1445
0
  bool hasArraySlow(OutputBuffer &OB) const override {
1446
0
    initializePackExpansion(OB);
1447
0
    size_t Idx = OB.CurrentPackIndex;
1448
0
    return Idx < Data.size() && Data[Idx]->hasArray(OB);
1449
0
  }
1450
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
1451
0
    initializePackExpansion(OB);
1452
0
    size_t Idx = OB.CurrentPackIndex;
1453
0
    return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1454
0
  }
1455
0
  const Node *getSyntaxNode(OutputBuffer &OB) const override {
1456
0
    initializePackExpansion(OB);
1457
0
    size_t Idx = OB.CurrentPackIndex;
1458
0
    return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1459
0
  }
1460
1461
0
  void printLeft(OutputBuffer &OB) const override {
1462
0
    initializePackExpansion(OB);
1463
0
    size_t Idx = OB.CurrentPackIndex;
1464
0
    if (Idx < Data.size())
1465
0
      OB.printLeft(*Data[Idx]);
1466
0
  }
1467
0
  void printRight(OutputBuffer &OB) const override {
1468
0
    initializePackExpansion(OB);
1469
0
    size_t Idx = OB.CurrentPackIndex;
1470
0
    if (Idx < Data.size())
1471
0
      OB.printRight(*Data[Idx]);
1472
0
  }
1473
};
1474
1475
/// A variadic template argument. This node represents an occurrence of
1476
/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1477
/// one of its Elements is. The parser inserts a ParameterPack into the
1478
/// TemplateParams table if the <template-args> this pack belongs to apply to an
1479
/// <encoding>.
1480
class TemplateArgumentPack final : public Node {
1481
  NodeArray Elements;
1482
public:
1483
  TemplateArgumentPack(NodeArray Elements_)
1484
15.6k
      : Node(KTemplateArgumentPack), Elements(Elements_) {}
1485
1486
0
  template<typename Fn> void match(Fn F) const { F(Elements); }
1487
1488
1.37k
  NodeArray getElements() const { return Elements; }
1489
1490
0
  void printLeft(OutputBuffer &OB) const override {
1491
0
    Elements.printWithComma(OB);
1492
0
  }
1493
};
1494
1495
/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1496
/// which each have Child->ParameterPackSize elements.
1497
class ParameterPackExpansion final : public Node {
1498
  const Node *Child;
1499
1500
public:
1501
  ParameterPackExpansion(const Node *Child_)
1502
14.9k
      : Node(KParameterPackExpansion), Child(Child_) {}
1503
1504
0
  template<typename Fn> void match(Fn F) const { F(Child); }
1505
1506
0
  const Node *getChild() const { return Child; }
1507
1508
0
  void printLeft(OutputBuffer &OB) const override {
1509
0
    constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1510
0
    ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1511
0
    ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1512
0
    size_t StreamPos = OB.getCurrentPosition();
1513
1514
    // Print the first element in the pack. If Child contains a ParameterPack,
1515
    // it will set up S.CurrentPackMax and print the first element.
1516
0
    Child->print(OB);
1517
1518
    // No ParameterPack was found in Child. This can occur if we've found a pack
1519
    // expansion on a <function-param>.
1520
0
    if (OB.CurrentPackMax == Max) {
1521
0
      OB += "...";
1522
0
      return;
1523
0
    }
1524
1525
    // We found a ParameterPack, but it has no elements. Erase whatever we may
1526
    // of printed.
1527
0
    if (OB.CurrentPackMax == 0) {
1528
0
      OB.setCurrentPosition(StreamPos);
1529
0
      return;
1530
0
    }
1531
1532
    // Else, iterate through the rest of the elements in the pack.
1533
0
    for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1534
0
      OB += ", ";
1535
0
      OB.CurrentPackIndex = I;
1536
0
      Child->print(OB);
1537
0
    }
1538
0
  }
1539
};
1540
1541
class PackIndexing final : public Node {
1542
  const Node *Pattern;
1543
  const Node *Index;
1544
1545
public:
1546
  PackIndexing(const Node *Pattern_, const Node *Index_)
1547
0
      : Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {}
1548
1549
0
  template <typename Fn> void match(Fn F) const { F(Pattern, Index); }
1550
1551
0
  void printLeft(OutputBuffer &OB) const override {
1552
0
    OB.printOpen('(');
1553
0
    ParameterPackExpansion PPE(Pattern);
1554
0
    PPE.printLeft(OB);
1555
0
    OB.printClose(')');
1556
0
    OB.printOpen('[');
1557
0
    OB.printLeft(*Index);
1558
0
    OB.printClose(']');
1559
0
  }
1560
};
1561
1562
class TemplateArgs final : public Node {
1563
  NodeArray Params;
1564
  Node *Requires;
1565
1566
public:
1567
  TemplateArgs(NodeArray Params_, Node *Requires_)
1568
14.9k
      : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1569
1570
0
  template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1571
1572
0
  NodeArray getParams() { return Params; }
1573
1574
0
  void printLeft(OutputBuffer &OB) const override {
1575
0
    ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1576
0
    OB += "<";
1577
0
    Params.printWithComma(OB);
1578
0
    OB += ">";
1579
    // Don't print the requires clause to keep the output simple.
1580
0
  }
1581
};
1582
1583
/// A forward-reference to a template argument that was not known at the point
1584
/// where the template parameter name was parsed in a mangling.
1585
///
1586
/// This is created when demangling the name of a specialization of a
1587
/// conversion function template:
1588
///
1589
/// \code
1590
/// struct A {
1591
///   template<typename T> operator T*();
1592
/// };
1593
/// \endcode
1594
///
1595
/// When demangling a specialization of the conversion function template, we
1596
/// encounter the name of the template (including the \c T) before we reach
1597
/// the template argument list, so we cannot substitute the parameter name
1598
/// for the corresponding argument while parsing. Instead, we create a
1599
/// \c ForwardTemplateReference node that is resolved after we parse the
1600
/// template arguments.
1601
struct ForwardTemplateReference : Node {
1602
  size_t Index;
1603
  Node *Ref = nullptr;
1604
1605
  // If we're currently printing this node. It is possible (though invalid) for
1606
  // a forward template reference to refer to itself via a substitution. This
1607
  // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1608
  // out if more than one print* function is active.
1609
  mutable bool Printing = false;
1610
1611
  ForwardTemplateReference(size_t Index_)
1612
2
      : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1613
2
             Cache::Unknown),
1614
2
        Index(Index_) {}
1615
1616
  // We don't provide a matcher for these, because the value of the node is
1617
  // not determined by its construction parameters, and it generally needs
1618
  // special handling.
1619
  template<typename Fn> void match(Fn F) const = delete;
1620
1621
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1622
0
    if (Printing)
1623
0
      return false;
1624
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1625
0
    return Ref->hasRHSComponent(OB);
1626
0
  }
1627
0
  bool hasArraySlow(OutputBuffer &OB) const override {
1628
0
    if (Printing)
1629
0
      return false;
1630
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1631
0
    return Ref->hasArray(OB);
1632
0
  }
1633
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
1634
0
    if (Printing)
1635
0
      return false;
1636
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1637
0
    return Ref->hasFunction(OB);
1638
0
  }
1639
0
  const Node *getSyntaxNode(OutputBuffer &OB) const override {
1640
0
    if (Printing)
1641
0
      return this;
1642
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1643
0
    return Ref->getSyntaxNode(OB);
1644
0
  }
1645
1646
0
  void printLeft(OutputBuffer &OB) const override {
1647
0
    if (Printing)
1648
0
      return;
1649
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1650
0
    OB.printLeft(*Ref);
1651
0
  }
1652
0
  void printRight(OutputBuffer &OB) const override {
1653
0
    if (Printing)
1654
0
      return;
1655
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1656
0
    OB.printRight(*Ref);
1657
0
  }
1658
};
1659
1660
struct NameWithTemplateArgs : Node {
1661
  // name<template_args>
1662
  Node *Name;
1663
  Node *TemplateArgs;
1664
1665
  NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1666
14.9k
      : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1667
1668
0
  template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1669
1670
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1671
1672
0
  void printLeft(OutputBuffer &OB) const override {
1673
0
    Name->print(OB);
1674
0
    TemplateArgs->print(OB);
1675
0
  }
1676
};
1677
1678
class GlobalQualifiedName final : public Node {
1679
  Node *Child;
1680
1681
public:
1682
  GlobalQualifiedName(Node* Child_)
1683
907
      : Node(KGlobalQualifiedName), Child(Child_) {}
1684
1685
0
  template<typename Fn> void match(Fn F) const { F(Child); }
1686
1687
0
  std::string_view getBaseName() const override { return Child->getBaseName(); }
1688
1689
0
  void printLeft(OutputBuffer &OB) const override {
1690
0
    OB += "::";
1691
0
    Child->print(OB);
1692
0
  }
1693
};
1694
1695
enum class SpecialSubKind {
1696
  allocator,
1697
  basic_string,
1698
  string,
1699
  istream,
1700
  ostream,
1701
  iostream,
1702
};
1703
1704
class SpecialSubstitution;
1705
class ExpandedSpecialSubstitution : public Node {
1706
protected:
1707
  SpecialSubKind SSK;
1708
1709
  ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1710
13.1k
      : Node(K_), SSK(SSK_) {}
1711
public:
1712
  ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1713
0
      : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1714
  inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1715
1716
0
  template<typename Fn> void match(Fn F) const { F(SSK); }
1717
1718
protected:
1719
0
  bool isInstantiation() const {
1720
0
    return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1721
0
  }
1722
1723
0
  std::string_view getBaseName() const override {
1724
0
    switch (SSK) {
1725
0
    case SpecialSubKind::allocator:
1726
0
      return {"allocator"};
1727
0
    case SpecialSubKind::basic_string:
1728
0
      return {"basic_string"};
1729
0
    case SpecialSubKind::string:
1730
0
      return {"basic_string"};
1731
0
    case SpecialSubKind::istream:
1732
0
      return {"basic_istream"};
1733
0
    case SpecialSubKind::ostream:
1734
0
      return {"basic_ostream"};
1735
0
    case SpecialSubKind::iostream:
1736
0
      return {"basic_iostream"};
1737
0
    }
1738
0
    DEMANGLE_UNREACHABLE;
1739
0
  }
1740
1741
private:
1742
0
  void printLeft(OutputBuffer &OB) const override {
1743
0
    OB << "std::" << getBaseName();
1744
0
    if (isInstantiation()) {
1745
0
      OB << "<char, std::char_traits<char>";
1746
0
      if (SSK == SpecialSubKind::string)
1747
0
        OB << ", std::allocator<char>";
1748
0
      OB << ">";
1749
0
    }
1750
0
  }
1751
};
1752
1753
class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1754
public:
1755
  SpecialSubstitution(SpecialSubKind SSK_)
1756
13.1k
      : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1757
1758
0
  template<typename Fn> void match(Fn F) const { F(SSK); }
1759
1760
0
  std::string_view getBaseName() const override {
1761
0
    std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1762
0
    if (isInstantiation()) {
1763
      // The instantiations are typedefs that drop the "basic_" prefix.
1764
0
      DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1765
0
      SV.remove_prefix(sizeof("basic_") - 1);
1766
0
    }
1767
0
    return SV;
1768
0
  }
1769
1770
0
  void printLeft(OutputBuffer &OB) const override {
1771
0
    OB << "std::" << getBaseName();
1772
0
  }
1773
};
1774
1775
inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1776
    SpecialSubstitution const *SS)
1777
0
    : ExpandedSpecialSubstitution(SS->SSK) {}
1778
1779
class CtorDtorName final : public Node {
1780
  const Node *Basename;
1781
  const bool IsDtor;
1782
  const int Variant;
1783
1784
public:
1785
  CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1786
0
      : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1787
0
        Variant(Variant_) {}
1788
1789
0
  template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1790
1791
0
  void printLeft(OutputBuffer &OB) const override {
1792
0
    if (IsDtor)
1793
0
      OB += "~";
1794
0
    OB += Basename->getBaseName();
1795
0
  }
1796
};
1797
1798
class DtorName : public Node {
1799
  const Node *Base;
1800
1801
public:
1802
4
  DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1803
1804
0
  template<typename Fn> void match(Fn F) const { F(Base); }
1805
1806
0
  void printLeft(OutputBuffer &OB) const override {
1807
0
    OB += "~";
1808
0
    OB.printLeft(*Base);
1809
0
  }
1810
};
1811
1812
class UnnamedTypeName : public Node {
1813
  const std::string_view Count;
1814
1815
public:
1816
  UnnamedTypeName(std::string_view Count_)
1817
44
      : Node(KUnnamedTypeName), Count(Count_) {}
1818
1819
0
  template<typename Fn> void match(Fn F) const { F(Count); }
1820
1821
0
  void printLeft(OutputBuffer &OB) const override {
1822
0
    OB += "'unnamed";
1823
0
    OB += Count;
1824
0
    OB += "\'";
1825
0
  }
1826
};
1827
1828
class ClosureTypeName : public Node {
1829
  NodeArray TemplateParams;
1830
  const Node *Requires1;
1831
  NodeArray Params;
1832
  const Node *Requires2;
1833
  std::string_view Count;
1834
1835
public:
1836
  ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1837
                  NodeArray Params_, const Node *Requires2_,
1838
                  std::string_view Count_)
1839
1.47k
      : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1840
1.47k
        Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1841
1.47k
        Count(Count_) {}
1842
1843
0
  template<typename Fn> void match(Fn F) const {
1844
0
    F(TemplateParams, Requires1, Params, Requires2, Count);
1845
0
  }
1846
1847
0
  void printDeclarator(OutputBuffer &OB) const {
1848
0
    if (!TemplateParams.empty()) {
1849
0
      ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
1850
0
      OB += "<";
1851
0
      TemplateParams.printWithComma(OB);
1852
0
      OB += ">";
1853
0
    }
1854
0
    if (Requires1 != nullptr) {
1855
0
      OB += " requires ";
1856
0
      Requires1->print(OB);
1857
0
      OB += " ";
1858
0
    }
1859
0
    OB.printOpen();
1860
0
    Params.printWithComma(OB);
1861
0
    OB.printClose();
1862
0
    if (Requires2 != nullptr) {
1863
0
      OB += " requires ";
1864
0
      Requires2->print(OB);
1865
0
    }
1866
0
  }
1867
1868
0
  void printLeft(OutputBuffer &OB) const override {
1869
    // FIXME: This demangling is not particularly readable.
1870
0
    OB += "\'lambda";
1871
0
    OB += Count;
1872
0
    OB += "\'";
1873
0
    printDeclarator(OB);
1874
0
  }
1875
};
1876
1877
class StructuredBindingName : public Node {
1878
  NodeArray Bindings;
1879
public:
1880
  StructuredBindingName(NodeArray Bindings_)
1881
0
      : Node(KStructuredBindingName), Bindings(Bindings_) {}
1882
1883
0
  template<typename Fn> void match(Fn F) const { F(Bindings); }
1884
1885
0
  void printLeft(OutputBuffer &OB) const override {
1886
0
    OB.printOpen('[');
1887
0
    Bindings.printWithComma(OB);
1888
0
    OB.printClose(']');
1889
0
  }
1890
};
1891
1892
// -- Expression Nodes --
1893
1894
class BinaryExpr : public Node {
1895
  const Node *LHS;
1896
  const std::string_view InfixOperator;
1897
  const Node *RHS;
1898
1899
public:
1900
  BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1901
             const Node *RHS_, Prec Prec_)
1902
0
      : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1903
0
        RHS(RHS_) {}
1904
1905
0
  template <typename Fn> void match(Fn F) const {
1906
0
    F(LHS, InfixOperator, RHS, getPrecedence());
1907
0
  }
1908
1909
0
  void printLeft(OutputBuffer &OB) const override {
1910
    // If we're printing a '<' inside of a template argument, and we haven't
1911
    // yet parenthesized the expression, do so now.
1912
0
    bool ParenAll = !OB.isInParensInTemplateArgs() &&
1913
0
                    (InfixOperator == ">" || InfixOperator == ">>");
1914
0
    if (ParenAll)
1915
0
      OB.printOpen();
1916
    // Assignment is right associative, with special LHS precedence.
1917
0
    bool IsAssign = getPrecedence() == Prec::Assign;
1918
0
    LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1919
    // No space before comma operator
1920
0
    if (!(InfixOperator == ","))
1921
0
      OB += " ";
1922
0
    OB += InfixOperator;
1923
0
    OB += " ";
1924
0
    RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1925
0
    if (ParenAll)
1926
0
      OB.printClose();
1927
0
  }
1928
};
1929
1930
class ArraySubscriptExpr : public Node {
1931
  const Node *Op1;
1932
  const Node *Op2;
1933
1934
public:
1935
  ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1936
0
      : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1937
1938
0
  template <typename Fn> void match(Fn F) const {
1939
0
    F(Op1, Op2, getPrecedence());
1940
0
  }
1941
1942
0
  void printLeft(OutputBuffer &OB) const override {
1943
0
    Op1->printAsOperand(OB, getPrecedence());
1944
0
    OB.printOpen('[');
1945
0
    Op2->printAsOperand(OB);
1946
0
    OB.printClose(']');
1947
0
  }
1948
};
1949
1950
class PostfixExpr : public Node {
1951
  const Node *Child;
1952
  const std::string_view Operator;
1953
1954
public:
1955
  PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1956
0
      : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1957
1958
0
  template <typename Fn> void match(Fn F) const {
1959
0
    F(Child, Operator, getPrecedence());
1960
0
  }
1961
1962
0
  void printLeft(OutputBuffer &OB) const override {
1963
0
    Child->printAsOperand(OB, getPrecedence(), true);
1964
0
    OB += Operator;
1965
0
  }
1966
};
1967
1968
class ConditionalExpr : public Node {
1969
  const Node *Cond;
1970
  const Node *Then;
1971
  const Node *Else;
1972
1973
public:
1974
  ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1975
                  Prec Prec_)
1976
0
      : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1977
1978
0
  template <typename Fn> void match(Fn F) const {
1979
0
    F(Cond, Then, Else, getPrecedence());
1980
0
  }
1981
1982
0
  void printLeft(OutputBuffer &OB) const override {
1983
0
    Cond->printAsOperand(OB, getPrecedence());
1984
0
    OB += " ? ";
1985
0
    Then->printAsOperand(OB);
1986
0
    OB += " : ";
1987
0
    Else->printAsOperand(OB, Prec::Assign, true);
1988
0
  }
1989
};
1990
1991
class MemberExpr : public Node {
1992
  const Node *LHS;
1993
  const std::string_view Kind;
1994
  const Node *RHS;
1995
1996
public:
1997
  MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1998
             Prec Prec_)
1999
0
      : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
2000
2001
0
  template <typename Fn> void match(Fn F) const {
2002
0
    F(LHS, Kind, RHS, getPrecedence());
2003
0
  }
2004
2005
0
  void printLeft(OutputBuffer &OB) const override {
2006
0
    LHS->printAsOperand(OB, getPrecedence(), true);
2007
0
    OB += Kind;
2008
0
    RHS->printAsOperand(OB, getPrecedence(), false);
2009
0
  }
2010
};
2011
2012
class SubobjectExpr : public Node {
2013
  const Node *Type;
2014
  const Node *SubExpr;
2015
  std::string_view Offset;
2016
  NodeArray UnionSelectors;
2017
  bool OnePastTheEnd;
2018
2019
public:
2020
  SubobjectExpr(const Node *Type_, const Node *SubExpr_,
2021
                std::string_view Offset_, NodeArray UnionSelectors_,
2022
                bool OnePastTheEnd_)
2023
4
      : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
2024
4
        UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
2025
2026
0
  template<typename Fn> void match(Fn F) const {
2027
0
    F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
2028
0
  }
2029
2030
0
  void printLeft(OutputBuffer &OB) const override {
2031
0
    SubExpr->print(OB);
2032
0
    OB += ".<";
2033
0
    Type->print(OB);
2034
0
    OB += " at offset ";
2035
0
    if (Offset.empty()) {
2036
0
      OB += "0";
2037
0
    } else if (Offset[0] == 'n') {
2038
0
      OB += "-";
2039
0
      OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
2040
0
    } else {
2041
0
      OB += Offset;
2042
0
    }
2043
0
    OB += ">";
2044
0
  }
2045
};
2046
2047
class EnclosingExpr : public Node {
2048
  const std::string_view Prefix;
2049
  const Node *Infix;
2050
  const std::string_view Postfix;
2051
2052
public:
2053
  EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
2054
                Prec Prec_ = Prec::Primary)
2055
25.4k
      : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
2056
2057
0
  template <typename Fn> void match(Fn F) const {
2058
0
    F(Prefix, Infix, getPrecedence());
2059
0
  }
2060
2061
0
  void printLeft(OutputBuffer &OB) const override {
2062
0
    OB += Prefix;
2063
0
    OB.printOpen();
2064
0
    Infix->print(OB);
2065
0
    OB.printClose();
2066
0
    OB += Postfix;
2067
0
  }
2068
};
2069
2070
class CastExpr : public Node {
2071
  // cast_kind<to>(from)
2072
  const std::string_view CastKind;
2073
  const Node *To;
2074
  const Node *From;
2075
2076
public:
2077
  CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2078
           Prec Prec_)
2079
0
      : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2080
2081
0
  template <typename Fn> void match(Fn F) const {
2082
0
    F(CastKind, To, From, getPrecedence());
2083
0
  }
2084
2085
0
  void printLeft(OutputBuffer &OB) const override {
2086
0
    OB += CastKind;
2087
0
    {
2088
0
      ScopedOverride<bool> LT(OB.TemplateTracker.InsideTemplate, true);
2089
0
      OB += "<";
2090
0
      OB.printLeft(*To);
2091
0
      OB += ">";
2092
0
    }
2093
0
    OB.printOpen();
2094
0
    From->printAsOperand(OB);
2095
0
    OB.printClose();
2096
0
  }
2097
};
2098
2099
class SizeofParamPackExpr : public Node {
2100
  const Node *Pack;
2101
2102
public:
2103
  SizeofParamPackExpr(const Node *Pack_)
2104
0
      : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2105
2106
0
  template<typename Fn> void match(Fn F) const { F(Pack); }
2107
2108
0
  void printLeft(OutputBuffer &OB) const override {
2109
0
    OB += "sizeof...";
2110
0
    OB.printOpen();
2111
0
    ParameterPackExpansion PPE(Pack);
2112
0
    PPE.printLeft(OB);
2113
0
    OB.printClose();
2114
0
  }
2115
};
2116
2117
class CallExpr : public Node {
2118
  const Node *Callee;
2119
  NodeArray Args;
2120
  bool IsParen; // (func)(args ...) ?
2121
2122
public:
2123
  CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2124
200
      : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2125
200
        IsParen(IsParen_) {}
2126
2127
0
  template <typename Fn> void match(Fn F) const {
2128
0
    F(Callee, Args, IsParen, getPrecedence());
2129
0
  }
2130
2131
0
  void printLeft(OutputBuffer &OB) const override {
2132
0
    if (IsParen)
2133
0
      OB.printOpen();
2134
0
    Callee->print(OB);
2135
0
    if (IsParen)
2136
0
      OB.printClose();
2137
0
    OB.printOpen();
2138
0
    Args.printWithComma(OB);
2139
0
    OB.printClose();
2140
0
  }
2141
};
2142
2143
class NewExpr : public Node {
2144
  // new (expr_list) type(init_list)
2145
  NodeArray ExprList;
2146
  Node *Type;
2147
  NodeArray InitList;
2148
  bool IsGlobal; // ::operator new ?
2149
  bool IsArray;  // new[] ?
2150
public:
2151
  NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2152
          bool IsArray_, Prec Prec_)
2153
4
      : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2154
4
        InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2155
2156
0
  template<typename Fn> void match(Fn F) const {
2157
0
    F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2158
0
  }
2159
2160
0
  void printLeft(OutputBuffer &OB) const override {
2161
0
    if (IsGlobal)
2162
0
      OB += "::";
2163
0
    OB += "new";
2164
0
    if (IsArray)
2165
0
      OB += "[]";
2166
0
    if (!ExprList.empty()) {
2167
0
      OB.printOpen();
2168
0
      ExprList.printWithComma(OB);
2169
0
      OB.printClose();
2170
0
    }
2171
0
    OB += " ";
2172
0
    Type->print(OB);
2173
0
    if (!InitList.empty()) {
2174
0
      OB.printOpen();
2175
0
      InitList.printWithComma(OB);
2176
0
      OB.printClose();
2177
0
    }
2178
0
  }
2179
};
2180
2181
class DeleteExpr : public Node {
2182
  Node *Op;
2183
  bool IsGlobal;
2184
  bool IsArray;
2185
2186
public:
2187
  DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2188
14.7k
      : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2189
14.7k
        IsArray(IsArray_) {}
2190
2191
0
  template <typename Fn> void match(Fn F) const {
2192
0
    F(Op, IsGlobal, IsArray, getPrecedence());
2193
0
  }
2194
2195
0
  void printLeft(OutputBuffer &OB) const override {
2196
0
    if (IsGlobal)
2197
0
      OB += "::";
2198
0
    OB += "delete";
2199
0
    if (IsArray)
2200
0
      OB += "[]";
2201
0
    OB += ' ';
2202
0
    Op->print(OB);
2203
0
  }
2204
};
2205
2206
class PrefixExpr : public Node {
2207
  std::string_view Prefix;
2208
  Node *Child;
2209
2210
public:
2211
  PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2212
10.4k
      : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2213
2214
0
  template <typename Fn> void match(Fn F) const {
2215
0
    F(Prefix, Child, getPrecedence());
2216
0
  }
2217
2218
0
  void printLeft(OutputBuffer &OB) const override {
2219
0
    OB += Prefix;
2220
0
    Child->printAsOperand(OB, getPrecedence());
2221
0
  }
2222
};
2223
2224
class FunctionParam : public Node {
2225
  std::string_view Number;
2226
2227
public:
2228
  FunctionParam(std::string_view Number_)
2229
3
      : Node(KFunctionParam), Number(Number_) {}
2230
2231
0
  template<typename Fn> void match(Fn F) const { F(Number); }
2232
2233
0
  void printLeft(OutputBuffer &OB) const override {
2234
0
    OB += "fp";
2235
0
    OB += Number;
2236
0
  }
2237
};
2238
2239
class ConversionExpr : public Node {
2240
  const Node *Type;
2241
  NodeArray Expressions;
2242
2243
public:
2244
  ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2245
0
      : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2246
2247
0
  template <typename Fn> void match(Fn F) const {
2248
0
    F(Type, Expressions, getPrecedence());
2249
0
  }
2250
2251
0
  void printLeft(OutputBuffer &OB) const override {
2252
0
    OB.printOpen();
2253
0
    Type->print(OB);
2254
0
    OB.printClose();
2255
0
    OB.printOpen();
2256
0
    Expressions.printWithComma(OB);
2257
0
    OB.printClose();
2258
0
  }
2259
};
2260
2261
class PointerToMemberConversionExpr : public Node {
2262
  const Node *Type;
2263
  const Node *SubExpr;
2264
  std::string_view Offset;
2265
2266
public:
2267
  PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2268
                                std::string_view Offset_, Prec Prec_)
2269
0
      : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2270
0
        SubExpr(SubExpr_), Offset(Offset_) {}
2271
2272
0
  template <typename Fn> void match(Fn F) const {
2273
0
    F(Type, SubExpr, Offset, getPrecedence());
2274
0
  }
2275
2276
0
  void printLeft(OutputBuffer &OB) const override {
2277
0
    OB.printOpen();
2278
0
    Type->print(OB);
2279
0
    OB.printClose();
2280
0
    OB.printOpen();
2281
0
    SubExpr->print(OB);
2282
0
    OB.printClose();
2283
0
  }
2284
};
2285
2286
class InitListExpr : public Node {
2287
  const Node *Ty;
2288
  NodeArray Inits;
2289
public:
2290
  InitListExpr(const Node *Ty_, NodeArray Inits_)
2291
25.2k
      : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2292
2293
0
  template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2294
2295
0
  void printLeft(OutputBuffer &OB) const override {
2296
0
    if (Ty) {
2297
0
      if (Ty->printInitListAsType(OB, Inits))
2298
0
        return;
2299
0
      Ty->print(OB);
2300
0
    }
2301
0
    OB += '{';
2302
0
    Inits.printWithComma(OB);
2303
0
    OB += '}';
2304
0
  }
2305
};
2306
2307
class BracedExpr : public Node {
2308
  const Node *Elem;
2309
  const Node *Init;
2310
  bool IsArray;
2311
public:
2312
  BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2313
11.3k
      : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2314
2315
0
  template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2316
2317
0
  void printLeft(OutputBuffer &OB) const override {
2318
0
    if (IsArray) {
2319
0
      OB += '[';
2320
0
      Elem->print(OB);
2321
0
      OB += ']';
2322
0
    } else {
2323
0
      OB += '.';
2324
0
      Elem->print(OB);
2325
0
    }
2326
0
    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2327
0
      OB += " = ";
2328
0
    Init->print(OB);
2329
0
  }
2330
};
2331
2332
class BracedRangeExpr : public Node {
2333
  const Node *First;
2334
  const Node *Last;
2335
  const Node *Init;
2336
public:
2337
  BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2338
5.67k
      : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2339
2340
0
  template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2341
2342
0
  void printLeft(OutputBuffer &OB) const override {
2343
0
    OB += '[';
2344
0
    First->print(OB);
2345
0
    OB += " ... ";
2346
0
    Last->print(OB);
2347
0
    OB += ']';
2348
0
    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2349
0
      OB += " = ";
2350
0
    Init->print(OB);
2351
0
  }
2352
};
2353
2354
class FoldExpr : public Node {
2355
  const Node *Pack, *Init;
2356
  std::string_view OperatorName;
2357
  bool IsLeftFold;
2358
2359
public:
2360
  FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2361
           const Node *Init_)
2362
9
      : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2363
9
        IsLeftFold(IsLeftFold_) {}
2364
2365
0
  template<typename Fn> void match(Fn F) const {
2366
0
    F(IsLeftFold, OperatorName, Pack, Init);
2367
0
  }
2368
2369
0
  void printLeft(OutputBuffer &OB) const override {
2370
0
    auto PrintPack = [&] {
2371
0
      OB.printOpen();
2372
0
      ParameterPackExpansion(Pack).print(OB);
2373
0
      OB.printClose();
2374
0
    };
2375
2376
0
    OB.printOpen();
2377
    // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2378
    // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2379
    // Fold expr operands are cast-expressions
2380
0
    if (!IsLeftFold || Init != nullptr) {
2381
      // '(init|pack) op '
2382
0
      if (IsLeftFold)
2383
0
        Init->printAsOperand(OB, Prec::Cast, true);
2384
0
      else
2385
0
        PrintPack();
2386
0
      OB << " " << OperatorName << " ";
2387
0
    }
2388
0
    OB << "...";
2389
0
    if (IsLeftFold || Init != nullptr) {
2390
      // ' op (init|pack)'
2391
0
      OB << " " << OperatorName << " ";
2392
0
      if (IsLeftFold)
2393
0
        PrintPack();
2394
0
      else
2395
0
        Init->printAsOperand(OB, Prec::Cast, true);
2396
0
    }
2397
0
    OB.printClose();
2398
0
  }
2399
};
2400
2401
class ThrowExpr : public Node {
2402
  const Node *Op;
2403
2404
public:
2405
0
  ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2406
2407
0
  template<typename Fn> void match(Fn F) const { F(Op); }
2408
2409
0
  void printLeft(OutputBuffer &OB) const override {
2410
0
    OB += "throw ";
2411
0
    Op->print(OB);
2412
0
  }
2413
};
2414
2415
class BoolExpr : public Node {
2416
  bool Value;
2417
2418
public:
2419
103
  BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2420
2421
0
  template<typename Fn> void match(Fn F) const { F(Value); }
2422
2423
0
  void printLeft(OutputBuffer &OB) const override {
2424
0
    OB += Value ? std::string_view("true") : std::string_view("false");
2425
0
  }
2426
};
2427
2428
class StringLiteral : public Node {
2429
  const Node *Type;
2430
2431
public:
2432
2
  StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2433
2434
0
  template<typename Fn> void match(Fn F) const { F(Type); }
2435
2436
0
  void printLeft(OutputBuffer &OB) const override {
2437
0
    OB += "\"<";
2438
0
    Type->print(OB);
2439
0
    OB += ">\"";
2440
0
  }
2441
};
2442
2443
class LambdaExpr : public Node {
2444
  const Node *Type;
2445
2446
public:
2447
0
  LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2448
2449
0
  template<typename Fn> void match(Fn F) const { F(Type); }
2450
2451
0
  void printLeft(OutputBuffer &OB) const override {
2452
0
    OB += "[]";
2453
0
    if (Type->getKind() == KClosureTypeName)
2454
0
      static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2455
0
    OB += "{...}";
2456
0
  }
2457
};
2458
2459
class EnumLiteral : public Node {
2460
  // ty(integer)
2461
  const Node *Ty;
2462
  std::string_view Integer;
2463
2464
public:
2465
  EnumLiteral(const Node *Ty_, std::string_view Integer_)
2466
103
      : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2467
2468
0
  template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2469
2470
0
  void printLeft(OutputBuffer &OB) const override {
2471
0
    OB.printOpen();
2472
0
    Ty->print(OB);
2473
0
    OB.printClose();
2474
2475
0
    if (Integer[0] == 'n')
2476
0
      OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2477
0
    else
2478
0
      OB << Integer;
2479
0
  }
2480
};
2481
2482
class IntegerLiteral : public Node {
2483
  std::string_view Type;
2484
  std::string_view Value;
2485
2486
public:
2487
  IntegerLiteral(std::string_view Type_, std::string_view Value_)
2488
124
      : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2489
2490
0
  template<typename Fn> void match(Fn F) const { F(Type, Value); }
2491
2492
0
  void printLeft(OutputBuffer &OB) const override {
2493
0
    if (Type.size() > 3) {
2494
0
      OB.printOpen();
2495
0
      OB += Type;
2496
0
      OB.printClose();
2497
0
    }
2498
2499
0
    if (Value[0] == 'n')
2500
0
      OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2501
0
    else
2502
0
      OB += Value;
2503
2504
0
    if (Type.size() <= 3)
2505
0
      OB += Type;
2506
0
  }
2507
2508
0
  std::string_view value() const { return Value; }
2509
};
2510
2511
class RequiresExpr : public Node {
2512
  NodeArray Parameters;
2513
  NodeArray Requirements;
2514
public:
2515
  RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2516
0
      : Node(KRequiresExpr), Parameters(Parameters_),
2517
0
        Requirements(Requirements_) {}
2518
2519
0
  template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2520
2521
0
  void printLeft(OutputBuffer &OB) const override {
2522
0
    OB += "requires";
2523
0
    if (!Parameters.empty()) {
2524
0
      OB += ' ';
2525
0
      OB.printOpen();
2526
0
      Parameters.printWithComma(OB);
2527
0
      OB.printClose();
2528
0
    }
2529
0
    OB += ' ';
2530
0
    OB.printOpen('{');
2531
0
    for (const Node *Req : Requirements) {
2532
0
      Req->print(OB);
2533
0
    }
2534
0
    OB += ' ';
2535
0
    OB.printClose('}');
2536
0
  }
2537
};
2538
2539
class ExprRequirement : public Node {
2540
  const Node *Expr;
2541
  bool IsNoexcept;
2542
  const Node *TypeConstraint;
2543
public:
2544
  ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2545
                  const Node *TypeConstraint_)
2546
0
      : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2547
0
        TypeConstraint(TypeConstraint_) {}
2548
2549
0
  template <typename Fn> void match(Fn F) const {
2550
0
    F(Expr, IsNoexcept, TypeConstraint);
2551
0
  }
2552
2553
0
  void printLeft(OutputBuffer &OB) const override {
2554
0
    OB += " ";
2555
0
    if (IsNoexcept || TypeConstraint)
2556
0
      OB.printOpen('{');
2557
0
    Expr->print(OB);
2558
0
    if (IsNoexcept || TypeConstraint)
2559
0
      OB.printClose('}');
2560
0
    if (IsNoexcept)
2561
0
      OB += " noexcept";
2562
0
    if (TypeConstraint) {
2563
0
      OB += " -> ";
2564
0
      TypeConstraint->print(OB);
2565
0
    }
2566
0
    OB += ';';
2567
0
  }
2568
};
2569
2570
class TypeRequirement : public Node {
2571
  const Node *Type;
2572
public:
2573
  TypeRequirement(const Node *Type_)
2574
0
      : Node(KTypeRequirement), Type(Type_) {}
2575
2576
0
  template <typename Fn> void match(Fn F) const { F(Type); }
2577
2578
0
  void printLeft(OutputBuffer &OB) const override {
2579
0
    OB += " typename ";
2580
0
    Type->print(OB);
2581
0
    OB += ';';
2582
0
  }
2583
};
2584
2585
class NestedRequirement : public Node {
2586
  const Node *Constraint;
2587
public:
2588
  NestedRequirement(const Node *Constraint_)
2589
0
      : Node(KNestedRequirement), Constraint(Constraint_) {}
2590
2591
0
  template <typename Fn> void match(Fn F) const { F(Constraint); }
2592
2593
0
  void printLeft(OutputBuffer &OB) const override {
2594
0
    OB += " requires ";
2595
0
    Constraint->print(OB);
2596
0
    OB += ';';
2597
0
  }
2598
};
2599
2600
template <class Float> struct FloatData;
2601
2602
namespace float_literal_impl {
2603
0
constexpr Node::Kind getFloatLiteralKind(float *) {
2604
0
  return Node::KFloatLiteral;
2605
0
}
2606
0
constexpr Node::Kind getFloatLiteralKind(double *) {
2607
0
  return Node::KDoubleLiteral;
2608
0
}
2609
0
constexpr Node::Kind getFloatLiteralKind(long double *) {
2610
0
  return Node::KLongDoubleLiteral;
2611
0
}
2612
}
2613
2614
template <class Float> class FloatLiteralImpl : public Node {
2615
  const std::string_view Contents;
2616
2617
  static constexpr Kind KindForClass =
2618
      float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2619
2620
public:
2621
  FloatLiteralImpl(std::string_view Contents_)
2622
0
      : Node(KindForClass), Contents(Contents_) {}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
2623
2624
0
  template<typename Fn> void match(Fn F) const { F(Contents); }
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
2625
2626
0
  void printLeft(OutputBuffer &OB) const override {
2627
0
    const size_t N = FloatData<Float>::mangled_size;
2628
0
    if (Contents.size() >= N) {
2629
0
      union {
2630
0
        Float value;
2631
0
        char buf[sizeof(Float)];
2632
0
      };
2633
0
      const char *t = Contents.data();
2634
0
      const char *last = t + N;
2635
0
      char *e = buf;
2636
0
      for (; t != last; ++t, ++e) {
2637
0
        unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2638
0
                                  : static_cast<unsigned>(*t - 'a' + 10);
2639
0
        ++t;
2640
0
        unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2641
0
                                  : static_cast<unsigned>(*t - 'a' + 10);
2642
0
        *e = static_cast<char>((d1 << 4) + d0);
2643
0
      }
2644
0
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2645
0
      std::reverse(buf, e);
2646
0
#endif
2647
0
      char num[FloatData<Float>::max_demangled_size] = {0};
2648
0
      int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2649
0
      OB += std::string_view(num, n);
2650
0
    }
2651
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
2652
};
2653
2654
using FloatLiteral = FloatLiteralImpl<float>;
2655
using DoubleLiteral = FloatLiteralImpl<double>;
2656
using LongDoubleLiteral = FloatLiteralImpl<long double>;
2657
2658
/// Visit the node. Calls \c F(P), where \c P is the node cast to the
2659
/// appropriate derived class.
2660
template<typename Fn>
2661
0
void Node::visit(Fn F) const {
2662
0
  switch (K) {
2663
0
#define NODE(X)                                                                \
2664
0
  case K##X:                                                                   \
2665
0
    return F(static_cast<const X *>(this));
2666
0
#include "ItaniumNodes.def"
2667
0
  }
2668
0
  DEMANGLE_ASSERT(0, "unknown mangling node kind");
2669
0
}
2670
2671
/// Determine the kind of a node from its type.
2672
template<typename NodeT> struct NodeKind;
2673
#define NODE(X)                                                                \
2674
  template <> struct NodeKind<X> {                                             \
2675
    static constexpr Node::Kind Kind = Node::K##X;                             \
2676
0
    static constexpr const char *name() { return #X; }                         \
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NodeArrayNode>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DotSuffix>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::VendorExtQualType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::QualType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConversionOperatorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PostfixQualifiedType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ElaboratedTypeSpefType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TransformedType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NameType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::AbiTagAttr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnableIfAttr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ObjCProtoName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ReferenceType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerToMemberType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ArrayType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NoexceptSpec>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DynamicExceptionSpec>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionEncoding>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LiteralOperator>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SpecialName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CtorVtableSpecialName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::QualifiedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NestedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::MemberLikeFriendName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LocalName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ModuleName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ModuleEntity>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::VectorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PixelVectorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BinaryFPType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BitIntType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SyntheticTemplateParamName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateParamQualifiedArg>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConstrainedTypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NonTypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateParamPackDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ParameterPack>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateArgumentPack>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ParameterPackExpansion>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateArgs>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NameWithTemplateArgs>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::GlobalQualifiedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExpandedSpecialSubstitution>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SpecialSubstitution>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CtorDtorName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DtorName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::UnnamedTypeName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ClosureTypeName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::StructuredBindingName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BinaryExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ArraySubscriptExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PostfixExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConditionalExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::MemberExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SubobjectExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnclosingExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CastExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SizeofParamPackExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CallExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NewExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DeleteExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PrefixExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionParam>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConversionExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerToMemberConversionExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::InitListExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FoldExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ThrowExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BoolExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::StringLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LambdaExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnumLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::IntegerLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BracedExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BracedRangeExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::RequiresExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExprRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TypeRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NestedRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExplicitObjectParameter>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PackIndexing>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ForwardTemplateReference>::name()
2677
  };
2678
#include "ItaniumNodes.def"
2679
2680
0
inline bool NodeArray::printAsString(OutputBuffer &OB) const {
2681
0
  auto StartPos = OB.getCurrentPosition();
2682
0
  auto Fail = [&OB, StartPos] {
2683
0
    OB.setCurrentPosition(StartPos);
2684
0
    return false;
2685
0
  };
2686
2687
0
  OB += '"';
2688
0
  bool LastWasNumericEscape = false;
2689
0
  for (const Node *Element : *this) {
2690
0
    if (Element->getKind() != Node::KIntegerLiteral)
2691
0
      return Fail();
2692
0
    int integer_value = 0;
2693
0
    for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
2694
0
      if (c < '0' || c > '9' || integer_value > 25)
2695
0
        return Fail();
2696
0
      integer_value *= 10;
2697
0
      integer_value += c - '0';
2698
0
    }
2699
0
    if (integer_value > 255)
2700
0
      return Fail();
2701
2702
    // Insert a `""` to avoid accidentally extending a numeric escape.
2703
0
    if (LastWasNumericEscape) {
2704
0
      if ((integer_value >= '0' && integer_value <= '9') ||
2705
0
          (integer_value >= 'a' && integer_value <= 'f') ||
2706
0
          (integer_value >= 'A' && integer_value <= 'F')) {
2707
0
        OB += "\"\"";
2708
0
      }
2709
0
    }
2710
2711
0
    LastWasNumericEscape = false;
2712
2713
    // Determine how to print this character.
2714
0
    switch (integer_value) {
2715
0
    case '\a':
2716
0
      OB += "\\a";
2717
0
      break;
2718
0
    case '\b':
2719
0
      OB += "\\b";
2720
0
      break;
2721
0
    case '\f':
2722
0
      OB += "\\f";
2723
0
      break;
2724
0
    case '\n':
2725
0
      OB += "\\n";
2726
0
      break;
2727
0
    case '\r':
2728
0
      OB += "\\r";
2729
0
      break;
2730
0
    case '\t':
2731
0
      OB += "\\t";
2732
0
      break;
2733
0
    case '\v':
2734
0
      OB += "\\v";
2735
0
      break;
2736
2737
0
    case '"':
2738
0
      OB += "\\\"";
2739
0
      break;
2740
0
    case '\\':
2741
0
      OB += "\\\\";
2742
0
      break;
2743
2744
0
    default:
2745
      // We assume that the character is ASCII, and use a numeric escape for all
2746
      // remaining non-printable ASCII characters.
2747
0
      if (integer_value < 32 || integer_value == 127) {
2748
0
        constexpr char Hex[] = "0123456789ABCDEF";
2749
0
        OB += '\\';
2750
0
        if (integer_value > 7)
2751
0
          OB += 'x';
2752
0
        if (integer_value >= 16)
2753
0
          OB += Hex[integer_value >> 4];
2754
0
        OB += Hex[integer_value & 0xF];
2755
0
        LastWasNumericEscape = true;
2756
0
        break;
2757
0
      }
2758
2759
      // Assume all remaining characters are directly printable.
2760
0
      OB += (char)integer_value;
2761
0
      break;
2762
0
    }
2763
0
  }
2764
0
  OB += '"';
2765
0
  return true;
2766
0
}
2767
2768
template <typename Derived, typename Alloc> struct AbstractManglingParser {
2769
  const char *First;
2770
  const char *Last;
2771
2772
  // Name stack, this is used by the parser to hold temporary names that were
2773
  // parsed. The parser collapses multiple names into new nodes to construct
2774
  // the AST. Once the parser is finished, names.size() == 1.
2775
  PODSmallVector<Node *, 32> Names;
2776
2777
  // Substitution table. Itanium supports name substitutions as a means of
2778
  // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2779
  // table.
2780
  PODSmallVector<Node *, 32> Subs;
2781
2782
  // A list of template argument values corresponding to a template parameter
2783
  // list.
2784
  using TemplateParamList = PODSmallVector<Node *, 8>;
2785
2786
  class ScopedTemplateParamList {
2787
    AbstractManglingParser *Parser;
2788
    size_t OldNumTemplateParamLists;
2789
    TemplateParamList Params;
2790
2791
  public:
2792
    ScopedTemplateParamList(AbstractManglingParser *TheParser)
2793
17.0k
        : Parser(TheParser),
2794
17.0k
          OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2795
17.0k
      Parser->TemplateParams.push_back(&Params);
2796
17.0k
    }
2797
17.0k
    ~ScopedTemplateParamList() {
2798
17.0k
      DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2799
17.0k
                      "");
2800
17.0k
      Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2801
17.0k
    }
2802
21.8k
    TemplateParamList *params() { return &Params; }
2803
  };
2804
2805
  // Template parameter table. Like the above, but referenced like "T42_".
2806
  // This has a smaller size compared to Subs and Names because it can be
2807
  // stored on the stack.
2808
  TemplateParamList OuterTemplateParams;
2809
2810
  // Lists of template parameters indexed by template parameter depth,
2811
  // referenced like "TL2_4_". If nonempty, element 0 is always
2812
  // OuterTemplateParams; inner elements are always template parameter lists of
2813
  // lambda expressions. For a generic lambda with no explicit template
2814
  // parameter list, the corresponding parameter list pointer will be null.
2815
  PODSmallVector<TemplateParamList *, 4> TemplateParams;
2816
2817
  class SaveTemplateParams {
2818
    AbstractManglingParser *Parser;
2819
    decltype(TemplateParams) OldParams;
2820
    decltype(OuterTemplateParams) OldOuterParams;
2821
2822
  public:
2823
9.72k
    SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2824
9.72k
      OldParams = std::move(Parser->TemplateParams);
2825
9.72k
      OldOuterParams = std::move(Parser->OuterTemplateParams);
2826
9.72k
      Parser->TemplateParams.clear();
2827
9.72k
      Parser->OuterTemplateParams.clear();
2828
9.72k
    }
2829
9.72k
    ~SaveTemplateParams() {
2830
9.72k
      Parser->TemplateParams = std::move(OldParams);
2831
9.72k
      Parser->OuterTemplateParams = std::move(OldOuterParams);
2832
9.72k
    }
2833
  };
2834
2835
  // Set of unresolved forward <template-param> references. These can occur in a
2836
  // conversion operator's type, and are resolved in the enclosing <encoding>.
2837
  PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2838
2839
  bool TryToParseTemplateArgs = true;
2840
  bool PermitForwardTemplateReferences = false;
2841
  bool HasIncompleteTemplateParameterTracking = false;
2842
  size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2843
2844
  unsigned NumSyntheticTemplateParameters[3] = {};
2845
2846
  Alloc ASTAllocator;
2847
2848
  AbstractManglingParser(const char *First_, const char *Last_)
2849
22
      : First(First_), Last(Last_) {}
2850
2851
6.84M
  Derived &getDerived() { return static_cast<Derived &>(*this); }
2852
2853
  void reset(const char *First_, const char *Last_) {
2854
    First = First_;
2855
    Last = Last_;
2856
    Names.clear();
2857
    Subs.clear();
2858
    TemplateParams.clear();
2859
    ParsingLambdaParamsAtLevel = (size_t)-1;
2860
    TryToParseTemplateArgs = true;
2861
    PermitForwardTemplateReferences = false;
2862
    for (unsigned int & NumSyntheticTemplateParameter : NumSyntheticTemplateParameters)
2863
      NumSyntheticTemplateParameter = 0;
2864
    ASTAllocator.reset();
2865
  }
2866
2867
3.68M
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3.68M
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3.68M
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [31], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [31], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [12], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [12], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [14], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [14], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [19], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [19], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [27], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [27], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CtorVtableSpecialName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [41], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [41], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [18], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [18], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [22], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [22], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [20], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [20], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [25], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [25], (anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [22]>(char const (&) [22])
Line
Count
Source
2867
21.1k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
21.1k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
21.1k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
54.1k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
54.1k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
54.1k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ModuleName, (anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&, bool&>((anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&, bool&)
Line
Count
Source
2867
3
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [24], (anonymous namespace)::itanium_demangle::ModuleName*&>(char const (&) [24], (anonymous namespace)::itanium_demangle::ModuleName*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> >&&)
Line
Count
Source
2867
174k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
174k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
174k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ForwardTemplateReference, unsigned long&>(unsigned long&)
Line
Count
Source
2867
2
  template <class T, class... Args> Node *make(Args &&... args) {
2868
2
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
2
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [5]>(char const (&) [5])
Line
Count
Source
2867
374k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
374k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
374k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BinaryExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PrefixExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&)
Line
Count
Source
2867
10.4k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
10.4k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
10.4k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ArraySubscriptExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::MemberExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NewExpr, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, bool&, bool, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, bool&, bool&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Line
Count
Source
2867
4
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DeleteExpr, (anonymous namespace)::itanium_demangle::Node*&, bool&, bool, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, bool&, bool&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Line
Count
Source
2867
14.7k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
14.7k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
14.7k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CallExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray, bool, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&&, bool&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Line
Count
Source
2867
200
  template <class T, class... Args> Node *make(Args &&... args) {
2868
200
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
200
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConversionExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConditionalExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CastExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::IntegerLiteral, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
124
  template <class T, class... Args> Node *make(Args &&... args) {
2868
124
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
124
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BoolExpr, int>(int&&)
Line
Count
Source
2867
103
  template <class T, class... Args> Node *make(Args &&... args) {
2868
103
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
103
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::StringLiteral, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
2
  template <class T, class... Args> Node *make(Args &&... args) {
2868
2
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
2
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [8]>(char const (&) [8])
Line
Count
Source
2867
87.0k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
87.0k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
87.0k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::UnnamedTypeName, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
44
  template <class T, class... Args> Node *make(Args &&... args) {
2868
44
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
44
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SyntheticTemplateParamName, (anonymous namespace)::itanium_demangle::TemplateParamKind&, unsigned int&>((anonymous namespace)::itanium_demangle::TemplateParamKind&, unsigned int&)
Line
Count
Source
2867
21.8k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
21.8k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
21.8k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
12.7k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
12.7k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
12.7k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConstrainedTypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NonTypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
264
  template <class T, class... Args> Node *make(Args &&... args) {
2868
264
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
264
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
8.82k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
8.82k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
8.82k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateParamPackDecl, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
229
  template <class T, class... Args> Node *make(Args &&... args) {
2868
229
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
229
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ClosureTypeName, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
1.47k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1.47k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1.47k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [16]>(char const (&) [16])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LambdaExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnumLiteral, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
103
  template <class T, class... Args> Node *make(Args &&... args) {
2868
103
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
103
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionParam, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
3
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FoldExpr, bool&, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>(bool&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
9
  template <class T, class... Args> Node *make(Args &&... args) {
2868
9
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
9
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BracedExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, bool>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, bool&&)
Line
Count
Source
2867
11.3k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
11.3k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
11.3k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BracedRangeExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
5.67k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
5.67k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
5.67k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::InitListExpr, decltype(nullptr), (anonymous namespace)::itanium_demangle::NodeArray>(decltype(nullptr)&&, (anonymous namespace)::itanium_demangle::NodeArray&&)
Line
Count
Source
2867
19.6k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
19.6k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
19.6k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerToMemberConversionExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [10], (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(char const (&) [10], (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Line
Count
Source
2867
58
  template <class T, class... Args> Node *make(Args &&... args) {
2868
58
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
58
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExprRequirement, (anonymous namespace)::itanium_demangle::Node*&, bool&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, bool&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TypeRequirement, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NestedRequirement, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::RequiresExpr, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::NodeArray&&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SubobjectExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::NodeArray, bool&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::NodeArray&&, bool&)
Line
Count
Source
2867
4
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ParameterPackExpansion, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
14.9k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
14.9k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
14.9k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PackIndexing, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SizeofParamPackExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [11], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [11], (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
25.3k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
25.3k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
25.3k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NodeArrayNode, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Line
Count
Source
2867
25.3k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
25.3k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
25.3k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::InitListExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&&)
Line
Count
Source
2867
5.67k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
5.67k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
5.67k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [6]>(char const (&) [6])
Line
Count
Source
2867
192k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
192k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
192k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ThrowExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::QualifiedName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
4.09k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4.09k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4.09k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DtorName, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
4
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConversionOperatorType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
107
  template <class T, class... Args> Node *make(Args &&... args) {
2868
107
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
107
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LiteralOperator, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
113
  template <class T, class... Args> Node *make(Args &&... args) {
2868
113
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
113
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::GlobalQualifiedName, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
907
  template <class T, class... Args> Node *make(Args &&... args) {
2868
907
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
907
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
4
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [4]>(char const (&) [4])
Line
Count
Source
2867
300k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
300k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
300k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialSubstitution, (anonymous namespace)::itanium_demangle::SpecialSubKind&>((anonymous namespace)::itanium_demangle::SpecialSubKind&)
Line
Count
Source
2867
13.1k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
13.1k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
13.1k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::AbiTagAttr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
4
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::StructuredBindingName, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExpandedSpecialSubstitution, (anonymous namespace)::itanium_demangle::SpecialSubstitution*>((anonymous namespace)::itanium_demangle::SpecialSubstitution*&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CtorDtorName, (anonymous namespace)::itanium_demangle::Node*&, bool, int&>((anonymous namespace)::itanium_demangle::Node*&, bool&&, int&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ModuleEntity, (anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
3
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::MemberLikeFriendName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NestedName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
4.01k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4.01k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4.01k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [15]>(char const (&) [15])
Line
Count
Source
2867
193k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
193k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
193k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LocalName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
2.85k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
2.85k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
2.85k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ParameterPack, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Line
Count
Source
2867
1.37k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1.37k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1.37k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateArgs, (anonymous namespace)::itanium_demangle::NodeArray, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::NodeArray&&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
14.9k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
14.9k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
14.9k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameWithTemplateArgs, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
14.9k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
14.9k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
14.9k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateArgumentPack, (anonymous namespace)::itanium_demangle::NodeArray&>((anonymous namespace)::itanium_demangle::NodeArray&)
Line
Count
Source
2867
15.6k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
15.6k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
15.6k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateParamQualifiedArg, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
1
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnableIfAttr, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExplicitObjectParameter, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionEncoding, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&)
Line
Count
Source
2867
2.62k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
2.62k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
2.62k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DotSuffix, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> > >((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&&)
Line
Count
Source
2867
1
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DotSuffix, (anonymous namespace)::itanium_demangle::Node*&, char const (&) [13]>((anonymous namespace)::itanium_demangle::Node*&, char const (&) [13])
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [34], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [34], (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
32
  template <class T, class... Args> Node *make(Args &&... args) {
2868
32
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
32
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NoexceptSpec, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
107
  template <class T, class... Args> Node *make(Args &&... args) {
2868
107
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
107
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DynamicExceptionSpec, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
26.9k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
26.9k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
26.9k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ObjCProtoName, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
3
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VendorExtQualType, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
4.02k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
4.02k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
4.02k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::QualType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&)
Line
Count
Source
2867
376k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
376k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
376k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [12]>(char const (&) [12])
Line
Count
Source
2867
44.4k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
44.4k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
44.4k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [14]>(char const (&) [14])
Line
Count
Source
2867
213k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
213k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
213k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [13]>(char const (&) [13])
Line
Count
Source
2867
442k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
442k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
442k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [10]>(char const (&) [10])
Line
Count
Source
2867
34.3k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
34.3k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
34.3k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [19]>(char const (&) [19])
Line
Count
Source
2867
27.1k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
27.1k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
27.1k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [9]>(char const (&) [9])
Line
Count
Source
2867
158k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
158k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
158k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [18]>(char const (&) [18])
Line
Count
Source
2867
59.8k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
59.8k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
59.8k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [7]>(char const (&) [7])
Line
Count
Source
2867
60.4k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
60.4k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
60.4k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [11]>(char const (&) [11])
Line
Count
Source
2867
338k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
338k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
338k
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TransformedType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BinaryFPType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
1.61k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1.61k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1.61k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [21]>(char const (&) [21])
Line
Count
Source
2867
1.89k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1.89k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1.89k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [27]>(char const (&) [27])
Line
Count
Source
2867
419
  template <class T, class... Args> Node *make(Args &&... args) {
2868
419
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
419
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [17]>(char const (&) [17])
Line
Count
Source
2867
17
  template <class T, class... Args> Node *make(Args &&... args) {
2868
17
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
17
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [26]>(char const (&) [26])
Line
Count
Source
2867
64
  template <class T, class... Args> Node *make(Args &&... args) {
2868
64
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
64
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BitIntType, (anonymous namespace)::itanium_demangle::Node*&, bool&>((anonymous namespace)::itanium_demangle::Node*&, bool&)
Line
Count
Source
2867
1.87k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
1.87k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
1.87k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Line
Count
Source
2867
103
  template <class T, class... Args> Node *make(Args &&... args) {
2868
103
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
103
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PixelVectorType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
24.0k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
24.0k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
24.0k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VectorType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
40.6k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
40.6k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
40.6k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VectorType, (anonymous namespace)::itanium_demangle::Node*&, decltype(nullptr)>((anonymous namespace)::itanium_demangle::Node*&, decltype(nullptr)&&)
Line
Count
Source
2867
74
  template <class T, class... Args> Node *make(Args &&... args) {
2868
74
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
74
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ArrayType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
7.38k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
7.38k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
7.38k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerToMemberType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
3.00k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
3.00k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
3.00k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ElaboratedTypeSpefType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
69
  template <class T, class... Args> Node *make(Args &&... args) {
2868
69
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
69
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Line
Count
Source
2867
76.7k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
76.7k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
76.7k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ReferenceType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::ReferenceKind>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::ReferenceKind&&)
Line
Count
Source
2867
75.9k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
75.9k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
75.9k
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, char const (&) [9]>((anonymous namespace)::itanium_demangle::Node*&, char const (&) [9])
Line
Count
Source
2867
311
  template <class T, class... Args> Node *make(Args &&... args) {
2868
311
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
311
  }
cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, char const (&) [11]>((anonymous namespace)::itanium_demangle::Node*&, char const (&) [11])
Line
Count
Source
2867
13.1k
  template <class T, class... Args> Node *make(Args &&... args) {
2868
13.1k
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2869
13.1k
  }
2870
2871
129k
  template <class It> NodeArray makeNodeArray(It begin, It end) {
2872
129k
    size_t sz = static_cast<size_t>(end - begin);
2873
129k
    void *mem = ASTAllocator.allocateNodeArray(sz);
2874
129k
    Node **data = new (mem) Node *[sz];
2875
129k
    std::copy(begin, end, data);
2876
129k
    return NodeArray(data, sz);
2877
129k
  }
2878
2879
129k
  NodeArray popTrailingNodeArray(size_t FromPosition) {
2880
129k
    DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2881
129k
    NodeArray res =
2882
129k
        makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2883
129k
    Names.shrinkToSize(FromPosition);
2884
129k
    return res;
2885
129k
  }
2886
2887
3.41M
  bool consumeIf(std::string_view S) {
2888
3.41M
    if (starts_with(std::string_view(First, Last - First), S)) {
2889
173k
      First += S.size();
2890
173k
      return true;
2891
173k
    }
2892
3.24M
    return false;
2893
3.41M
  }
2894
2895
6.21M
  bool consumeIf(char C) {
2896
6.21M
    if (First != Last && *First == C) {
2897
868k
      ++First;
2898
868k
      return true;
2899
868k
    }
2900
5.34M
    return false;
2901
6.21M
  }
2902
2903
67.0k
  char consume() { return First != Last ? *First++ : '\0'; }
2904
2905
11.5M
  char look(unsigned Lookahead = 0) const {
2906
11.5M
    if (static_cast<size_t>(Last - First) <= Lookahead)
2907
30
      return '\0';
2908
11.5M
    return First[Lookahead];
2909
11.5M
  }
2910
2911
1.14M
  size_t numLeft() const { return static_cast<size_t>(Last - First); }
2912
2913
  std::string_view parseNumber(bool AllowNegative = false);
2914
  Qualifiers parseCVQualifiers();
2915
  bool parsePositiveInteger(size_t *Out);
2916
  std::string_view parseBareSourceName();
2917
2918
  bool parseSeqId(size_t *Out);
2919
  Node *parseSubstitution();
2920
  Node *parseTemplateParam();
2921
  Node *parseTemplateParamDecl(TemplateParamList *Params);
2922
  Node *parseTemplateArgs(bool TagTemplates = false);
2923
  Node *parseTemplateArg();
2924
2925
28.4k
  bool isTemplateParamDecl() {
2926
28.4k
    return look() == 'T' &&
2927
20.3k
           std::string_view("yptnk").find(look(1)) != std::string_view::npos;
2928
28.4k
  }
2929
2930
  /// Parse the <expression> production.
2931
  Node *parseExpr();
2932
  Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2933
  Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2934
  Node *parseIntegerLiteral(std::string_view Lit);
2935
  Node *parseExprPrimary();
2936
  template <class Float> Node *parseFloatingLiteral();
2937
  Node *parseFunctionParam();
2938
  Node *parseConversionExpr();
2939
  Node *parseBracedExpr();
2940
  Node *parseFoldExpr();
2941
  Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2942
  Node *parseSubobjectExpr();
2943
  Node *parseConstraintExpr();
2944
  Node *parseRequiresExpr();
2945
2946
  /// Parse the <type> production.
2947
  Node *parseType();
2948
  Node *parseFunctionType();
2949
  Node *parseVectorType();
2950
  Node *parseDecltype();
2951
  Node *parseArrayType();
2952
  Node *parsePointerToMemberType();
2953
  Node *parseClassEnumType();
2954
  Node *parseQualifiedType();
2955
2956
  Node *parseEncoding(bool ParseParams = true);
2957
  bool parseCallOffset();
2958
  Node *parseSpecialName();
2959
2960
  /// Holds some extra information about a <name> that is being parsed. This
2961
  /// information is only pertinent if the <name> refers to an <encoding>.
2962
  struct NameState {
2963
    bool CtorDtorConversion = false;
2964
    bool EndsWithTemplateArgs = false;
2965
    Qualifiers CVQualifiers = QualNone;
2966
    FunctionRefQual ReferenceQualifier = FrefQualNone;
2967
    size_t ForwardTemplateRefsBegin;
2968
    bool HasExplicitObjectParameter = false;
2969
2970
    NameState(AbstractManglingParser *Enclosing)
2971
8.01k
        : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2972
  };
2973
2974
6.33k
  bool resolveForwardTemplateRefs(NameState &State) {
2975
6.33k
    size_t I = State.ForwardTemplateRefsBegin;
2976
6.33k
    size_t E = ForwardTemplateRefs.size();
2977
6.33k
    for (; I < E; ++I) {
2978
0
      size_t Idx = ForwardTemplateRefs[I]->Index;
2979
0
      if (TemplateParams.empty() || !TemplateParams[0] ||
2980
0
          Idx >= TemplateParams[0]->size())
2981
0
        return true;
2982
0
      ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2983
0
    }
2984
6.33k
    ForwardTemplateRefs.shrinkToSize(State.ForwardTemplateRefsBegin);
2985
6.33k
    return false;
2986
6.33k
  }
2987
2988
  /// Parse the <name> production>
2989
  Node *parseName(NameState *State = nullptr);
2990
  Node *parseLocalName(NameState *State);
2991
  Node *parseOperatorName(NameState *State);
2992
  bool parseModuleNameOpt(ModuleName *&Module);
2993
  Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2994
  Node *parseUnnamedTypeName(NameState *State);
2995
  Node *parseSourceName(NameState *State);
2996
  Node *parseUnscopedName(NameState *State, bool *isSubstName);
2997
  Node *parseNestedName(NameState *State);
2998
  Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2999
3000
  Node *parseAbiTags(Node *N);
3001
3002
  struct OperatorInfo {
3003
    enum OIKind : unsigned char {
3004
      Prefix,      // Prefix unary: @ expr
3005
      Postfix,     // Postfix unary: expr @
3006
      Binary,      // Binary: lhs @ rhs
3007
      Array,       // Array index:  lhs [ rhs ]
3008
      Member,      // Member access: lhs @ rhs
3009
      New,         // New
3010
      Del,         // Delete
3011
      Call,        // Function call: expr (expr*)
3012
      CCast,       // C cast: (type)expr
3013
      Conditional, // Conditional: expr ? expr : expr
3014
      NameOnly,    // Overload only, not allowed in expression.
3015
      // Below do not have operator names
3016
      NamedCast, // Named cast, @<type>(expr)
3017
      OfIdOp,    // alignof, sizeof, typeid
3018
3019
      Unnameable = NamedCast,
3020
    };
3021
    char Enc[2];      // Encoding
3022
    OIKind Kind;      // Kind of operator
3023
    bool Flag : 1;    // Entry-specific flag
3024
    Node::Prec Prec : 7; // Precedence
3025
    const char *Name; // Spelling
3026
3027
  public:
3028
    constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
3029
                           const char *N)
3030
        : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
3031
3032
  public:
3033
    bool operator<(const OperatorInfo &Other) const {
3034
      return *this < Other.Enc;
3035
    }
3036
1.53M
    bool operator<(const char *Peek) const {
3037
1.53M
      return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
3038
1.53M
    }
3039
258k
    bool operator==(const char *Peek) const {
3040
258k
      return Enc[0] == Peek[0] && Enc[1] == Peek[1];
3041
258k
    }
3042
258k
    bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
3043
3044
  public:
3045
25.2k
    std::string_view getSymbol() const {
3046
25.2k
      std::string_view Res = Name;
3047
25.2k
      if (Kind < Unnameable) {
3048
25.2k
        DEMANGLE_ASSERT(starts_with(Res, "operator"),
3049
25.2k
                        "operator name does not start with 'operator'");
3050
25.2k
        Res.remove_prefix(sizeof("operator") - 1);
3051
25.2k
        if (starts_with(Res, ' '))
3052
14.7k
          Res.remove_prefix(1);
3053
25.2k
      }
3054
25.2k
      return Res;
3055
25.2k
    }
3056
116k
    std::string_view getName() const { return Name; }
3057
375k
    OIKind getKind() const { return Kind; }
3058
63.8k
    bool getFlag() const { return Flag; }
3059
25.2k
    Node::Prec getPrecedence() const { return Prec; }
3060
  };
3061
  static const OperatorInfo Ops[];
3062
  static const size_t NumOps;
3063
  const OperatorInfo *parseOperatorEncoding();
3064
3065
  /// Parse the <unresolved-name> production.
3066
  Node *parseUnresolvedName(bool Global);
3067
  Node *parseSimpleId();
3068
  Node *parseBaseUnresolvedName();
3069
  Node *parseUnresolvedType();
3070
  Node *parseDestructorName();
3071
3072
  /// Top-level entry point into the parser.
3073
  Node *parse(bool ParseParams = true);
3074
};
3075
3076
DEMANGLE_ABI const char *parse_discriminator(const char *first,
3077
                                             const char *last);
3078
3079
// <name> ::= <nested-name> // N
3080
//        ::= <local-name> # See Scope Encoding below  // Z
3081
//        ::= <unscoped-template-name> <template-args>
3082
//        ::= <unscoped-name>
3083
//
3084
// <unscoped-template-name> ::= <unscoped-name>
3085
//                          ::= <substitution>
3086
template <typename Derived, typename Alloc>
3087
165k
Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
3088
165k
  if (look() == 'N')
3089
111
    return getDerived().parseNestedName(State);
3090
165k
  if (look() == 'Z')
3091
8.03k
    return getDerived().parseLocalName(State);
3092
3093
157k
  Node *Result = nullptr;
3094
157k
  bool IsSubst = false;
3095
3096
157k
  Result = getDerived().parseUnscopedName(State, &IsSubst);
3097
157k
  if (!Result)
3098
2.90k
    return nullptr;
3099
3100
154k
  if (look() == 'I') {
3101
    //        ::= <unscoped-template-name> <template-args>
3102
5.95k
    if (!IsSubst)
3103
      // An unscoped-template-name is substitutable.
3104
5.95k
      Subs.push_back(Result);
3105
5.95k
    Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3106
5.95k
    if (TA == nullptr)
3107
3.96k
      return nullptr;
3108
1.99k
    if (State)
3109
1.27k
      State->EndsWithTemplateArgs = true;
3110
1.99k
    Result = make<NameWithTemplateArgs>(Result, TA);
3111
148k
  } else if (IsSubst) {
3112
    // The substitution case must be followed by <template-args>.
3113
0
    return nullptr;
3114
0
  }
3115
3116
150k
  return Result;
3117
154k
}
3118
3119
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3120
//              := Z <function encoding> E s [<discriminator>]
3121
//              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
3122
template <typename Derived, typename Alloc>
3123
8.03k
Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
3124
8.03k
  if (!consumeIf('Z'))
3125
0
    return nullptr;
3126
8.03k
  Node *Encoding = getDerived().parseEncoding();
3127
8.03k
  if (Encoding == nullptr || !consumeIf('E'))
3128
5.15k
    return nullptr;
3129
3130
2.88k
  if (consumeIf('s')) {
3131
1.21k
    First = parse_discriminator(First, Last);
3132
1.21k
    auto *StringLitName = make<NameType>("string literal");
3133
1.21k
    if (!StringLitName)
3134
0
      return nullptr;
3135
1.21k
    return make<LocalName>(Encoding, StringLitName);
3136
1.21k
  }
3137
3138
  // The template parameters of the inner name are unrelated to those of the
3139
  // enclosing context.
3140
1.66k
  SaveTemplateParams SaveTemplateParamsScope(this);
3141
3142
1.66k
  if (consumeIf('d')) {
3143
948
    parseNumber(true);
3144
948
    if (!consumeIf('_'))
3145
0
      return nullptr;
3146
948
    Node *N = getDerived().parseName(State);
3147
948
    if (N == nullptr)
3148
0
      return nullptr;
3149
948
    return make<LocalName>(Encoding, N);
3150
948
  }
3151
3152
720
  Node *Entity = getDerived().parseName(State);
3153
720
  if (Entity == nullptr)
3154
28
    return nullptr;
3155
692
  First = parse_discriminator(First, Last);
3156
692
  return make<LocalName>(Encoding, Entity);
3157
720
}
3158
3159
// <unscoped-name> ::= <unqualified-name>
3160
//                 ::= St <unqualified-name>   # ::std::
3161
// [*] extension
3162
template <typename Derived, typename Alloc>
3163
Node *
3164
AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3165
172k
                                                          bool *IsSubst) {
3166
3167
172k
  Node *Std = nullptr;
3168
172k
  if (consumeIf("St")) {
3169
3.91k
    Std = make<NameType>("std");
3170
3.91k
    if (Std == nullptr)
3171
0
      return nullptr;
3172
3.91k
  }
3173
3174
172k
  Node *Res = nullptr;
3175
172k
  ModuleName *Module = nullptr;
3176
172k
  if (look() == 'S') {
3177
14.4k
    Node *S = getDerived().parseSubstitution();
3178
14.4k
    if (!S)
3179
0
      return nullptr;
3180
14.4k
    if (S->getKind() == Node::KModuleName)
3181
0
      Module = static_cast<ModuleName *>(S);
3182
14.4k
    else if (IsSubst && Std == nullptr) {
3183
14.4k
      Res = S;
3184
14.4k
      *IsSubst = true;
3185
14.4k
    } else {
3186
0
      return nullptr;
3187
0
    }
3188
14.4k
  }
3189
3190
172k
  if (Res == nullptr || Std != nullptr) {
3191
157k
    Res = getDerived().parseUnqualifiedName(State, Std, Module);
3192
157k
  }
3193
3194
172k
  return Res;
3195
172k
}
3196
3197
// <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3198
//                    ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3199
//                    ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3200
//                    ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3201
//      # structured binding declaration
3202
//                    ::= [<module-name>] L? DC <source-name>+ E
3203
template <typename Derived, typename Alloc>
3204
Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3205
157k
    NameState *State, Node *Scope, ModuleName *Module) {
3206
157k
  if (getDerived().parseModuleNameOpt(Module))
3207
0
    return nullptr;
3208
3209
157k
  bool IsMemberLikeFriend = Scope && consumeIf('F');
3210
3211
157k
  consumeIf('L');
3212
3213
157k
  Node *Result;
3214
157k
  if (look() >= '1' && look() <= '9') {
3215
40.5k
    Result = getDerived().parseSourceName(State);
3216
117k
  } else if (look() == 'U') {
3217
4.40k
    Result = getDerived().parseUnnamedTypeName(State);
3218
112k
  } else if (consumeIf("DC")) {
3219
    // Structured binding
3220
0
    size_t BindingsBegin = Names.size();
3221
0
    do {
3222
0
      Node *Binding = getDerived().parseSourceName(State);
3223
0
      if (Binding == nullptr)
3224
0
        return nullptr;
3225
0
      Names.push_back(Binding);
3226
0
    } while (!consumeIf('E'));
3227
0
    Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3228
112k
  } else if (look() == 'C' || look() == 'D') {
3229
    // A <ctor-dtor-name>.
3230
0
    if (Scope == nullptr || Module != nullptr)
3231
0
      return nullptr;
3232
0
    Result = getDerived().parseCtorDtorName(Scope, State);
3233
112k
  } else {
3234
112k
    Result = getDerived().parseOperatorName(State);
3235
112k
  }
3236
3237
157k
  if (Result != nullptr && Module != nullptr)
3238
3
    Result = make<ModuleEntity>(Module, Result);
3239
157k
  if (Result != nullptr)
3240
154k
    Result = getDerived().parseAbiTags(Result);
3241
157k
  if (Result != nullptr && IsMemberLikeFriend)
3242
0
    Result = make<MemberLikeFriendName>(Scope, Result);
3243
157k
  else if (Result != nullptr && Scope != nullptr)
3244
4.01k
    Result = make<NestedName>(Scope, Result);
3245
3246
157k
  return Result;
3247
157k
}
3248
3249
// <module-name> ::= <module-subname>
3250
//     ::= <module-name> <module-subname>
3251
//     ::= <substitution>  # passed in by caller
3252
// <module-subname> ::= W <source-name>
3253
//        ::= W P <source-name>
3254
template <typename Derived, typename Alloc>
3255
bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3256
157k
    ModuleName *&Module) {
3257
157k
  while (consumeIf('W')) {
3258
3
    bool IsPartition = consumeIf('P');
3259
3
    Node *Sub = getDerived().parseSourceName(nullptr);
3260
3
    if (!Sub)
3261
0
      return true;
3262
3
    Module =
3263
3
        static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3264
3
    Subs.push_back(Module);
3265
3
  }
3266
3267
157k
  return false;
3268
157k
}
3269
3270
// <unnamed-type-name> ::= Ut [<nonnegative number>] _
3271
//                     ::= <closure-type-name>
3272
//
3273
// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3274
//
3275
// <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3276
//                  <parameter type>+  # or "v" if the lambda has no parameters
3277
template <typename Derived, typename Alloc>
3278
Node *
3279
8.29k
AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3280
  // <template-params> refer to the innermost <template-args>. Clear out any
3281
  // outer args that we may have inserted into TemplateParams.
3282
8.29k
  if (State != nullptr)
3283
1.57k
    TemplateParams.clear();
3284
3285
8.29k
  if (consumeIf("Ut")) {
3286
44
    std::string_view Count = parseNumber();
3287
44
    if (!consumeIf('_'))
3288
0
      return nullptr;
3289
44
    return make<UnnamedTypeName>(Count);
3290
44
  }
3291
8.25k
  if (consumeIf("Ul")) {
3292
8.25k
    ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3293
8.25k
                                      TemplateParams.size());
3294
8.25k
    ScopedTemplateParamList LambdaTemplateParams(this);
3295
3296
8.25k
    size_t ParamsBegin = Names.size();
3297
17.4k
    while (getDerived().isTemplateParamDecl()) {
3298
9.22k
      Node *T =
3299
9.22k
          getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3300
9.22k
      if (T == nullptr)
3301
1
        return nullptr;
3302
9.22k
      Names.push_back(T);
3303
9.22k
    }
3304
8.25k
    NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3305
3306
    // FIXME: If TempParams is empty and none of the function parameters
3307
    // includes 'auto', we should remove LambdaTemplateParams from the
3308
    // TemplateParams list. Unfortunately, we don't find out whether there are
3309
    // any 'auto' parameters until too late in an example such as:
3310
    //
3311
    //   template<typename T> void f(
3312
    //       decltype([](decltype([]<typename T>(T v) {}),
3313
    //                   auto) {})) {}
3314
    //   template<typename T> void f(
3315
    //       decltype([](decltype([]<typename T>(T w) {}),
3316
    //                   int) {})) {}
3317
    //
3318
    // Here, the type of v is at level 2 but the type of w is at level 1. We
3319
    // don't find this out until we encounter the type of the next parameter.
3320
    //
3321
    // However, compilers can't actually cope with the former example in
3322
    // practice, and it's likely to be made ill-formed in future, so we don't
3323
    // need to support it here.
3324
    //
3325
    // If we encounter an 'auto' in the function parameter types, we will
3326
    // recreate a template parameter scope for it, but any intervening lambdas
3327
    // will be parsed in the 'wrong' template parameter depth.
3328
8.25k
    if (TempParams.empty())
3329
324
      TemplateParams.pop_back();
3330
3331
8.25k
    Node *Requires1 = nullptr;
3332
8.25k
    if (consumeIf('Q')) {
3333
0
      Requires1 = getDerived().parseConstraintExpr();
3334
0
      if (Requires1 == nullptr)
3335
0
        return nullptr;
3336
0
    }
3337
3338
8.25k
    if (!consumeIf("v")) {
3339
33.2k
      do {
3340
33.2k
        Node *P = getDerived().parseType();
3341
33.2k
        if (P == nullptr)
3342
6.77k
          return nullptr;
3343
26.5k
        Names.push_back(P);
3344
26.5k
      } while (look() != 'E' && look() != 'Q');
3345
8.25k
    }
3346
1.47k
    NodeArray Params = popTrailingNodeArray(ParamsBegin);
3347
3348
1.47k
    Node *Requires2 = nullptr;
3349
1.47k
    if (consumeIf('Q')) {
3350
0
      Requires2 = getDerived().parseConstraintExpr();
3351
0
      if (Requires2 == nullptr)
3352
0
        return nullptr;
3353
0
    }
3354
3355
1.47k
    if (!consumeIf('E'))
3356
0
      return nullptr;
3357
3358
1.47k
    std::string_view Count = parseNumber();
3359
1.47k
    if (!consumeIf('_'))
3360
0
      return nullptr;
3361
1.47k
    return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3362
1.47k
                                 Count);
3363
1.47k
  }
3364
0
  if (consumeIf("Ub")) {
3365
0
    (void)parseNumber();
3366
0
    if (!consumeIf('_'))
3367
0
      return nullptr;
3368
0
    return make<NameType>("'block-literal'");
3369
0
  }
3370
0
  return nullptr;
3371
0
}
3372
3373
// <source-name> ::= <positive length number> <identifier>
3374
template <typename Derived, typename Alloc>
3375
54.0k
Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3376
54.0k
  size_t Length = 0;
3377
54.0k
  if (parsePositiveInteger(&Length))
3378
0
    return nullptr;
3379
54.0k
  if (numLeft() < Length || Length == 0)
3380
1
    return nullptr;
3381
54.0k
  std::string_view Name(First, Length);
3382
54.0k
  First += Length;
3383
54.0k
  if (starts_with(Name, "_GLOBAL__N"))
3384
0
    return make<NameType>("(anonymous namespace)");
3385
54.0k
  return make<NameType>(Name);
3386
54.0k
}
3387
3388
// Operator encodings
3389
template <typename Derived, typename Alloc>
3390
const typename AbstractManglingParser<
3391
    Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3392
                                                         Alloc>::Ops[] = {
3393
    // Keep ordered by encoding
3394
    {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3395
    {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3396
    {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3397
    {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3398
    {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3399
    {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3400
    {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3401
     "operator co_await"},
3402
    {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3403
    {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3404
    {"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
3405
     "operator()"},
3406
    {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3407
    {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3408
    {"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
3409
     "operator()"},
3410
    {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3411
    {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3412
    {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3413
     "operator delete[]"},
3414
    {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3415
    {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3416
    {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3417
     "operator delete"},
3418
    {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3419
     "operator.*"},
3420
    {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3421
     "operator."},
3422
    {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3423
    {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3424
    {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3425
    {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3426
    {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3427
    {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3428
    {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3429
    {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3430
    {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3431
    {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3432
    {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3433
    {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3434
    {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3435
    {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3436
    {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3437
     "operator*"},
3438
    {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3439
    {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3440
     "operator new[]"},
3441
    {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3442
    {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3443
    {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3444
    {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3445
    {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3446
    {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3447
    {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3448
    {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3449
    {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3450
    {"pm", OperatorInfo::Member, /*Named*/ true, Node::Prec::PtrMem,
3451
     "operator->*"},
3452
    {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3453
    {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3454
    {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3455
     "operator->"},
3456
    {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3457
     "operator?"},
3458
    {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3459
    {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3460
    {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3461
     "reinterpret_cast"},
3462
    {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3463
     "operator%"},
3464
    {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3465
    {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3466
    {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3467
    {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3468
    {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3469
    {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3470
     "typeid "},
3471
    {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3472
};
3473
template <typename Derived, typename Alloc>
3474
const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3475
                                                              sizeof(Ops[0]);
3476
3477
// If the next 2 chars are an operator encoding, consume them and return their
3478
// OperatorInfo.  Otherwise return nullptr.
3479
template <typename Derived, typename Alloc>
3480
const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3481
258k
AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3482
258k
  if (numLeft() < 2)
3483
3
    return nullptr;
3484
3485
  // We can't use lower_bound as that can link to symbols in the C++ library,
3486
  // and this must remain independent of that.
3487
258k
  size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3488
1.79M
  while (upper != lower) {
3489
1.53M
    size_t middle = (upper + lower) / 2;
3490
1.53M
    if (Ops[middle] < First)
3491
691k
      lower = middle + 1;
3492
847k
    else
3493
847k
      upper = middle;
3494
1.53M
  }
3495
258k
  if (Ops[lower] != First)
3496
115k
    return nullptr;
3497
3498
142k
  First += 2;
3499
142k
  return &Ops[lower];
3500
258k
}
3501
3502
//   <operator-name> ::= See parseOperatorEncoding()
3503
//                   ::= li <source-name>  # operator ""
3504
//                   ::= v <digit> <source-name>  # vendor extended operator
3505
template <typename Derived, typename Alloc>
3506
Node *
3507
117k
AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3508
117k
  if (const auto *Op = parseOperatorEncoding()) {
3509
116k
    if (Op->getKind() == OperatorInfo::CCast) {
3510
      //              ::= cv <type>    # (cast)
3511
107
      ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3512
      // If we're parsing an encoding, State != nullptr and the conversion
3513
      // operators' <type> could have a <template-param> that refers to some
3514
      // <template-arg>s further ahead in the mangled name.
3515
107
      ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3516
107
                                      PermitForwardTemplateReferences ||
3517
107
                                          State != nullptr);
3518
107
      Node *Ty = getDerived().parseType();
3519
107
      if (Ty == nullptr)
3520
0
        return nullptr;
3521
107
      if (State) State->CtorDtorConversion = true;
3522
107
      return make<ConversionOperatorType>(Ty);
3523
107
    }
3524
3525
116k
    if (Op->getKind() >= OperatorInfo::Unnameable)
3526
      /* Not a nameable operator.  */
3527
0
      return nullptr;
3528
116k
    if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3529
      /* Not a nameable MemberExpr */
3530
0
      return nullptr;
3531
3532
116k
    return make<NameType>(Op->getName());
3533
116k
  }
3534
3535
130
  if (consumeIf("li")) {
3536
    //                   ::= li <source-name>  # operator ""
3537
113
    Node *SN = getDerived().parseSourceName(State);
3538
113
    if (SN == nullptr)
3539
0
      return nullptr;
3540
113
    return make<LiteralOperator>(SN);
3541
113
  }
3542
3543
17
  if (consumeIf('v')) {
3544
    // ::= v <digit> <source-name>        # vendor extended operator
3545
0
    if (look() >= '0' && look() <= '9') {
3546
0
      First++;
3547
0
      Node *SN = getDerived().parseSourceName(State);
3548
0
      if (SN == nullptr)
3549
0
        return nullptr;
3550
0
      return make<ConversionOperatorType>(SN);
3551
0
    }
3552
0
    return nullptr;
3553
0
  }
3554
3555
17
  return nullptr;
3556
17
}
3557
3558
// <ctor-dtor-name> ::= C1  # complete object constructor
3559
//                  ::= C2  # base object constructor
3560
//                  ::= C3  # complete object allocating constructor
3561
//   extension      ::= C4  # gcc old-style "[unified]" constructor
3562
//   extension      ::= C5  # the COMDAT used for ctors
3563
//                  ::= D0  # deleting destructor
3564
//                  ::= D1  # complete object destructor
3565
//                  ::= D2  # base object destructor
3566
//   extension      ::= D4  # gcc old-style "[unified]" destructor
3567
//   extension      ::= D5  # the COMDAT used for dtors
3568
template <typename Derived, typename Alloc>
3569
Node *
3570
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3571
0
                                                          NameState *State) {
3572
0
  if (SoFar->getKind() == Node::KSpecialSubstitution) {
3573
    // Expand the special substitution.
3574
0
    SoFar = make<ExpandedSpecialSubstitution>(
3575
0
        static_cast<SpecialSubstitution *>(SoFar));
3576
0
    if (!SoFar)
3577
0
      return nullptr;
3578
0
  }
3579
3580
0
  if (consumeIf('C')) {
3581
0
    bool IsInherited = consumeIf('I');
3582
0
    if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3583
0
        look() != '5')
3584
0
      return nullptr;
3585
0
    int Variant = look() - '0';
3586
0
    ++First;
3587
0
    if (State) State->CtorDtorConversion = true;
3588
0
    if (IsInherited) {
3589
0
      if (getDerived().parseName(State) == nullptr)
3590
0
        return nullptr;
3591
0
    }
3592
0
    return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3593
0
  }
3594
3595
0
  if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3596
0
                        look(1) == '4' || look(1) == '5')) {
3597
0
    int Variant = look(1) - '0';
3598
0
    First += 2;
3599
0
    if (State) State->CtorDtorConversion = true;
3600
0
    return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3601
0
  }
3602
3603
0
  return nullptr;
3604
0
}
3605
3606
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3607
//      <unqualified-name> E
3608
//               ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3609
//                <template-args> E
3610
//
3611
// <prefix> ::= <prefix> <unqualified-name>
3612
//          ::= <template-prefix> <template-args>
3613
//          ::= <template-param>
3614
//          ::= <decltype>
3615
//          ::= # empty
3616
//          ::= <substitution>
3617
//          ::= <prefix> <data-member-prefix>
3618
// [*] extension
3619
//
3620
// <data-member-prefix> := <member source-name> [<template-args>] M
3621
//
3622
// <template-prefix> ::= <prefix> <template unqualified-name>
3623
//                   ::= <template-param>
3624
//                   ::= <substitution>
3625
template <typename Derived, typename Alloc>
3626
Node *
3627
111
AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3628
111
  if (!consumeIf('N'))
3629
0
    return nullptr;
3630
3631
  // 'H' specifies that the encoding that follows
3632
  // has an explicit object parameter.
3633
111
  if (!consumeIf('H')) {
3634
111
    Qualifiers CVTmp = parseCVQualifiers();
3635
111
    if (State)
3636
111
      State->CVQualifiers = CVTmp;
3637
3638
111
    if (consumeIf('O')) {
3639
103
      if (State)
3640
103
        State->ReferenceQualifier = FrefQualRValue;
3641
103
    } else if (consumeIf('R')) {
3642
0
      if (State)
3643
0
        State->ReferenceQualifier = FrefQualLValue;
3644
8
    } else {
3645
8
      if (State)
3646
8
        State->ReferenceQualifier = FrefQualNone;
3647
8
    }
3648
111
  } else if (State) {
3649
0
    State->HasExplicitObjectParameter = true;
3650
0
  }
3651
3652
111
  Node *SoFar = nullptr;
3653
436
  while (!consumeIf('E')) {
3654
325
    if (State)
3655
      // Only set end-with-template on the case that does that.
3656
325
      State->EndsWithTemplateArgs = false;
3657
3658
325
    if (look() == 'T') {
3659
      //          ::= <template-param>
3660
0
      if (SoFar != nullptr)
3661
0
        return nullptr; // Cannot have a prefix.
3662
0
      SoFar = getDerived().parseTemplateParam();
3663
325
    } else if (look() == 'I') {
3664
      //          ::= <template-prefix> <template-args>
3665
111
      if (SoFar == nullptr)
3666
0
        return nullptr; // Must have a prefix.
3667
111
      Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3668
111
      if (TA == nullptr)
3669
0
        return nullptr;
3670
111
      if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3671
        // Semantically <template-args> <template-args> cannot be generated by a
3672
        // C++ entity.  There will always be [something like] a name between
3673
        // them.
3674
0
        return nullptr;
3675
111
      if (State)
3676
111
        State->EndsWithTemplateArgs = true;
3677
111
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3678
214
    } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3679
      //          ::= <decltype>
3680
0
      if (SoFar != nullptr)
3681
0
        return nullptr; // Cannot have a prefix.
3682
0
      SoFar = getDerived().parseDecltype();
3683
214
    } else {
3684
214
      ModuleName *Module = nullptr;
3685
3686
214
      if (look() == 'S') {
3687
        //          ::= <substitution>
3688
0
        Node *S = nullptr;
3689
0
        if (look(1) == 't') {
3690
0
          First += 2;
3691
0
          S = make<NameType>("std");
3692
0
        } else {
3693
0
          S = getDerived().parseSubstitution();
3694
0
        }
3695
0
        if (!S)
3696
0
          return nullptr;
3697
0
        if (S->getKind() == Node::KModuleName) {
3698
0
          Module = static_cast<ModuleName *>(S);
3699
0
        } else if (SoFar != nullptr) {
3700
0
          return nullptr; // Cannot have a prefix.
3701
0
        } else {
3702
0
          SoFar = S;
3703
0
          continue; // Do not push a new substitution.
3704
0
        }
3705
0
      }
3706
3707
      //          ::= [<prefix>] <unqualified-name>
3708
214
      SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3709
214
    }
3710
3711
325
    if (SoFar == nullptr)
3712
0
      return nullptr;
3713
325
    Subs.push_back(SoFar);
3714
3715
    // No longer used.
3716
    // <data-member-prefix> := <member source-name> [<template-args>] M
3717
325
    consumeIf('M');
3718
325
  }
3719
3720
111
  if (SoFar == nullptr || Subs.empty())
3721
0
    return nullptr;
3722
3723
111
  Subs.pop_back();
3724
111
  return SoFar;
3725
111
}
3726
3727
// <simple-id> ::= <source-name> [ <template-args> ]
3728
template <typename Derived, typename Alloc>
3729
11.5k
Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3730
11.5k
  Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3731
11.5k
  if (SN == nullptr)
3732
0
    return nullptr;
3733
11.5k
  if (look() == 'I') {
3734
0
    Node *TA = getDerived().parseTemplateArgs();
3735
0
    if (TA == nullptr)
3736
0
      return nullptr;
3737
0
    return make<NameWithTemplateArgs>(SN, TA);
3738
0
  }
3739
11.5k
  return SN;
3740
11.5k
}
3741
3742
// <destructor-name> ::= <unresolved-type>  # e.g., ~T or ~decltype(f())
3743
//                   ::= <simple-id>        # e.g., ~A<2*N>
3744
template <typename Derived, typename Alloc>
3745
4
Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3746
4
  Node *Result;
3747
4
  if (std::isdigit(look()))
3748
4
    Result = getDerived().parseSimpleId();
3749
0
  else
3750
0
    Result = getDerived().parseUnresolvedType();
3751
4
  if (Result == nullptr)
3752
0
    return nullptr;
3753
4
  return make<DtorName>(Result);
3754
4
}
3755
3756
// <unresolved-type> ::= <template-param>
3757
//                   ::= <decltype>
3758
//                   ::= <substitution>
3759
template <typename Derived, typename Alloc>
3760
4.14k
Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3761
4.14k
  if (look() == 'T') {
3762
0
    Node *TP = getDerived().parseTemplateParam();
3763
0
    if (TP == nullptr)
3764
0
      return nullptr;
3765
0
    Subs.push_back(TP);
3766
0
    return TP;
3767
0
  }
3768
4.14k
  if (look() == 'D') {
3769
0
    Node *DT = getDerived().parseDecltype();
3770
0
    if (DT == nullptr)
3771
0
      return nullptr;
3772
0
    Subs.push_back(DT);
3773
0
    return DT;
3774
0
  }
3775
4.14k
  return getDerived().parseSubstitution();
3776
4.14k
}
3777
3778
// <base-unresolved-name> ::= <simple-id>                                # unresolved name
3779
//          extension     ::= <operator-name>                            # unresolved operator-function-id
3780
//          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3781
//                        ::= on <operator-name>                         # unresolved operator-function-id
3782
//                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3783
//                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3784
//                                                                         # e.g. ~X or ~X<N-1>
3785
template <typename Derived, typename Alloc>
3786
15.6k
Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3787
15.6k
  if (std::isdigit(look()))
3788
11.5k
    return getDerived().parseSimpleId();
3789
3790
4.10k
  if (consumeIf("dn"))
3791
4
    return getDerived().parseDestructorName();
3792
3793
4.10k
  consumeIf("on");
3794
3795
4.10k
  Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3796
4.10k
  if (Oper == nullptr)
3797
3
    return nullptr;
3798
4.09k
  if (look() == 'I') {
3799
0
    Node *TA = getDerived().parseTemplateArgs();
3800
0
    if (TA == nullptr)
3801
0
      return nullptr;
3802
0
    return make<NameWithTemplateArgs>(Oper, TA);
3803
0
  }
3804
4.09k
  return Oper;
3805
4.09k
}
3806
3807
// <unresolved-name>
3808
//  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3809
//                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3810
//                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3811
//                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3812
// [gs] has been parsed by caller.
3813
//                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3814
//  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3815
//                                                                       # T::N::x /decltype(p)::N::x
3816
//  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3817
//
3818
// <unresolved-qualifier-level> ::= <simple-id>
3819
template <typename Derived, typename Alloc>
3820
15.6k
Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3821
15.6k
  Node *SoFar = nullptr;
3822
3823
  // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3824
  // srN <unresolved-type>                   <unresolved-qualifier-level>+ E <base-unresolved-name>
3825
15.6k
  if (consumeIf("srN")) {
3826
4.14k
    SoFar = getDerived().parseUnresolvedType();
3827
4.14k
    if (SoFar == nullptr)
3828
0
      return nullptr;
3829
3830
4.14k
    if (look() == 'I') {
3831
4.14k
      Node *TA = getDerived().parseTemplateArgs();
3832
4.14k
      if (TA == nullptr)
3833
53
        return nullptr;
3834
4.09k
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3835
4.09k
      if (!SoFar)
3836
0
        return nullptr;
3837
4.09k
    }
3838
3839
4.09k
    while (!consumeIf('E')) {
3840
0
      Node *Qual = getDerived().parseSimpleId();
3841
0
      if (Qual == nullptr)
3842
0
        return nullptr;
3843
0
      SoFar = make<QualifiedName>(SoFar, Qual);
3844
0
      if (!SoFar)
3845
0
        return nullptr;
3846
0
    }
3847
3848
4.09k
    Node *Base = getDerived().parseBaseUnresolvedName();
3849
4.09k
    if (Base == nullptr)
3850
0
      return nullptr;
3851
4.09k
    return make<QualifiedName>(SoFar, Base);
3852
4.09k
  }
3853
3854
  // [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3855
11.5k
  if (!consumeIf("sr")) {
3856
11.5k
    SoFar = getDerived().parseBaseUnresolvedName();
3857
11.5k
    if (SoFar == nullptr)
3858
3
      return nullptr;
3859
11.5k
    if (Global)
3860
907
      SoFar = make<GlobalQualifiedName>(SoFar);
3861
11.5k
    return SoFar;
3862
11.5k
  }
3863
3864
  // [gs] sr <unresolved-qualifier-level>+ E   <base-unresolved-name>
3865
3
  if (std::isdigit(look())) {
3866
3
    do {
3867
3
      Node *Qual = getDerived().parseSimpleId();
3868
3
      if (Qual == nullptr)
3869
0
        return nullptr;
3870
3
      if (SoFar)
3871
0
        SoFar = make<QualifiedName>(SoFar, Qual);
3872
3
      else if (Global)
3873
0
        SoFar = make<GlobalQualifiedName>(Qual);
3874
3
      else
3875
3
        SoFar = Qual;
3876
3
      if (!SoFar)
3877
0
        return nullptr;
3878
3
    } while (!consumeIf('E'));
3879
3
  }
3880
  //      sr <unresolved-type>                 <base-unresolved-name>
3881
  //      sr <unresolved-type> <template-args> <base-unresolved-name>
3882
0
  else {
3883
0
    SoFar = getDerived().parseUnresolvedType();
3884
0
    if (SoFar == nullptr)
3885
0
      return nullptr;
3886
3887
0
    if (look() == 'I') {
3888
0
      Node *TA = getDerived().parseTemplateArgs();
3889
0
      if (TA == nullptr)
3890
0
        return nullptr;
3891
0
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3892
0
      if (!SoFar)
3893
0
        return nullptr;
3894
0
    }
3895
0
  }
3896
3897
3
  DEMANGLE_ASSERT(SoFar != nullptr, "");
3898
3899
3
  Node *Base = getDerived().parseBaseUnresolvedName();
3900
3
  if (Base == nullptr)
3901
0
    return nullptr;
3902
3
  return make<QualifiedName>(SoFar, Base);
3903
3
}
3904
3905
// <abi-tags> ::= <abi-tag> [<abi-tags>]
3906
// <abi-tag> ::= B <source-name>
3907
template <typename Derived, typename Alloc>
3908
168k
Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3909
168k
  while (consumeIf('B')) {
3910
4
    std::string_view SN = parseBareSourceName();
3911
4
    if (SN.empty())
3912
0
      return nullptr;
3913
4
    N = make<AbiTagAttr>(N, SN);
3914
4
    if (!N)
3915
0
      return nullptr;
3916
4
  }
3917
168k
  return N;
3918
168k
}
3919
3920
// <number> ::= [n] <non-negative decimal integer>
3921
template <typename Alloc, typename Derived>
3922
std::string_view
3923
60.4k
AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3924
60.4k
  const char *Tmp = First;
3925
60.4k
  if (AllowNegative)
3926
1.18k
    consumeIf('n');
3927
60.4k
  if (numLeft() == 0 || !std::isdigit(*First))
3928
257
    return std::string_view();
3929
120k
  while (numLeft() != 0 && std::isdigit(*First))
3930
60.4k
    ++First;
3931
60.2k
  return std::string_view(Tmp, First - Tmp);
3932
60.4k
}
3933
3934
// <positive length number> ::= [0-9]*
3935
template <typename Alloc, typename Derived>
3936
59.1k
bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3937
59.1k
  *Out = 0;
3938
59.1k
  if (look() < '0' || look() > '9')
3939
2
    return true;
3940
126k
  while (look() >= '0' && look() <= '9') {
3941
67.0k
    *Out *= 10;
3942
67.0k
    *Out += static_cast<size_t>(consume() - '0');
3943
67.0k
  }
3944
59.1k
  return false;
3945
59.1k
}
3946
3947
template <typename Alloc, typename Derived>
3948
5.17k
std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3949
5.17k
  size_t Int = 0;
3950
5.17k
  if (parsePositiveInteger(&Int) || numLeft() < Int)
3951
1
    return {};
3952
5.17k
  std::string_view R(First, Int);
3953
5.17k
  First += Int;
3954
5.17k
  return R;
3955
5.17k
}
3956
3957
// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3958
//
3959
// <exception-spec> ::= Do                # non-throwing exception-specification (e.g., noexcept, throw())
3960
//                  ::= DO <expression> E # computed (instantiation-dependent) noexcept
3961
//                  ::= Dw <type>+ E      # dynamic exception specification with instantiation-dependent types
3962
//
3963
// <ref-qualifier> ::= R                   # & ref-qualifier
3964
// <ref-qualifier> ::= O                   # && ref-qualifier
3965
template <typename Derived, typename Alloc>
3966
34.5k
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3967
34.5k
  Qualifiers CVQuals = parseCVQualifiers();
3968
3969
34.5k
  Node *ExceptionSpec = nullptr;
3970
34.5k
  if (consumeIf("Do")) {
3971
103
    ExceptionSpec = make<NameType>("noexcept");
3972
103
    if (!ExceptionSpec)
3973
0
      return nullptr;
3974
34.4k
  } else if (consumeIf("DO")) {
3975
107
    Node *E = getDerived().parseExpr();
3976
107
    if (E == nullptr || !consumeIf('E'))
3977
0
      return nullptr;
3978
107
    ExceptionSpec = make<NoexceptSpec>(E);
3979
107
    if (!ExceptionSpec)
3980
0
      return nullptr;
3981
34.3k
  } else if (consumeIf("Dw")) {
3982
36
    size_t SpecsBegin = Names.size();
3983
333
    while (!consumeIf('E')) {
3984
333
      Node *T = getDerived().parseType();
3985
333
      if (T == nullptr)
3986
36
        return nullptr;
3987
297
      Names.push_back(T);
3988
297
    }
3989
0
    ExceptionSpec =
3990
0
      make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3991
0
    if (!ExceptionSpec)
3992
0
      return nullptr;
3993
0
  }
3994
3995
34.5k
  consumeIf("Dx"); // transaction safe
3996
3997
34.5k
  if (!consumeIf('F'))
3998
0
    return nullptr;
3999
34.5k
  consumeIf('Y'); // extern "C"
4000
34.5k
  Node *ReturnType = getDerived().parseType();
4001
34.5k
  if (ReturnType == nullptr)
4002
403
    return nullptr;
4003
4004
34.1k
  FunctionRefQual ReferenceQualifier = FrefQualNone;
4005
34.1k
  size_t ParamsBegin = Names.size();
4006
874k
  while (true) {
4007
874k
    if (consumeIf('E'))
4008
13.0k
      break;
4009
861k
    if (consumeIf('v'))
4010
396
      continue;
4011
860k
    if (consumeIf("RE")) {
4012
15
      ReferenceQualifier = FrefQualLValue;
4013
15
      break;
4014
15
    }
4015
860k
    if (consumeIf("OE")) {
4016
13.9k
      ReferenceQualifier = FrefQualRValue;
4017
13.9k
      break;
4018
13.9k
    }
4019
846k
    Node *T = getDerived().parseType();
4020
846k
    if (T == nullptr)
4021
7.12k
      return nullptr;
4022
839k
    Names.push_back(T);
4023
839k
  }
4024
4025
26.9k
  NodeArray Params = popTrailingNodeArray(ParamsBegin);
4026
26.9k
  return make<FunctionType>(ReturnType, Params, CVQuals,
4027
26.9k
                            ReferenceQualifier, ExceptionSpec);
4028
34.1k
}
4029
4030
// extension:
4031
// <vector-type>           ::= Dv <positive dimension number> _ <extended element type>
4032
//                         ::= Dv [<dimension expression>] _ <element type>
4033
// <extended element type> ::= <element type>
4034
//                         ::= p # AltiVec vector pixel
4035
template <typename Derived, typename Alloc>
4036
64.8k
Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
4037
64.8k
  if (!consumeIf("Dv"))
4038
0
    return nullptr;
4039
64.8k
  if (look() >= '1' && look() <= '9') {
4040
54.2k
    Node *DimensionNumber = make<NameType>(parseNumber());
4041
54.2k
    if (!DimensionNumber)
4042
0
      return nullptr;
4043
54.2k
    if (!consumeIf('_'))
4044
0
      return nullptr;
4045
54.2k
    if (consumeIf('p'))
4046
24.0k
      return make<PixelVectorType>(DimensionNumber);
4047
30.2k
    Node *ElemType = getDerived().parseType();
4048
30.2k
    if (ElemType == nullptr)
4049
0
      return nullptr;
4050
30.2k
    return make<VectorType>(ElemType, DimensionNumber);
4051
30.2k
  }
4052
4053
10.5k
  if (!consumeIf('_')) {
4054
10.4k
    Node *DimExpr = getDerived().parseExpr();
4055
10.4k
    if (!DimExpr)
4056
3
      return nullptr;
4057
10.4k
    if (!consumeIf('_'))
4058
0
      return nullptr;
4059
10.4k
    Node *ElemType = getDerived().parseType();
4060
10.4k
    if (!ElemType)
4061
1
      return nullptr;
4062
10.4k
    return make<VectorType>(ElemType, DimExpr);
4063
10.4k
  }
4064
74
  Node *ElemType = getDerived().parseType();
4065
74
  if (!ElemType)
4066
0
    return nullptr;
4067
74
  return make<VectorType>(ElemType, /*Dimension=*/nullptr);
4068
74
}
4069
4070
// <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
4071
//             ::= DT <expression> E  # decltype of an expression (C++0x)
4072
template <typename Derived, typename Alloc>
4073
969
Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
4074
969
  if (!consumeIf('D'))
4075
0
    return nullptr;
4076
969
  if (!consumeIf('t') && !consumeIf('T'))
4077
0
    return nullptr;
4078
969
  Node *E = getDerived().parseExpr();
4079
969
  if (E == nullptr)
4080
965
    return nullptr;
4081
4
  if (!consumeIf('E'))
4082
0
    return nullptr;
4083
4
  return make<EnclosingExpr>("decltype", E);
4084
4
}
4085
4086
// <array-type> ::= A <positive dimension number> _ <element type>
4087
//              ::= A [<dimension expression>] _ <element type>
4088
template <typename Derived, typename Alloc>
4089
11.2k
Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
4090
11.2k
  if (!consumeIf('A'))
4091
0
    return nullptr;
4092
4093
11.2k
  Node *Dimension = nullptr;
4094
4095
11.2k
  if (std::isdigit(look())) {
4096
0
    Dimension = make<NameType>(parseNumber());
4097
0
    if (!Dimension)
4098
0
      return nullptr;
4099
0
    if (!consumeIf('_'))
4100
0
      return nullptr;
4101
11.2k
  } else if (!consumeIf('_')) {
4102
9.60k
    Node *DimExpr = getDerived().parseExpr();
4103
9.60k
    if (DimExpr == nullptr)
4104
3.89k
      return nullptr;
4105
5.70k
    if (!consumeIf('_'))
4106
0
      return nullptr;
4107
5.70k
    Dimension = DimExpr;
4108
5.70k
  }
4109
4110
7.38k
  Node *Ty = getDerived().parseType();
4111
7.38k
  if (Ty == nullptr)
4112
0
    return nullptr;
4113
7.38k
  return make<ArrayType>(Ty, Dimension);
4114
7.38k
}
4115
4116
// <pointer-to-member-type> ::= M <class type> <member type>
4117
template <typename Derived, typename Alloc>
4118
3.00k
Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
4119
3.00k
  if (!consumeIf('M'))
4120
0
    return nullptr;
4121
3.00k
  Node *ClassType = getDerived().parseType();
4122
3.00k
  if (ClassType == nullptr)
4123
0
    return nullptr;
4124
3.00k
  Node *MemberType = getDerived().parseType();
4125
3.00k
  if (MemberType == nullptr)
4126
0
    return nullptr;
4127
3.00k
  return make<PointerToMemberType>(ClassType, MemberType);
4128
3.00k
}
4129
4130
// <class-enum-type> ::= <name>     # non-dependent type name, dependent type name, or dependent typename-specifier
4131
//                   ::= Ts <name>  # dependent elaborated type specifier using 'struct' or 'class'
4132
//                   ::= Tu <name>  # dependent elaborated type specifier using 'union'
4133
//                   ::= Te <name>  # dependent elaborated type specifier using 'enum'
4134
template <typename Derived, typename Alloc>
4135
155k
Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
4136
155k
  std::string_view ElabSpef;
4137
155k
  if (consumeIf("Ts"))
4138
0
    ElabSpef = "struct";
4139
155k
  else if (consumeIf("Tu"))
4140
13
    ElabSpef = "union";
4141
155k
  else if (consumeIf("Te"))
4142
56
    ElabSpef = "enum";
4143
4144
155k
  Node *Name = getDerived().parseName();
4145
155k
  if (Name == nullptr)
4146
10.3k
    return nullptr;
4147
4148
145k
  if (!ElabSpef.empty())
4149
69
    return make<ElaboratedTypeSpefType>(ElabSpef, Name);
4150
4151
145k
  return Name;
4152
145k
}
4153
4154
// <qualified-type>     ::= <qualifiers> <type>
4155
// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
4156
// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
4157
template <typename Derived, typename Alloc>
4158
385k
Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
4159
385k
  if (consumeIf('U')) {
4160
4.99k
    std::string_view Qual = parseBareSourceName();
4161
4.99k
    if (Qual.empty())
4162
1
      return nullptr;
4163
4164
    // extension            ::= U <objc-name> <objc-type>  # objc-type<identifier>
4165
4.99k
    if (starts_with(Qual, "objcproto")) {
4166
3
      constexpr size_t Len = sizeof("objcproto") - 1;
4167
3
      std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4168
3
      std::string_view Proto;
4169
3
      {
4170
3
        ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4171
3
            SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4172
3
        Proto = parseBareSourceName();
4173
3
      }
4174
3
      if (Proto.empty())
4175
0
        return nullptr;
4176
3
      Node *Child = getDerived().parseQualifiedType();
4177
3
      if (Child == nullptr)
4178
0
        return nullptr;
4179
3
      return make<ObjCProtoName>(Child, Proto);
4180
3
    }
4181
4182
4.98k
    Node *TA = nullptr;
4183
4.98k
    if (look() == 'I') {
4184
0
      TA = getDerived().parseTemplateArgs();
4185
0
      if (TA == nullptr)
4186
0
        return nullptr;
4187
0
    }
4188
4189
4.98k
    Node *Child = getDerived().parseQualifiedType();
4190
4.98k
    if (Child == nullptr)
4191
965
      return nullptr;
4192
4.02k
    return make<VendorExtQualType>(Child, Qual, TA);
4193
4.98k
  }
4194
4195
380k
  Qualifiers Quals = parseCVQualifiers();
4196
380k
  Node *Ty = getDerived().parseType();
4197
380k
  if (Ty == nullptr)
4198
1.02k
    return nullptr;
4199
379k
  if (Quals != QualNone)
4200
376k
    Ty = make<QualType>(Ty, Quals);
4201
379k
  return Ty;
4202
380k
}
4203
4204
// <type>      ::= <builtin-type>
4205
//             ::= <qualified-type>
4206
//             ::= <function-type>
4207
//             ::= <class-enum-type>
4208
//             ::= <array-type>
4209
//             ::= <pointer-to-member-type>
4210
//             ::= <template-param>
4211
//             ::= <template-template-param> <template-args>
4212
//             ::= <decltype>
4213
//             ::= P <type>        # pointer
4214
//             ::= R <type>        # l-value reference
4215
//             ::= O <type>        # r-value reference (C++11)
4216
//             ::= C <type>        # complex pair (C99)
4217
//             ::= G <type>        # imaginary (C99)
4218
//             ::= <substitution>  # See Compression below
4219
// extension   ::= U <objc-name> <objc-type>  # objc-type<identifier>
4220
// extension   ::= <vector-type> # <vector-type> starts with Dv
4221
//
4222
// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
4223
// <objc-type> ::= <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4224
template <typename Derived, typename Alloc>
4225
3.38M
Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4226
3.38M
  Node *Result = nullptr;
4227
4228
3.38M
  switch (look()) {
4229
  //             ::= <qualified-type>
4230
312k
  case 'r':
4231
352k
  case 'V':
4232
381k
  case 'K': {
4233
381k
    unsigned AfterQuals = 0;
4234
381k
    if (look(AfterQuals) == 'r') ++AfterQuals;
4235
381k
    if (look(AfterQuals) == 'V') ++AfterQuals;
4236
381k
    if (look(AfterQuals) == 'K') ++AfterQuals;
4237
4238
381k
    if (look(AfterQuals) == 'F' ||
4239
375k
        (look(AfterQuals) == 'D' &&
4240
6.56k
         (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
4241
6.55k
          look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
4242
5.57k
      Result = getDerived().parseFunctionType();
4243
5.57k
      break;
4244
5.57k
    }
4245
375k
    DEMANGLE_FALLTHROUGH;
4246
375k
  }
4247
380k
  case 'U': {
4248
380k
    Result = getDerived().parseQualifiedType();
4249
380k
    break;
4250
375k
  }
4251
  // <builtin-type> ::= v    # void
4252
2.38k
  case 'v':
4253
2.38k
    ++First;
4254
2.38k
    return make<NameType>("void");
4255
  //                ::= w    # wchar_t
4256
87.0k
  case 'w':
4257
87.0k
    ++First;
4258
87.0k
    return make<NameType>("wchar_t");
4259
  //                ::= b    # bool
4260
133k
  case 'b':
4261
133k
    ++First;
4262
133k
    return make<NameType>("bool");
4263
  //                ::= c    # char
4264
98.0k
  case 'c':
4265
98.0k
    ++First;
4266
98.0k
    return make<NameType>("char");
4267
  //                ::= a    # signed char
4268
15.4k
  case 'a':
4269
15.4k
    ++First;
4270
15.4k
    return make<NameType>("signed char");
4271
  //                ::= h    # unsigned char
4272
30.3k
  case 'h':
4273
30.3k
    ++First;
4274
30.3k
    return make<NameType>("unsigned char");
4275
  //                ::= s    # short
4276
157k
  case 's':
4277
157k
    ++First;
4278
157k
    return make<NameType>("short");
4279
  //                ::= t    # unsigned short
4280
191k
  case 't':
4281
191k
    ++First;
4282
191k
    return make<NameType>("unsigned short");
4283
  //                ::= i    # int
4284
139k
  case 'i':
4285
139k
    ++First;
4286
139k
    return make<NameType>("int");
4287
  //                ::= j    # unsigned int
4288
432k
  case 'j':
4289
432k
    ++First;
4290
432k
    return make<NameType>("unsigned int");
4291
  //                ::= l    # long
4292
99.0k
  case 'l':
4293
99.0k
    ++First;
4294
99.0k
    return make<NameType>("long");
4295
  //                ::= m    # unsigned long
4296
183k
  case 'm':
4297
183k
    ++First;
4298
183k
    return make<NameType>("unsigned long");
4299
  //                ::= x    # long long, __int64
4300
32.4k
  case 'x':
4301
32.4k
    ++First;
4302
32.4k
    return make<NameType>("long long");
4303
  //                ::= y    # unsigned long long, __int64
4304
27.1k
  case 'y':
4305
27.1k
    ++First;
4306
27.1k
    return make<NameType>("unsigned long long");
4307
  //                ::= n    # __int128
4308
149k
  case 'n':
4309
149k
    ++First;
4310
149k
    return make<NameType>("__int128");
4311
  //                ::= o    # unsigned __int128
4312
59.8k
  case 'o':
4313
59.8k
    ++First;
4314
59.8k
    return make<NameType>("unsigned __int128");
4315
  //                ::= f    # float
4316
35.9k
  case 'f':
4317
35.9k
    ++First;
4318
35.9k
    return make<NameType>("float");
4319
  //                ::= d    # double
4320
60.4k
  case 'd':
4321
60.4k
    ++First;
4322
60.4k
    return make<NameType>("double");
4323
  //                ::= e    # long double, __float80
4324
28.8k
  case 'e':
4325
28.8k
    ++First;
4326
28.8k
    return make<NameType>("long double");
4327
  //                ::= g    # __float128
4328
338k
  case 'g':
4329
338k
    ++First;
4330
338k
    return make<NameType>("__float128");
4331
  //                ::= z    # ellipsis
4332
156k
  case 'z':
4333
156k
    ++First;
4334
156k
    return make<NameType>("...");
4335
4336
  // <builtin-type> ::= u <source-name>    # vendor extended type
4337
179
  case 'u': {
4338
179
    ++First;
4339
179
    std::string_view Res = parseBareSourceName();
4340
179
    if (Res.empty())
4341
0
      return nullptr;
4342
    // Typically, <builtin-type>s are not considered substitution candidates,
4343
    // but the exception to that exception is vendor extended types (Itanium C++
4344
    // ABI 5.9.1).
4345
179
    if (consumeIf('I')) {
4346
0
      Node *BaseType = parseType();
4347
0
      if (BaseType == nullptr)
4348
0
        return nullptr;
4349
0
      if (!consumeIf('E'))
4350
0
        return nullptr;
4351
0
      Result = make<TransformedType>(Res, BaseType);
4352
0
    } else
4353
179
      Result = make<NameType>(Res);
4354
179
    break;
4355
179
  }
4356
132k
  case 'D':
4357
132k
    switch (look(1)) {
4358
    //                ::= Dd   # IEEE 754r decimal floating point (64 bits)
4359
221
    case 'd':
4360
221
      First += 2;
4361
221
      return make<NameType>("decimal64");
4362
    //                ::= De   # IEEE 754r decimal floating point (128 bits)
4363
3
    case 'e':
4364
3
      First += 2;
4365
3
      return make<NameType>("decimal128");
4366
    //                ::= Df   # IEEE 754r decimal floating point (32 bits)
4367
1.65k
    case 'f':
4368
1.65k
      First += 2;
4369
1.65k
      return make<NameType>("decimal32");
4370
    //                ::= Dh   # IEEE 754r half-precision floating point (16 bits)
4371
0
    case 'h':
4372
0
      First += 2;
4373
0
      return make<NameType>("half");
4374
    //       ::= DF16b         # C++23 std::bfloat16_t
4375
    //       ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4376
1.61k
    case 'F': {
4377
1.61k
      First += 2;
4378
1.61k
      if (consumeIf("16b"))
4379
0
        return make<NameType>("std::bfloat16_t");
4380
1.61k
      Node *DimensionNumber = make<NameType>(parseNumber());
4381
1.61k
      if (!DimensionNumber)
4382
0
        return nullptr;
4383
1.61k
      if (!consumeIf('_'))
4384
0
        return nullptr;
4385
1.61k
      return make<BinaryFPType>(DimensionNumber);
4386
1.61k
    }
4387
    //                ::= [DS] DA  # N1169 fixed-point [_Sat] T _Accum
4388
    //                ::= [DS] DR  # N1169 fixed-point [_Sat] T _Frac
4389
    // <fixed-point-size>
4390
    //                ::= s # short
4391
    //                ::= t # unsigned short
4392
    //                ::= i # plain
4393
    //                ::= j # unsigned
4394
    //                ::= l # long
4395
    //                ::= m # unsigned long
4396
1.88k
    case 'A': {
4397
1.88k
      char c = look(2);
4398
1.88k
      First += 3;
4399
1.88k
      switch (c) {
4400
0
      case 's':
4401
0
        return make<NameType>("short _Accum");
4402
0
      case 't':
4403
0
        return make<NameType>("unsigned short _Accum");
4404
0
      case 'i':
4405
0
        return make<NameType>("_Accum");
4406
0
      case 'j':
4407
0
        return make<NameType>("unsigned _Accum");
4408
0
      case 'l':
4409
0
        return make<NameType>("long _Accum");
4410
1.88k
      case 'm':
4411
1.88k
        return make<NameType>("unsigned long _Accum");
4412
0
      default:
4413
0
        return nullptr;
4414
1.88k
      }
4415
1.88k
    }
4416
31.3k
    case 'R': {
4417
31.3k
      char c = look(2);
4418
31.3k
      First += 3;
4419
31.3k
      switch (c) {
4420
10.1k
      case 's':
4421
10.1k
        return make<NameType>("short _Fract");
4422
21.1k
      case 't':
4423
21.1k
        return make<NameType>("unsigned short _Fract");
4424
0
      case 'i':
4425
0
        return make<NameType>("_Fract");
4426
0
      case 'j':
4427
0
        return make<NameType>("unsigned _Fract");
4428
0
      case 'l':
4429
0
        return make<NameType>("long _Fract");
4430
5
      case 'm':
4431
5
        return make<NameType>("unsigned long _Fract");
4432
0
      default:
4433
0
        return nullptr;
4434
31.3k
      }
4435
31.3k
    }
4436
661
    case 'S': {
4437
661
      First += 2;
4438
661
      if (look() != 'D')
4439
0
        return nullptr;
4440
661
      if (look(1) == 'A') {
4441
618
        char c = look(2);
4442
618
        First += 3;
4443
618
        switch (c) {
4444
0
        case 's':
4445
0
          return make<NameType>("_Sat short _Accum");
4446
419
        case 't':
4447
419
          return make<NameType>("_Sat unsigned short _Accum");
4448
151
        case 'i':
4449
151
          return make<NameType>("_Sat _Accum");
4450
0
        case 'j':
4451
0
          return make<NameType>("_Sat unsigned _Accum");
4452
0
        case 'l':
4453
0
          return make<NameType>("_Sat long _Accum");
4454
48
        case 'm':
4455
48
          return make<NameType>("_Sat unsigned long _Accum");
4456
0
        default:
4457
0
          return nullptr;
4458
618
        }
4459
618
      }
4460
43
      if (look(1) == 'R') {
4461
43
        char c = look(2);
4462
43
        First += 3;
4463
43
        switch (c) {
4464
10
        case 's':
4465
10
          return make<NameType>("_Sat short _Fract");
4466
0
        case 't':
4467
0
          return make<NameType>("_Sat unsigned short _Fract");
4468
0
        case 'i':
4469
0
          return make<NameType>("_Sat _Fract");
4470
0
        case 'j':
4471
0
          return make<NameType>("_Sat unsigned _Fract");
4472
17
        case 'l':
4473
17
          return make<NameType>("_Sat long _Fract");
4474
16
        case 'm':
4475
16
          return make<NameType>("_Sat unsigned long _Fract");
4476
0
        default:
4477
0
          return nullptr;
4478
43
        }
4479
43
      }
4480
0
      return nullptr;
4481
43
    }
4482
    //                ::= DB <number> _                             # C23 signed _BitInt(N)
4483
    //                ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4484
    //                ::= DU <number> _                             # C23 unsigned _BitInt(N)
4485
    //                ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4486
1.87k
    case 'B':
4487
1.87k
    case 'U': {
4488
1.87k
      bool Signed = look(1) == 'B';
4489
1.87k
      First += 2;
4490
1.87k
      Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4491
1.87k
                                        : getDerived().parseExpr();
4492
1.87k
      if (!Size)
4493
0
        return nullptr;
4494
1.87k
      if (!consumeIf('_'))
4495
0
        return nullptr;
4496
      // The front end expects this to be available for Substitution
4497
1.87k
      Result = make<BitIntType>(Size, Signed);
4498
1.87k
      break;
4499
1.87k
    }
4500
    //                ::= Di   # char32_t
4501
8.52k
    case 'i':
4502
8.52k
      First += 2;
4503
8.52k
      return make<NameType>("char32_t");
4504
    //                ::= Ds   # char16_t
4505
0
    case 's':
4506
0
      First += 2;
4507
0
      return make<NameType>("char16_t");
4508
    //                ::= Du   # char8_t (C++2a, not yet in the Itanium spec)
4509
1
    case 'u':
4510
1
      First += 2;
4511
1
      return make<NameType>("char8_t");
4512
    //                ::= Da   # auto (in dependent new-expressions)
4513
2.77k
    case 'a':
4514
2.77k
      First += 2;
4515
2.77k
      return make<NameType>("auto");
4516
    //                ::= Dc   # decltype(auto)
4517
1
    case 'c':
4518
1
      First += 2;
4519
1
      return make<NameType>("decltype(auto)");
4520
    //                ::= Dk <type-constraint> # constrained auto
4521
    //                ::= DK <type-constraint> # constrained decltype(auto)
4522
0
    case 'k':
4523
124
    case 'K': {
4524
124
      std::string_view Kind = look(1) == 'k' ? " auto" : " decltype(auto)";
4525
124
      First += 2;
4526
124
      Node *Constraint = getDerived().parseName();
4527
124
      if (!Constraint)
4528
21
        return nullptr;
4529
103
      return make<PostfixQualifiedType>(Constraint, Kind);
4530
124
    }
4531
    //                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))
4532
1.22k
    case 'n':
4533
1.22k
      First += 2;
4534
1.22k
      return make<NameType>("std::nullptr_t");
4535
4536
    //             ::= <decltype>
4537
0
    case 't':
4538
969
    case 'T': {
4539
969
      Result = getDerived().parseDecltype();
4540
969
      break;
4541
0
    }
4542
    // extension   ::= <vector-type> # <vector-type> starts with Dv
4543
64.8k
    case 'v': {
4544
64.8k
      Result = getDerived().parseVectorType();
4545
64.8k
      break;
4546
0
    }
4547
    //           ::= Dp <type>       # pack expansion (C++0x)
4548
14.9k
    case 'p': {
4549
14.9k
      First += 2;
4550
14.9k
      Node *Child = getDerived().parseType();
4551
14.9k
      if (!Child)
4552
5
        return nullptr;
4553
14.9k
      Result = make<ParameterPackExpansion>(Child);
4554
14.9k
      break;
4555
14.9k
    }
4556
    //           ::= Dy <type> <expression> # pack indexing (C++26)
4557
0
    case 'y': {
4558
0
      First += 2;
4559
0
      Node *Pattern = getDerived().parseType();
4560
0
      if (!Pattern)
4561
0
        return nullptr;
4562
0
      Node *Index = getDerived().parseExpr();
4563
0
      if (!Index)
4564
0
        return nullptr;
4565
0
      Result = make<PackIndexing>(Pattern, Index);
4566
0
      break;
4567
0
    }
4568
    // Exception specifier on a function type.
4569
103
    case 'o':
4570
206
    case 'O':
4571
242
    case 'w':
4572
    // Transaction safe function type.
4573
242
    case 'x':
4574
242
      Result = getDerived().parseFunctionType();
4575
242
      break;
4576
132k
    }
4577
82.8k
    break;
4578
  //             ::= <function-type>
4579
82.8k
  case 'F': {
4580
28.7k
    Result = getDerived().parseFunctionType();
4581
28.7k
    break;
4582
132k
  }
4583
  //             ::= <array-type>
4584
11.2k
  case 'A': {
4585
11.2k
    Result = getDerived().parseArrayType();
4586
11.2k
    break;
4587
132k
  }
4588
  //             ::= <pointer-to-member-type>
4589
3.00k
  case 'M': {
4590
3.00k
    Result = getDerived().parsePointerToMemberType();
4591
3.00k
    break;
4592
132k
  }
4593
  //             ::= <template-param>
4594
25.3k
  case 'T': {
4595
    // This could be an elaborate type specifier on a <class-enum-type>.
4596
25.3k
    if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
4597
69
      Result = getDerived().parseClassEnumType();
4598
69
      break;
4599
69
    }
4600
4601
25.3k
    Result = getDerived().parseTemplateParam();
4602
25.3k
    if (Result == nullptr)
4603
0
      return nullptr;
4604
4605
    // Result could be either of:
4606
    //   <type>        ::= <template-param>
4607
    //   <type>        ::= <template-template-param> <template-args>
4608
    //
4609
    //   <template-template-param> ::= <template-param>
4610
    //                             ::= <substitution>
4611
    //
4612
    // If this is followed by some <template-args>, and we're permitted to
4613
    // parse them, take the second production.
4614
4615
25.3k
    if (TryToParseTemplateArgs && look() == 'I') {
4616
16.8k
      Subs.push_back(Result);
4617
16.8k
      Node *TA = getDerived().parseTemplateArgs();
4618
16.8k
      if (TA == nullptr)
4619
8.05k
        return nullptr;
4620
8.75k
      Result = make<NameWithTemplateArgs>(Result, TA);
4621
8.75k
    }
4622
17.2k
    break;
4623
25.3k
  }
4624
  //             ::= P <type>        # pointer
4625
76.7k
  case 'P': {
4626
76.7k
    ++First;
4627
76.7k
    Node *Ptr = getDerived().parseType();
4628
76.7k
    if (Ptr == nullptr)
4629
0
      return nullptr;
4630
76.7k
    Result = make<PointerType>(Ptr);
4631
76.7k
    break;
4632
76.7k
  }
4633
  //             ::= R <type>        # l-value reference
4634
66.0k
  case 'R': {
4635
66.0k
    ++First;
4636
66.0k
    Node *Ref = getDerived().parseType();
4637
66.0k
    if (Ref == nullptr)
4638
4.86k
      return nullptr;
4639
61.1k
    Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4640
61.1k
    break;
4641
66.0k
  }
4642
  //             ::= O <type>        # r-value reference (C++11)
4643
14.8k
  case 'O': {
4644
14.8k
    ++First;
4645
14.8k
    Node *Ref = getDerived().parseType();
4646
14.8k
    if (Ref == nullptr)
4647
78
      return nullptr;
4648
14.7k
    Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4649
14.7k
    break;
4650
14.8k
  }
4651
  //             ::= C <type>        # complex pair (C99)
4652
376
  case 'C': {
4653
376
    ++First;
4654
376
    Node *P = getDerived().parseType();
4655
376
    if (P == nullptr)
4656
65
      return nullptr;
4657
311
    Result = make<PostfixQualifiedType>(P, " complex");
4658
311
    break;
4659
376
  }
4660
  //             ::= G <type>        # imaginary (C99)
4661
13.1k
  case 'G': {
4662
13.1k
    ++First;
4663
13.1k
    Node *P = getDerived().parseType();
4664
13.1k
    if (P == nullptr)
4665
0
      return P;
4666
13.1k
    Result = make<PostfixQualifiedType>(P, " imaginary");
4667
13.1k
    break;
4668
13.1k
  }
4669
  //             ::= <substitution>  # See Compression below
4670
18.3k
  case 'S': {
4671
18.3k
    if (look(1) != 't') {
4672
14.4k
      bool IsSubst = false;
4673
14.4k
      Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4674
14.4k
      if (!Result)
4675
0
        return nullptr;
4676
4677
      // Sub could be either of:
4678
      //   <type>        ::= <substitution>
4679
      //   <type>        ::= <template-template-param> <template-args>
4680
      //
4681
      //   <template-template-param> ::= <template-param>
4682
      //                             ::= <substitution>
4683
      //
4684
      // If this is followed by some <template-args>, and we're permitted to
4685
      // parse them, take the second production.
4686
4687
14.4k
      if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4688
0
        if (!IsSubst)
4689
0
          Subs.push_back(Result);
4690
0
        Node *TA = getDerived().parseTemplateArgs();
4691
0
        if (TA == nullptr)
4692
0
          return nullptr;
4693
0
        Result = make<NameWithTemplateArgs>(Result, TA);
4694
14.4k
      } else if (IsSubst) {
4695
        // If all we parsed was a substitution, don't re-insert into the
4696
        // substitution table.
4697
14.4k
        return Result;
4698
14.4k
      }
4699
0
      break;
4700
14.4k
    }
4701
3.91k
    DEMANGLE_FALLTHROUGH;
4702
3.91k
  }
4703
  //        ::= <class-enum-type>
4704
155k
  default: {
4705
155k
    Result = getDerived().parseClassEnumType();
4706
155k
    break;
4707
3.91k
  }
4708
3.38M
  }
4709
4710
  // If we parsed a type, insert it into the substitution table. Note that all
4711
  // <builtin-type>s and <substitution>s have already bailed out, because they
4712
  // don't get substitutions.
4713
851k
  if (Result != nullptr)
4714
827k
    Subs.push_back(Result);
4715
851k
  return Result;
4716
3.38M
}
4717
4718
template <typename Derived, typename Alloc>
4719
Node *
4720
AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4721
10.4k
                                                        Node::Prec Prec) {
4722
10.4k
  Node *E = getDerived().parseExpr();
4723
10.4k
  if (E == nullptr)
4724
0
    return nullptr;
4725
10.4k
  return make<PrefixExpr>(Kind, E, Prec);
4726
10.4k
}
4727
4728
template <typename Derived, typename Alloc>
4729
Node *
4730
AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4731
0
                                                        Node::Prec Prec) {
4732
0
  Node *LHS = getDerived().parseExpr();
4733
0
  if (LHS == nullptr)
4734
0
    return nullptr;
4735
0
  Node *RHS = getDerived().parseExpr();
4736
0
  if (RHS == nullptr)
4737
0
    return nullptr;
4738
0
  return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4739
0
}
4740
4741
template <typename Derived, typename Alloc>
4742
Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4743
124
    std::string_view Lit) {
4744
124
  std::string_view Tmp = parseNumber(true);
4745
124
  if (!Tmp.empty() && consumeIf('E'))
4746
124
    return make<IntegerLiteral>(Lit, Tmp);
4747
0
  return nullptr;
4748
124
}
4749
4750
// <CV-Qualifiers> ::= [r] [V] [K]
4751
template <typename Alloc, typename Derived>
4752
415k
Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4753
415k
  Qualifiers CVR = QualNone;
4754
415k
  if (consumeIf('r'))
4755
312k
    CVR |= QualRestrict;
4756
415k
  if (consumeIf('V'))
4757
40.9k
    CVR |= QualVolatile;
4758
415k
  if (consumeIf('K'))
4759
28.7k
    CVR |= QualConst;
4760
415k
  return CVR;
4761
415k
}
4762
4763
// <function-param> ::= fp <top-level CV-Qualifiers> _                                     # L == 0, first parameter
4764
//                  ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
4765
//                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _         # L > 0, first parameter
4766
//                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
4767
//                  ::= fpT      # 'this' expression (not part of standard?)
4768
template <typename Derived, typename Alloc>
4769
14
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4770
14
  if (consumeIf("fpT"))
4771
11
    return make<NameType>("this");
4772
3
  if (consumeIf("fp")) {
4773
3
    parseCVQualifiers();
4774
3
    std::string_view Num = parseNumber();
4775
3
    if (!consumeIf('_'))
4776
0
      return nullptr;
4777
3
    return make<FunctionParam>(Num);
4778
3
  }
4779
0
  if (consumeIf("fL")) {
4780
0
    if (parseNumber().empty())
4781
0
      return nullptr;
4782
0
    if (!consumeIf('p'))
4783
0
      return nullptr;
4784
0
    parseCVQualifiers();
4785
0
    std::string_view Num = parseNumber();
4786
0
    if (!consumeIf('_'))
4787
0
      return nullptr;
4788
0
    return make<FunctionParam>(Num);
4789
0
  }
4790
0
  return nullptr;
4791
0
}
4792
4793
// cv <type> <expression>                               # conversion with one argument
4794
// cv <type> _ <expression>* E                          # conversion with a different number of arguments
4795
template <typename Derived, typename Alloc>
4796
Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4797
  if (!consumeIf("cv"))
4798
    return nullptr;
4799
  Node *Ty;
4800
  {
4801
    ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4802
    Ty = getDerived().parseType();
4803
  }
4804
4805
  if (Ty == nullptr)
4806
    return nullptr;
4807
4808
  if (consumeIf('_')) {
4809
    size_t ExprsBegin = Names.size();
4810
    while (!consumeIf('E')) {
4811
      Node *E = getDerived().parseExpr();
4812
      if (E == nullptr)
4813
        return E;
4814
      Names.push_back(E);
4815
    }
4816
    NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4817
    return make<ConversionExpr>(Ty, Exprs);
4818
  }
4819
4820
  Node *E[1] = {getDerived().parseExpr()};
4821
  if (E[0] == nullptr)
4822
    return nullptr;
4823
  return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4824
}
4825
4826
// <expr-primary> ::= L <type> <value number> E                          # integer literal
4827
//                ::= L <type> <value float> E                           # floating literal
4828
//                ::= L <string type> E                                  # string literal
4829
//                ::= L <nullptr type> E                                 # nullptr literal (i.e., "LDnE")
4830
//                ::= L <lambda type> E                                  # lambda expression
4831
// FIXME:         ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)
4832
//                ::= L <mangled-name> E                                 # external name
4833
template <typename Derived, typename Alloc>
4834
4.23k
Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4835
4.23k
  if (!consumeIf('L'))
4836
0
    return nullptr;
4837
4.23k
  switch (look()) {
4838
0
  case 'w':
4839
0
    ++First;
4840
0
    return getDerived().parseIntegerLiteral("wchar_t");
4841
103
  case 'b':
4842
103
    if (consumeIf("b0E"))
4843
103
      return make<BoolExpr>(0);
4844
0
    if (consumeIf("b1E"))
4845
0
      return make<BoolExpr>(1);
4846
0
    return nullptr;
4847
0
  case 'c':
4848
0
    ++First;
4849
0
    return getDerived().parseIntegerLiteral("char");
4850
0
  case 'a':
4851
0
    ++First;
4852
0
    return getDerived().parseIntegerLiteral("signed char");
4853
0
  case 'h':
4854
0
    ++First;
4855
0
    return getDerived().parseIntegerLiteral("unsigned char");
4856
0
  case 's':
4857
0
    ++First;
4858
0
    return getDerived().parseIntegerLiteral("short");
4859
0
  case 't':
4860
0
    ++First;
4861
0
    return getDerived().parseIntegerLiteral("unsigned short");
4862
121
  case 'i':
4863
121
    ++First;
4864
121
    return getDerived().parseIntegerLiteral("");
4865
0
  case 'j':
4866
0
    ++First;
4867
0
    return getDerived().parseIntegerLiteral("u");
4868
0
  case 'l':
4869
0
    ++First;
4870
0
    return getDerived().parseIntegerLiteral("l");
4871
0
  case 'm':
4872
0
    ++First;
4873
0
    return getDerived().parseIntegerLiteral("ul");
4874
0
  case 'x':
4875
0
    ++First;
4876
0
    return getDerived().parseIntegerLiteral("ll");
4877
0
  case 'y':
4878
0
    ++First;
4879
0
    return getDerived().parseIntegerLiteral("ull");
4880
0
  case 'n':
4881
0
    ++First;
4882
0
    return getDerived().parseIntegerLiteral("__int128");
4883
3
  case 'o':
4884
3
    ++First;
4885
3
    return getDerived().parseIntegerLiteral("unsigned __int128");
4886
0
  case 'f':
4887
0
    ++First;
4888
0
    return getDerived().template parseFloatingLiteral<float>();
4889
0
  case 'd':
4890
0
    ++First;
4891
0
    return getDerived().template parseFloatingLiteral<double>();
4892
0
  case 'e':
4893
0
    ++First;
4894
#if defined(__powerpc__) || defined(__s390__)
4895
    // Handle cases where long doubles encoded with e have the same size
4896
    // and representation as doubles.
4897
    return getDerived().template parseFloatingLiteral<double>();
4898
#else
4899
0
    return getDerived().template parseFloatingLiteral<long double>();
4900
0
#endif
4901
6
  case '_':
4902
6
    if (consumeIf("_Z")) {
4903
6
      Node *R = getDerived().parseEncoding();
4904
6
      if (R != nullptr && consumeIf('E'))
4905
6
        return R;
4906
6
    }
4907
0
    return nullptr;
4908
4
  case 'A': {
4909
4
    Node *T = getDerived().parseType();
4910
4
    if (T == nullptr)
4911
2
      return nullptr;
4912
    // FIXME: We need to include the string contents in the mangling.
4913
2
    if (consumeIf('E'))
4914
2
      return make<StringLiteral>(T);
4915
0
    return nullptr;
4916
2
  }
4917
0
  case 'D':
4918
0
    if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4919
0
      return make<NameType>("nullptr");
4920
0
    return nullptr;
4921
0
  case 'T':
4922
    // Invalid mangled name per
4923
    //   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4924
0
    return nullptr;
4925
3.89k
  case 'U': {
4926
    // FIXME: Should we support LUb... for block literals?
4927
3.89k
    if (look(1) != 'l')
4928
0
      return nullptr;
4929
3.89k
    Node *T = parseUnnamedTypeName(nullptr);
4930
3.89k
    if (!T || !consumeIf('E'))
4931
3.89k
      return nullptr;
4932
0
    return make<LambdaExpr>(T);
4933
3.89k
  }
4934
104
  default: {
4935
    // might be named type
4936
104
    Node *T = getDerived().parseType();
4937
104
    if (T == nullptr)
4938
1
      return nullptr;
4939
103
    std::string_view N = parseNumber(/*AllowNegative=*/true);
4940
103
    if (N.empty())
4941
0
      return nullptr;
4942
103
    if (!consumeIf('E'))
4943
0
      return nullptr;
4944
103
    return make<EnumLiteral>(T, N);
4945
103
  }
4946
4.23k
  }
4947
4.23k
}
4948
4949
// <braced-expression> ::= <expression>
4950
//                     ::= di <field source-name> <braced-expression>    # .name = expr
4951
//                     ::= dx <index expression> <braced-expression>     # [expr] = expr
4952
//                     ::= dX <range begin expression> <range end expression> <braced-expression>
4953
template <typename Derived, typename Alloc>
4954
83.8k
Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4955
83.8k
  if (look() == 'd') {
4956
33.7k
    switch (look(1)) {
4957
0
    case 'i': {
4958
0
      First += 2;
4959
0
      Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4960
0
      if (Field == nullptr)
4961
0
        return nullptr;
4962
0
      Node *Init = getDerived().parseBracedExpr();
4963
0
      if (Init == nullptr)
4964
0
        return nullptr;
4965
0
      return make<BracedExpr>(Field, Init, /*isArray=*/false);
4966
0
    }
4967
12.3k
    case 'x': {
4968
12.3k
      First += 2;
4969
12.3k
      Node *Index = getDerived().parseExpr();
4970
12.3k
      if (Index == nullptr)
4971
0
        return nullptr;
4972
12.3k
      Node *Init = getDerived().parseBracedExpr();
4973
12.3k
      if (Init == nullptr)
4974
965
        return nullptr;
4975
11.3k
      return make<BracedExpr>(Index, Init, /*isArray=*/true);
4976
12.3k
    }
4977
6.63k
    case 'X': {
4978
6.63k
      First += 2;
4979
6.63k
      Node *RangeBegin = getDerived().parseExpr();
4980
6.63k
      if (RangeBegin == nullptr)
4981
965
        return nullptr;
4982
5.67k
      Node *RangeEnd = getDerived().parseExpr();
4983
5.67k
      if (RangeEnd == nullptr)
4984
1
        return nullptr;
4985
5.67k
      Node *Init = getDerived().parseBracedExpr();
4986
5.67k
      if (Init == nullptr)
4987
0
        return nullptr;
4988
5.67k
      return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4989
5.67k
    }
4990
33.7k
    }
4991
33.7k
  }
4992
64.9k
  return getDerived().parseExpr();
4993
83.8k
}
4994
4995
// (not yet in the spec)
4996
// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4997
//             ::= fR <binary-operator-name> <expression> <expression>
4998
//             ::= fl <binary-operator-name> <expression>
4999
//             ::= fr <binary-operator-name> <expression>
5000
template <typename Derived, typename Alloc>
5001
9
Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
5002
9
  if (!consumeIf('f'))
5003
0
    return nullptr;
5004
5005
9
  bool IsLeftFold = false, HasInitializer = false;
5006
9
  switch (look()) {
5007
0
  default:
5008
0
    return nullptr;
5009
0
  case 'L':
5010
0
    IsLeftFold = true;
5011
0
    HasInitializer = true;
5012
0
    break;
5013
3
  case 'R':
5014
3
    HasInitializer = true;
5015
3
    break;
5016
6
  case 'l':
5017
6
    IsLeftFold = true;
5018
6
    break;
5019
0
  case 'r':
5020
0
    break;
5021
9
  }
5022
9
  ++First;
5023
5024
9
  const auto *Op = parseOperatorEncoding();
5025
9
  if (!Op)
5026
0
    return nullptr;
5027
9
  if (!(Op->getKind() == OperatorInfo::Binary
5028
0
        || (Op->getKind() == OperatorInfo::Member
5029
0
            && Op->getName().back() == '*')))
5030
0
    return nullptr;
5031
5032
9
  Node *Pack = getDerived().parseExpr();
5033
9
  if (Pack == nullptr)
5034
0
    return nullptr;
5035
5036
9
  Node *Init = nullptr;
5037
9
  if (HasInitializer) {
5038
3
    Init = getDerived().parseExpr();
5039
3
    if (Init == nullptr)
5040
0
      return nullptr;
5041
3
  }
5042
5043
9
  if (IsLeftFold && Init)
5044
0
    std::swap(Pack, Init);
5045
5046
9
  return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
5047
9
}
5048
5049
// <expression> ::= mc <parameter type> <expr> [<offset number>] E
5050
//
5051
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5052
template <typename Derived, typename Alloc>
5053
Node *
5054
AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
5055
0
    Node::Prec Prec) {
5056
0
  Node *Ty = getDerived().parseType();
5057
0
  if (!Ty)
5058
0
    return nullptr;
5059
0
  Node *Expr = getDerived().parseExpr();
5060
0
  if (!Expr)
5061
0
    return nullptr;
5062
0
  std::string_view Offset = getDerived().parseNumber(true);
5063
0
  if (!consumeIf('E'))
5064
0
    return nullptr;
5065
0
  return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
5066
0
}
5067
5068
// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
5069
// <union-selector> ::= _ [<number>]
5070
//
5071
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
5072
template <typename Derived, typename Alloc>
5073
4
Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
5074
4
  Node *Ty = getDerived().parseType();
5075
4
  if (!Ty)
5076
0
    return nullptr;
5077
4
  Node *Expr = getDerived().parseExpr();
5078
4
  if (!Expr)
5079
0
    return nullptr;
5080
4
  std::string_view Offset = getDerived().parseNumber(true);
5081
4
  size_t SelectorsBegin = Names.size();
5082
4
  while (consumeIf('_')) {
5083
0
    Node *Selector = make<NameType>(parseNumber());
5084
0
    if (!Selector)
5085
0
      return nullptr;
5086
0
    Names.push_back(Selector);
5087
0
  }
5088
4
  bool OnePastTheEnd = consumeIf('p');
5089
4
  if (!consumeIf('E'))
5090
0
    return nullptr;
5091
4
  return make<SubobjectExpr>(
5092
4
      Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
5093
4
}
5094
5095
template <typename Derived, typename Alloc>
5096
0
Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
5097
  // Within this expression, all enclosing template parameter lists are in
5098
  // scope.
5099
0
  ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
5100
0
      HasIncompleteTemplateParameterTracking, true);
5101
0
  return getDerived().parseExpr();
5102
0
}
5103
5104
template <typename Derived, typename Alloc>
5105
0
Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
5106
0
  NodeArray Params;
5107
0
  if (consumeIf("rQ")) {
5108
    // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
5109
0
    size_t ParamsBegin = Names.size();
5110
0
    while (!consumeIf('_')) {
5111
0
      Node *Type = getDerived().parseType();
5112
0
      if (Type == nullptr)
5113
0
        return nullptr;
5114
0
      Names.push_back(Type);
5115
0
    }
5116
0
    Params = popTrailingNodeArray(ParamsBegin);
5117
0
  } else if (!consumeIf("rq")) {
5118
    // <expression> ::= rq <requirement>+ E
5119
0
    return nullptr;
5120
0
  }
5121
5122
0
  size_t ReqsBegin = Names.size();
5123
0
  do {
5124
0
    Node *Constraint = nullptr;
5125
0
    if (consumeIf('X')) {
5126
      // <requirement> ::= X <expression> [N] [R <type-constraint>]
5127
0
      Node *Expr = getDerived().parseExpr();
5128
0
      if (Expr == nullptr)
5129
0
        return nullptr;
5130
0
      bool Noexcept = consumeIf('N');
5131
0
      Node *TypeReq = nullptr;
5132
0
      if (consumeIf('R')) {
5133
0
        TypeReq = getDerived().parseName();
5134
0
        if (TypeReq == nullptr)
5135
0
          return nullptr;
5136
0
      }
5137
0
      Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
5138
0
    } else if (consumeIf('T')) {
5139
      // <requirement> ::= T <type>
5140
0
      Node *Type = getDerived().parseType();
5141
0
      if (Type == nullptr)
5142
0
        return nullptr;
5143
0
      Constraint = make<TypeRequirement>(Type);
5144
0
    } else if (consumeIf('Q')) {
5145
      // <requirement> ::= Q <constraint-expression>
5146
      //
5147
      // FIXME: We use <expression> instead of <constraint-expression>. Either
5148
      // the requires expression is already inside a constraint expression, in
5149
      // which case it makes no difference, or we're in a requires-expression
5150
      // that might be partially-substituted, where the language behavior is
5151
      // not yet settled and clang mangles after substitution.
5152
0
      Node *NestedReq = getDerived().parseExpr();
5153
0
      if (NestedReq == nullptr)
5154
0
        return nullptr;
5155
0
      Constraint = make<NestedRequirement>(NestedReq);
5156
0
    }
5157
0
    if (Constraint == nullptr)
5158
0
      return nullptr;
5159
0
    Names.push_back(Constraint);
5160
0
  } while (!consumeIf('E'));
5161
5162
0
  return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
5163
0
}
5164
5165
// <expression> ::= <unary operator-name> <expression>
5166
//              ::= <binary operator-name> <expression> <expression>
5167
//              ::= <ternary operator-name> <expression> <expression> <expression>
5168
//              ::= cl <expression>+ E                                   # call
5169
//              ::= cp <base-unresolved-name> <expression>* E            # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
5170
//              ::= cv <type> <expression>                               # conversion with one argument
5171
//              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments
5172
//              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type
5173
//              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
5174
//              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
5175
//              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
5176
//              ::= [gs] dl <expression>                                 # delete expression
5177
//              ::= [gs] da <expression>                                 # delete[] expression
5178
//              ::= pp_ <expression>                                     # prefix ++
5179
//              ::= mm_ <expression>                                     # prefix --
5180
//              ::= ti <type>                                            # typeid (type)
5181
//              ::= te <expression>                                      # typeid (expression)
5182
//              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)
5183
//              ::= sc <type> <expression>                               # static_cast<type> (expression)
5184
//              ::= cc <type> <expression>                               # const_cast<type> (expression)
5185
//              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)
5186
//              ::= st <type>                                            # sizeof (a type)
5187
//              ::= sz <expression>                                      # sizeof (an expression)
5188
//              ::= at <type>                                            # alignof (a type)
5189
//              ::= az <expression>                                      # alignof (an expression)
5190
//              ::= nx <expression>                                      # noexcept (expression)
5191
//              ::= <template-param>
5192
//              ::= <function-param>
5193
//              ::= dt <expression> <unresolved-name>                    # expr.name
5194
//              ::= pt <expression> <unresolved-name>                    # expr->name
5195
//              ::= ds <expression> <expression>                         # expr.*expr
5196
//              ::= sZ <template-param>                                  # size of a parameter pack
5197
//              ::= sZ <function-param>                                  # size of a function parameter pack
5198
//              ::= sP <template-arg>* E                                 # sizeof...(T), size of a captured template parameter pack from an alias template
5199
//              ::= sp <expression>                                      # pack expansion
5200
//              ::= tw <expression>                                      # throw expression
5201
//              ::= tr                                                   # throw with no operand (rethrow)
5202
//              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),
5203
//                                                                       # freestanding dependent name (e.g., T::x),
5204
//                                                                       # objectless nonstatic member reference
5205
//              ::= fL <binary-operator-name> <expression> <expression>
5206
//              ::= fR <binary-operator-name> <expression> <expression>
5207
//              ::= fl <binary-operator-name> <expression>
5208
//              ::= fr <binary-operator-name> <expression>
5209
//              ::= <expr-primary>
5210
template <typename Derived, typename Alloc>
5211
141k
Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
5212
141k
  bool Global = consumeIf("gs");
5213
5214
141k
  const auto *Op = parseOperatorEncoding();
5215
141k
  if (Op) {
5216
25.2k
    auto Sym = Op->getSymbol();
5217
25.2k
    switch (Op->getKind()) {
5218
0
    case OperatorInfo::Binary:
5219
      // Binary operator: lhs @ rhs
5220
0
      return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
5221
13
    case OperatorInfo::Prefix:
5222
      // Prefix unary operator: @ expr
5223
13
      return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5224
10.4k
    case OperatorInfo::Postfix: {
5225
      // Postfix unary operator: expr @
5226
10.4k
      if (consumeIf('_'))
5227
10.4k
        return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
5228
0
      Node *Ex = getDerived().parseExpr();
5229
0
      if (Ex == nullptr)
5230
0
        return nullptr;
5231
0
      return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
5232
0
    }
5233
0
    case OperatorInfo::Array: {
5234
      // Array Index:  lhs [ rhs ]
5235
0
      Node *Base = getDerived().parseExpr();
5236
0
      if (Base == nullptr)
5237
0
        return nullptr;
5238
0
      Node *Index = getDerived().parseExpr();
5239
0
      if (Index == nullptr)
5240
0
        return nullptr;
5241
0
      return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
5242
0
    }
5243
0
    case OperatorInfo::Member: {
5244
      // Member access lhs @ rhs
5245
0
      Node *LHS = getDerived().parseExpr();
5246
0
      if (LHS == nullptr)
5247
0
        return nullptr;
5248
0
      Node *RHS = getDerived().parseExpr();
5249
0
      if (RHS == nullptr)
5250
0
        return nullptr;
5251
0
      return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
5252
0
    }
5253
4
    case OperatorInfo::New: {
5254
      // New
5255
      // # new (expr-list) type [(init)]
5256
      // [gs] nw <expression>* _ <type> [pi <expression>*] E
5257
      // # new[] (expr-list) type [(init)]
5258
      // [gs] na <expression>* _ <type> [pi <expression>*] E
5259
4
      size_t Exprs = Names.size();
5260
4
      while (!consumeIf('_')) {
5261
0
        Node *Ex = getDerived().parseExpr();
5262
0
        if (Ex == nullptr)
5263
0
          return nullptr;
5264
0
        Names.push_back(Ex);
5265
0
      }
5266
4
      NodeArray ExprList = popTrailingNodeArray(Exprs);
5267
4
      Node *Ty = getDerived().parseType();
5268
4
      if (Ty == nullptr)
5269
0
        return nullptr;
5270
4
      bool HaveInits = consumeIf("pi");
5271
4
      size_t InitsBegin = Names.size();
5272
5
      while (!consumeIf('E')) {
5273
1
        if (!HaveInits)
5274
0
          return nullptr;
5275
1
        Node *Init = getDerived().parseExpr();
5276
1
        if (Init == nullptr)
5277
0
          return Init;
5278
1
        Names.push_back(Init);
5279
1
      }
5280
4
      NodeArray Inits = popTrailingNodeArray(InitsBegin);
5281
4
      return make<NewExpr>(ExprList, Ty, Inits, Global,
5282
4
                           /*IsArray=*/Op->getFlag(), Op->getPrecedence());
5283
4
    }
5284
14.7k
    case OperatorInfo::Del: {
5285
      // Delete
5286
14.7k
      Node *Ex = getDerived().parseExpr();
5287
14.7k
      if (Ex == nullptr)
5288
0
        return nullptr;
5289
14.7k
      return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
5290
14.7k
                              Op->getPrecedence());
5291
14.7k
    }
5292
0
    case OperatorInfo::Call: {
5293
      // Function Call
5294
0
      Node *Callee = getDerived().parseExpr();
5295
0
      if (Callee == nullptr)
5296
0
        return nullptr;
5297
0
      size_t ExprsBegin = Names.size();
5298
0
      while (!consumeIf('E')) {
5299
0
        Node *E = getDerived().parseExpr();
5300
0
        if (E == nullptr)
5301
0
          return nullptr;
5302
0
        Names.push_back(E);
5303
0
      }
5304
0
      return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5305
0
                            /*IsParen=*/Op->getFlag(), Op->getPrecedence());
5306
0
    }
5307
0
    case OperatorInfo::CCast: {
5308
      // C Cast: (type)expr
5309
0
      Node *Ty;
5310
0
      {
5311
0
        ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5312
0
        Ty = getDerived().parseType();
5313
0
      }
5314
0
      if (Ty == nullptr)
5315
0
        return nullptr;
5316
5317
0
      size_t ExprsBegin = Names.size();
5318
0
      bool IsMany = consumeIf('_');
5319
0
      while (!consumeIf('E')) {
5320
0
        Node *E = getDerived().parseExpr();
5321
0
        if (E == nullptr)
5322
0
          return E;
5323
0
        Names.push_back(E);
5324
0
        if (!IsMany)
5325
0
          break;
5326
0
      }
5327
0
      NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5328
0
      if (!IsMany && Exprs.size() != 1)
5329
0
        return nullptr;
5330
0
      return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5331
0
    }
5332
3
    case OperatorInfo::Conditional: {
5333
      // Conditional operator: expr ? expr : expr
5334
3
      Node *Cond = getDerived().parseExpr();
5335
3
      if (Cond == nullptr)
5336
1
        return nullptr;
5337
2
      Node *LHS = getDerived().parseExpr();
5338
2
      if (LHS == nullptr)
5339
2
        return nullptr;
5340
0
      Node *RHS = getDerived().parseExpr();
5341
0
      if (RHS == nullptr)
5342
0
        return nullptr;
5343
0
      return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5344
0
    }
5345
0
    case OperatorInfo::NamedCast: {
5346
      // Named cast operation, @<type>(expr)
5347
0
      Node *Ty = getDerived().parseType();
5348
0
      if (Ty == nullptr)
5349
0
        return nullptr;
5350
0
      Node *Ex = getDerived().parseExpr();
5351
0
      if (Ex == nullptr)
5352
0
        return nullptr;
5353
0
      return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5354
0
    }
5355
1
    case OperatorInfo::OfIdOp: {
5356
      // [sizeof/alignof/typeid] ( <type>|<expr> )
5357
1
      Node *Arg =
5358
1
          Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5359
1
      if (!Arg)
5360
1
        return nullptr;
5361
0
      return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5362
1
    }
5363
0
    case OperatorInfo::NameOnly: {
5364
      // Not valid as an expression operand.
5365
0
      return nullptr;
5366
1
    }
5367
25.2k
    }
5368
25.2k
    DEMANGLE_UNREACHABLE;
5369
25.2k
  }
5370
5371
115k
  if (numLeft() < 2)
5372
0
    return nullptr;
5373
5374
115k
  if (look() == 'L')
5375
3.91k
    return getDerived().parseExprPrimary();
5376
111k
  if (look() == 'T')
5377
39.8k
    return getDerived().parseTemplateParam();
5378
72.0k
  if (look() == 'f') {
5379
    // Disambiguate a fold expression from a <function-param>.
5380
23
    if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
5381
14
      return getDerived().parseFunctionParam();
5382
9
    return getDerived().parseFoldExpr();
5383
23
  }
5384
72.0k
  if (consumeIf("il")) {
5385
22.4k
    size_t InitsBegin = Names.size();
5386
67.3k
    while (!consumeIf('E')) {
5387
47.7k
      Node *E = getDerived().parseBracedExpr();
5388
47.7k
      if (E == nullptr)
5389
2.79k
        return nullptr;
5390
44.9k
      Names.push_back(E);
5391
44.9k
    }
5392
19.6k
    return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
5393
22.4k
  }
5394
49.6k
  if (consumeIf("mc"))
5395
0
    return parsePointerToMemberConversionExpr(Node::Prec::Unary);
5396
49.6k
  if (consumeIf("nx")) {
5397
58
    Node *Ex = getDerived().parseExpr();
5398
58
    if (Ex == nullptr)
5399
0
      return Ex;
5400
58
    return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5401
58
  }
5402
49.5k
  if (look() == 'r' && (look(1) == 'q' || look(1) == 'Q'))
5403
0
    return parseRequiresExpr();
5404
49.5k
  if (consumeIf("so"))
5405
4
    return parseSubobjectExpr();
5406
49.5k
  if (consumeIf("sp")) {
5407
0
    Node *Child = getDerived().parseExpr();
5408
0
    if (Child == nullptr)
5409
0
      return nullptr;
5410
0
    return make<ParameterPackExpansion>(Child);
5411
0
  }
5412
49.5k
  if (consumeIf("sy")) {
5413
0
    Node *Pattern = look() == 'T' ? getDerived().parseTemplateParam()
5414
0
                                  : getDerived().parseFunctionParam();
5415
0
    if (Pattern == nullptr)
5416
0
      return nullptr;
5417
0
    Node *Index = getDerived().parseExpr();
5418
0
    if (Index == nullptr)
5419
0
      return nullptr;
5420
0
    return make<PackIndexing>(Pattern, Index);
5421
0
  }
5422
49.5k
  if (consumeIf("sZ")) {
5423
0
    if (look() == 'T') {
5424
0
      Node *R = getDerived().parseTemplateParam();
5425
0
      if (R == nullptr)
5426
0
        return nullptr;
5427
0
      return make<SizeofParamPackExpr>(R);
5428
0
    }
5429
0
    Node *FP = getDerived().parseFunctionParam();
5430
0
    if (FP == nullptr)
5431
0
      return nullptr;
5432
0
    return make<EnclosingExpr>("sizeof... ", FP);
5433
0
  }
5434
49.5k
  if (consumeIf("sP")) {
5435
25.3k
    size_t ArgsBegin = Names.size();
5436
264k
    while (!consumeIf('E')) {
5437
239k
      Node *Arg = getDerived().parseTemplateArg();
5438
239k
      if (Arg == nullptr)
5439
2
        return nullptr;
5440
239k
      Names.push_back(Arg);
5441
239k
    }
5442
25.3k
    auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5443
25.3k
    if (!Pack)
5444
0
      return nullptr;
5445
25.3k
    return make<EnclosingExpr>("sizeof... ", Pack);
5446
25.3k
  }
5447
24.1k
  if (consumeIf("tl")) {
5448
6.63k
    Node *Ty = getDerived().parseType();
5449
6.63k
    if (Ty == nullptr)
5450
0
      return nullptr;
5451
6.63k
    size_t InitsBegin = Names.size();
5452
23.7k
    while (!consumeIf('E')) {
5453
18.1k
      Node *E = getDerived().parseBracedExpr();
5454
18.1k
      if (E == nullptr)
5455
966
        return nullptr;
5456
17.1k
      Names.push_back(E);
5457
17.1k
    }
5458
5.67k
    return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5459
6.63k
  }
5460
17.5k
  if (consumeIf("tr"))
5461
6
    return make<NameType>("throw");
5462
17.5k
  if (consumeIf("tw")) {
5463
0
    Node *Ex = getDerived().parseExpr();
5464
0
    if (Ex == nullptr)
5465
0
      return nullptr;
5466
0
    return make<ThrowExpr>(Ex);
5467
0
  }
5468
17.5k
  if (consumeIf('u')) {
5469
1.83k
    Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5470
1.83k
    if (!Name)
5471
0
      return nullptr;
5472
    // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5473
    // standard encoding expects a <template-arg>, and would be otherwise be
5474
    // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5475
    // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5476
    // actual conflict here.
5477
1.83k
    bool IsUUID = false;
5478
1.83k
    Node *UUID = nullptr;
5479
1.83k
    if (Name->getBaseName() == "__uuidof") {
5480
0
      if (consumeIf('t')) {
5481
0
        UUID = getDerived().parseType();
5482
0
        IsUUID = true;
5483
0
      } else if (consumeIf('z')) {
5484
0
        UUID = getDerived().parseExpr();
5485
0
        IsUUID = true;
5486
0
      }
5487
0
    }
5488
1.83k
    size_t ExprsBegin = Names.size();
5489
1.83k
    if (IsUUID) {
5490
0
      if (UUID == nullptr)
5491
0
        return nullptr;
5492
0
      Names.push_back(UUID);
5493
1.83k
    } else {
5494
23.1k
      while (!consumeIf('E')) {
5495
22.9k
        Node *E = getDerived().parseTemplateArg();
5496
22.9k
        if (E == nullptr)
5497
1.63k
          return E;
5498
21.3k
        Names.push_back(E);
5499
21.3k
      }
5500
1.83k
    }
5501
200
    return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5502
200
                          /*IsParen=*/false, Node::Prec::Postfix);
5503
1.83k
  }
5504
5505
  // Only unresolved names remain.
5506
15.6k
  return getDerived().parseUnresolvedName(Global);
5507
17.5k
}
5508
5509
// <call-offset> ::= h <nv-offset> _
5510
//               ::= v <v-offset> _
5511
//
5512
// <nv-offset> ::= <offset number>
5513
//               # non-virtual base override
5514
//
5515
// <v-offset>  ::= <offset number> _ <virtual offset number>
5516
//               # virtual base override, with vcall offset
5517
template <typename Alloc, typename Derived>
5518
0
bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5519
  // Just scan through the call offset, we never add this information into the
5520
  // output.
5521
0
  if (consumeIf('h'))
5522
0
    return parseNumber(true).empty() || !consumeIf('_');
5523
0
  if (consumeIf('v'))
5524
0
    return parseNumber(true).empty() || !consumeIf('_') ||
5525
0
           parseNumber(true).empty() || !consumeIf('_');
5526
0
  return true;
5527
0
}
5528
5529
// <special-name> ::= TV <type>    # virtual table
5530
//                ::= TT <type>    # VTT structure (construction vtable index)
5531
//                ::= TI <type>    # typeinfo structure
5532
//                ::= TS <type>    # typeinfo name (null-terminated byte string)
5533
//                ::= Tc <call-offset> <call-offset> <base encoding>
5534
//                    # base is the nominal target function of thunk
5535
//                    # first call-offset is 'this' adjustment
5536
//                    # second call-offset is result adjustment
5537
//                ::= T <call-offset> <base encoding>
5538
//                    # base is the nominal target function of thunk
5539
//                # Guard variable for one-time initialization
5540
//                ::= GV <object name>
5541
//                                     # No <type>
5542
//                ::= TW <object name> # Thread-local wrapper
5543
//                ::= TH <object name> # Thread-local initialization
5544
//                ::= GR <object name> _             # First temporary
5545
//                ::= GR <object name> <seq-id> _    # Subsequent temporaries
5546
//                # construction vtable for second-in-first
5547
//      extension ::= TC <first type> <number> _ <second type>
5548
//      extension ::= GR <object name> # reference temporary for object
5549
//      extension ::= GI <module name> # module global initializer
5550
template <typename Derived, typename Alloc>
5551
42
Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5552
42
  switch (look()) {
5553
42
  case 'T':
5554
42
    switch (look(1)) {
5555
    // TA <template-arg>    # template parameter object
5556
    //
5557
    // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5558
0
    case 'A': {
5559
0
      First += 2;
5560
0
      Node *Arg = getDerived().parseTemplateArg();
5561
0
      if (Arg == nullptr)
5562
0
        return nullptr;
5563
0
      return make<SpecialName>("template parameter object for ", Arg);
5564
0
    }
5565
    // TV <type>    # virtual table
5566
0
    case 'V': {
5567
0
      First += 2;
5568
0
      Node *Ty = getDerived().parseType();
5569
0
      if (Ty == nullptr)
5570
0
        return nullptr;
5571
0
      return make<SpecialName>("vtable for ", Ty);
5572
0
    }
5573
    // TT <type>    # VTT structure (construction vtable index)
5574
0
    case 'T': {
5575
0
      First += 2;
5576
0
      Node *Ty = getDerived().parseType();
5577
0
      if (Ty == nullptr)
5578
0
        return nullptr;
5579
0
      return make<SpecialName>("VTT for ", Ty);
5580
0
    }
5581
    // TI <type>    # typeinfo structure
5582
0
    case 'I': {
5583
0
      First += 2;
5584
0
      Node *Ty = getDerived().parseType();
5585
0
      if (Ty == nullptr)
5586
0
        return nullptr;
5587
0
      return make<SpecialName>("typeinfo for ", Ty);
5588
0
    }
5589
    // TS <type>    # typeinfo name (null-terminated byte string)
5590
0
    case 'S': {
5591
0
      First += 2;
5592
0
      Node *Ty = getDerived().parseType();
5593
0
      if (Ty == nullptr)
5594
0
        return nullptr;
5595
0
      return make<SpecialName>("typeinfo name for ", Ty);
5596
0
    }
5597
    // Tc <call-offset> <call-offset> <base encoding>
5598
0
    case 'c': {
5599
0
      First += 2;
5600
0
      if (parseCallOffset() || parseCallOffset())
5601
0
        return nullptr;
5602
0
      Node *Encoding = getDerived().parseEncoding();
5603
0
      if (Encoding == nullptr)
5604
0
        return nullptr;
5605
0
      return make<SpecialName>("covariant return thunk to ", Encoding);
5606
0
    }
5607
    // extension ::= TC <first type> <number> _ <second type>
5608
    //               # construction vtable for second-in-first
5609
10
    case 'C': {
5610
10
      First += 2;
5611
10
      Node *FirstType = getDerived().parseType();
5612
10
      if (FirstType == nullptr)
5613
6
        return nullptr;
5614
4
      if (parseNumber(true).empty() || !consumeIf('_'))
5615
0
        return nullptr;
5616
4
      Node *SecondType = getDerived().parseType();
5617
4
      if (SecondType == nullptr)
5618
4
        return nullptr;
5619
0
      return make<CtorVtableSpecialName>(SecondType, FirstType);
5620
4
    }
5621
    // TW <object name> # Thread-local wrapper
5622
32
    case 'W': {
5623
32
      First += 2;
5624
32
      Node *Name = getDerived().parseName();
5625
32
      if (Name == nullptr)
5626
0
        return nullptr;
5627
32
      return make<SpecialName>("thread-local wrapper routine for ", Name);
5628
32
    }
5629
    // TH <object name> # Thread-local initialization
5630
0
    case 'H': {
5631
0
      First += 2;
5632
0
      Node *Name = getDerived().parseName();
5633
0
      if (Name == nullptr)
5634
0
        return nullptr;
5635
0
      return make<SpecialName>("thread-local initialization routine for ", Name);
5636
0
    }
5637
    // T <call-offset> <base encoding>
5638
0
    default: {
5639
0
      ++First;
5640
0
      bool IsVirt = look() == 'v';
5641
0
      if (parseCallOffset())
5642
0
        return nullptr;
5643
0
      Node *BaseEncoding = getDerived().parseEncoding();
5644
0
      if (BaseEncoding == nullptr)
5645
0
        return nullptr;
5646
0
      if (IsVirt)
5647
0
        return make<SpecialName>("virtual thunk to ", BaseEncoding);
5648
0
      else
5649
0
        return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5650
0
    }
5651
42
    }
5652
0
  case 'G':
5653
0
    switch (look(1)) {
5654
    // GV <object name> # Guard variable for one-time initialization
5655
0
    case 'V': {
5656
0
      First += 2;
5657
0
      Node *Name = getDerived().parseName();
5658
0
      if (Name == nullptr)
5659
0
        return nullptr;
5660
0
      return make<SpecialName>("guard variable for ", Name);
5661
0
    }
5662
    // GR <object name> # reference temporary for object
5663
    // GR <object name> _             # First temporary
5664
    // GR <object name> <seq-id> _    # Subsequent temporaries
5665
0
    case 'R': {
5666
0
      First += 2;
5667
0
      Node *Name = getDerived().parseName();
5668
0
      if (Name == nullptr)
5669
0
        return nullptr;
5670
0
      size_t Count;
5671
0
      bool ParsedSeqId = !parseSeqId(&Count);
5672
0
      if (!consumeIf('_') && ParsedSeqId)
5673
0
        return nullptr;
5674
0
      return make<SpecialName>("reference temporary for ", Name);
5675
0
    }
5676
    // GI <module-name> v
5677
0
    case 'I': {
5678
0
      First += 2;
5679
0
      ModuleName *Module = nullptr;
5680
0
      if (getDerived().parseModuleNameOpt(Module))
5681
0
        return nullptr;
5682
0
      if (Module == nullptr)
5683
0
        return nullptr;
5684
0
      return make<SpecialName>("initializer for module ", Module);
5685
0
    }
5686
0
    }
5687
42
  }
5688
0
  return nullptr;
5689
42
}
5690
5691
// <encoding> ::= <function name> <bare-function-type>
5692
//                    [`Q` <requires-clause expr>]
5693
//            ::= <data name>
5694
//            ::= <special-name>
5695
template <typename Derived, typename Alloc>
5696
8.05k
Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5697
  // The template parameters of an encoding are unrelated to those of the
5698
  // enclosing context.
5699
8.05k
  SaveTemplateParams SaveTemplateParamsScope(this);
5700
5701
8.05k
  if (look() == 'G' || look() == 'T')
5702
42
    return getDerived().parseSpecialName();
5703
5704
527k
  auto IsEndOfEncoding = [&] {
5705
    // The set of chars that can potentially follow an <encoding> (none of which
5706
    // can start a <type>). Enumerating these allows us to avoid speculative
5707
    // parsing.
5708
527k
    return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5709
527k
  };
5710
5711
8.01k
  NameState NameInfo(this);
5712
8.01k
  Node *Name = getDerived().parseName(&NameInfo);
5713
8.01k
  if (Name == nullptr)
5714
1.67k
    return nullptr;
5715
5716
6.33k
  if (resolveForwardTemplateRefs(NameInfo))
5717
0
    return nullptr;
5718
5719
6.33k
  if (IsEndOfEncoding())
5720
233
    return Name;
5721
5722
  // ParseParams may be false at the top level only, when called from parse().
5723
  // For example in the mangled name _Z3fooILZ3BarEET_f, ParseParams may be
5724
  // false when demangling 3fooILZ3BarEET_f but is always true when demangling
5725
  // 3Bar.
5726
6.10k
  if (!ParseParams) {
5727
0
    while (consume())
5728
0
      ;
5729
0
    return Name;
5730
0
  }
5731
5732
6.10k
  Node *Attrs = nullptr;
5733
6.10k
  if (consumeIf("Ua9enable_ifI")) {
5734
0
    size_t BeforeArgs = Names.size();
5735
0
    while (!consumeIf('E')) {
5736
0
      Node *Arg = getDerived().parseTemplateArg();
5737
0
      if (Arg == nullptr)
5738
0
        return nullptr;
5739
0
      Names.push_back(Arg);
5740
0
    }
5741
0
    Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5742
0
    if (!Attrs)
5743
0
      return nullptr;
5744
0
  }
5745
5746
6.10k
  Node *ReturnType = nullptr;
5747
6.10k
  if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5748
1.38k
    ReturnType = getDerived().parseType();
5749
1.38k
    if (ReturnType == nullptr)
5750
2
      return nullptr;
5751
1.38k
  }
5752
5753
6.10k
  NodeArray Params;
5754
6.10k
  if (!consumeIf('v')) {
5755
6.10k
    size_t ParamsBegin = Names.size();
5756
524k
    do {
5757
524k
      Node *Ty = getDerived().parseType();
5758
524k
      if (Ty == nullptr)
5759
3.48k
        return nullptr;
5760
5761
520k
      const bool IsFirstParam = ParamsBegin == Names.size();
5762
520k
      if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5763
0
        Ty = make<ExplicitObjectParameter>(Ty);
5764
5765
520k
      if (Ty == nullptr)
5766
0
        return nullptr;
5767
5768
520k
      Names.push_back(Ty);
5769
520k
    } while (!IsEndOfEncoding() && look() != 'Q');
5770
2.62k
    Params = popTrailingNodeArray(ParamsBegin);
5771
2.62k
  }
5772
5773
2.62k
  Node *Requires = nullptr;
5774
2.62k
  if (consumeIf('Q')) {
5775
0
    Requires = getDerived().parseConstraintExpr();
5776
0
    if (!Requires)
5777
0
      return nullptr;
5778
0
  }
5779
5780
2.62k
  return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5781
2.62k
                                NameInfo.CVQualifiers,
5782
2.62k
                                NameInfo.ReferenceQualifier);
5783
2.62k
}
5784
5785
template <class Float>
5786
struct FloatData;
5787
5788
template <>
5789
struct FloatData<float>
5790
{
5791
    static const size_t mangled_size = 8;
5792
    static const size_t max_demangled_size = 24;
5793
    static constexpr const char* spec = "%af";
5794
};
5795
5796
template <>
5797
struct FloatData<double>
5798
{
5799
    static const size_t mangled_size = 16;
5800
    static const size_t max_demangled_size = 32;
5801
    static constexpr const char* spec = "%a";
5802
};
5803
5804
template <>
5805
struct FloatData<long double>
5806
{
5807
#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106
5808
  static const size_t mangled_size = 32;
5809
#elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER)
5810
  // MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to
5811
  // regular double on all current architectures.
5812
  static const size_t mangled_size = 16;
5813
#elif __LDBL_MANT_DIG__ == 64
5814
  static const size_t mangled_size = 20;
5815
#else
5816
#error Unknown size for __LDBL_MANT_DIG__
5817
#endif
5818
    // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5819
    // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5820
    // Negatives are one character longer than positives.
5821
    // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5822
    // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5823
    static const size_t max_demangled_size = 42;
5824
    static constexpr const char *spec = "%LaL";
5825
};
5826
5827
template <typename Alloc, typename Derived>
5828
template <class Float>
5829
0
Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5830
0
  const size_t N = FloatData<Float>::mangled_size;
5831
0
  if (numLeft() <= N)
5832
0
    return nullptr;
5833
0
  std::string_view Data(First, N);
5834
0
  for (char C : Data)
5835
0
    if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
5836
0
      return nullptr;
5837
0
  First += N;
5838
0
  if (!consumeIf('E'))
5839
0
    return nullptr;
5840
0
  return make<FloatLiteralImpl<Float>>(Data);
5841
0
}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<float>()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<double>()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<long double>()
5842
5843
// <seq-id> ::= <0-9A-Z>+
5844
template <typename Alloc, typename Derived>
5845
4
bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5846
4
  if (!(look() >= '0' && look() <= '9') &&
5847
0
      !(look() >= 'A' && look() <= 'Z'))
5848
0
    return true;
5849
5850
4
  size_t Id = 0;
5851
8
  while (true) {
5852
8
    if (look() >= '0' && look() <= '9') {
5853
4
      Id *= 36;
5854
4
      Id += static_cast<size_t>(look() - '0');
5855
4
    } else if (look() >= 'A' && look() <= 'Z') {
5856
0
      Id *= 36;
5857
0
      Id += static_cast<size_t>(look() - 'A') + 10;
5858
4
    } else {
5859
4
      *Out = Id;
5860
4
      return false;
5861
4
    }
5862
4
    ++First;
5863
4
  }
5864
4
}
5865
5866
// <substitution> ::= S <seq-id> _
5867
//                ::= S_
5868
// <substitution> ::= Sa # ::std::allocator
5869
// <substitution> ::= Sb # ::std::basic_string
5870
// <substitution> ::= Ss # ::std::basic_string < char,
5871
//                                               ::std::char_traits<char>,
5872
//                                               ::std::allocator<char> >
5873
// <substitution> ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
5874
// <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
5875
// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5876
// The St case is handled specially in parseNestedName.
5877
template <typename Derived, typename Alloc>
5878
18.5k
Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5879
18.5k
  if (!consumeIf('S'))
5880
0
    return nullptr;
5881
5882
18.5k
  if (look() >= 'a' && look() <= 'z') {
5883
13.1k
    SpecialSubKind Kind;
5884
13.1k
    switch (look()) {
5885
72
    case 'a':
5886
72
      Kind = SpecialSubKind::allocator;
5887
72
      break;
5888
212
    case 'b':
5889
212
      Kind = SpecialSubKind::basic_string;
5890
212
      break;
5891
0
    case 'd':
5892
0
      Kind = SpecialSubKind::iostream;
5893
0
      break;
5894
10
    case 'i':
5895
10
      Kind = SpecialSubKind::istream;
5896
10
      break;
5897
10.1k
    case 'o':
5898
10.1k
      Kind = SpecialSubKind::ostream;
5899
10.1k
      break;
5900
2.72k
    case 's':
5901
2.72k
      Kind = SpecialSubKind::string;
5902
2.72k
      break;
5903
0
    default:
5904
0
      return nullptr;
5905
13.1k
    }
5906
13.1k
    ++First;
5907
13.1k
    auto *SpecialSub = make<SpecialSubstitution>(Kind);
5908
13.1k
    if (!SpecialSub)
5909
0
      return nullptr;
5910
5911
    // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5912
    // has ABI tags, the tags are appended to the substitution; the result is a
5913
    // substitutable component.
5914
13.1k
    Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5915
13.1k
    if (WithTags != SpecialSub) {
5916
4
      Subs.push_back(WithTags);
5917
4
      SpecialSub = WithTags;
5918
4
    }
5919
13.1k
    return SpecialSub;
5920
13.1k
  }
5921
5922
  //                ::= S_
5923
5.41k
  if (consumeIf('_')) {
5924
5.40k
    if (Subs.empty())
5925
0
      return nullptr;
5926
5.40k
    return Subs[0];
5927
5.40k
  }
5928
5929
  //                ::= S <seq-id> _
5930
4
  size_t Index = 0;
5931
4
  if (parseSeqId(&Index))
5932
0
    return nullptr;
5933
4
  ++Index;
5934
4
  if (!consumeIf('_') || Index >= Subs.size())
5935
0
    return nullptr;
5936
4
  return Subs[Index];
5937
4
}
5938
5939
// <template-param> ::= T_    # first template parameter
5940
//                  ::= T <parameter-2 non-negative number> _
5941
//                  ::= TL <level-1> __
5942
//                  ::= TL <level-1> _ <parameter-2 non-negative number> _
5943
template <typename Derived, typename Alloc>
5944
65.1k
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5945
65.1k
  const char *Begin = First;
5946
65.1k
  if (!consumeIf('T'))
5947
0
    return nullptr;
5948
5949
65.1k
  size_t Level = 0;
5950
65.1k
  if (consumeIf('L')) {
5951
0
    if (parsePositiveInteger(&Level))
5952
0
      return nullptr;
5953
0
    ++Level;
5954
0
    if (!consumeIf('_'))
5955
0
      return nullptr;
5956
0
  }
5957
5958
65.1k
  size_t Index = 0;
5959
65.1k
  if (!consumeIf('_')) {
5960
1
    if (parsePositiveInteger(&Index))
5961
1
      return nullptr;
5962
0
    ++Index;
5963
0
    if (!consumeIf('_'))
5964
0
      return nullptr;
5965
0
  }
5966
5967
  // We don't track enclosing template parameter levels well enough to reliably
5968
  // substitute them all within a <constraint-expression>, so print the
5969
  // parameter numbering instead for now.
5970
  // TODO: Track all enclosing template parameters and substitute them here.
5971
65.1k
  if (HasIncompleteTemplateParameterTracking) {
5972
0
    return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5973
0
  }
5974
5975
  // If we're in a context where this <template-param> refers to a
5976
  // <template-arg> further ahead in the mangled name (currently just conversion
5977
  // operator types), then we should only look it up in the right context.
5978
  // This can only happen at the outermost level.
5979
65.1k
  if (PermitForwardTemplateReferences && Level == 0) {
5980
2
    Node *ForwardRef = make<ForwardTemplateReference>(Index);
5981
2
    if (!ForwardRef)
5982
0
      return nullptr;
5983
2
    DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5984
2
                    "");
5985
2
    ForwardTemplateRefs.push_back(
5986
2
        static_cast<ForwardTemplateReference *>(ForwardRef));
5987
2
    return ForwardRef;
5988
2
  }
5989
5990
65.1k
  if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5991
38.3k
      Index >= TemplateParams[Level]->size()) {
5992
    // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5993
    // list are mangled as the corresponding artificial template type parameter.
5994
38.3k
    if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5995
      // This will be popped by the ScopedTemplateParamList in
5996
      // parseUnnamedTypeName.
5997
38.3k
      if (Level == TemplateParams.size())
5998
193
        TemplateParams.push_back(nullptr);
5999
38.3k
      return make<NameType>("auto");
6000
38.3k
    }
6001
6002
0
    return nullptr;
6003
38.3k
  }
6004
6005
26.7k
  return (*TemplateParams[Level])[Index];
6006
65.1k
}
6007
6008
// <template-param-decl> ::= Ty                          # type parameter
6009
//                       ::= Tk <concept name> [<template-args>] # constrained type parameter
6010
//                       ::= Tn <type>                   # non-type parameter
6011
//                       ::= Tt <template-param-decl>* E # template parameter
6012
//                       ::= Tp <template-param-decl>    # parameter pack
6013
template <typename Derived, typename Alloc>
6014
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
6015
22.0k
    TemplateParamList *Params) {
6016
22.0k
  auto InventTemplateParamName = [&](TemplateParamKind Kind) {
6017
21.8k
    unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
6018
21.8k
    Node *N = make<SyntheticTemplateParamName>(Kind, Index);
6019
21.8k
    if (N && Params)
6020
21.8k
      Params->push_back(N);
6021
21.8k
    return N;
6022
21.8k
  };
6023
6024
22.0k
  if (consumeIf("Ty")) {
6025
12.7k
    Node *Name = InventTemplateParamName(TemplateParamKind::Type);
6026
12.7k
    if (!Name)
6027
0
      return nullptr;
6028
12.7k
    return make<TypeTemplateParamDecl>(Name);
6029
12.7k
  }
6030
6031
9.31k
  if (consumeIf("Tk")) {
6032
    // We don't track enclosing template parameter levels well enough to
6033
    // reliably demangle template parameter substitutions, so print an arbitrary
6034
    // string in place of a parameter for now.
6035
    // TODO: Track all enclosing template parameters and demangle substitutions.
6036
0
    ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
6037
0
        HasIncompleteTemplateParameterTracking, true);
6038
0
    Node *Constraint = getDerived().parseName();
6039
0
    if (!Constraint)
6040
0
      return nullptr;
6041
0
    Node *Name = InventTemplateParamName(TemplateParamKind::Type);
6042
0
    if (!Name)
6043
0
      return nullptr;
6044
0
    return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
6045
0
  }
6046
6047
9.31k
  if (consumeIf("Tn")) {
6048
264
    Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
6049
264
    if (!Name)
6050
0
      return nullptr;
6051
264
    Node *Type = parseType();
6052
264
    if (!Type)
6053
0
      return nullptr;
6054
264
    return make<NonTypeTemplateParamDecl>(Name, Type);
6055
264
  }
6056
6057
9.05k
  if (consumeIf("Tt")) {
6058
8.82k
    Node *Name = InventTemplateParamName(TemplateParamKind::Template);
6059
8.82k
    if (!Name)
6060
0
      return nullptr;
6061
8.82k
    size_t ParamsBegin = Names.size();
6062
8.82k
    ScopedTemplateParamList TemplateTemplateParamParams(this);
6063
8.82k
    Node *Requires = nullptr;
6064
21.4k
    while (!consumeIf('E')) {
6065
12.6k
      Node *P = parseTemplateParamDecl(TemplateTemplateParamParams.params());
6066
12.6k
      if (!P)
6067
0
        return nullptr;
6068
12.6k
      Names.push_back(P);
6069
12.6k
      if (consumeIf('Q')) {
6070
0
        Requires = getDerived().parseConstraintExpr();
6071
0
        if (Requires == nullptr || !consumeIf('E'))
6072
0
          return nullptr;
6073
0
        break;
6074
0
      }
6075
12.6k
    }
6076
8.82k
    NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
6077
8.82k
    return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
6078
8.82k
  }
6079
6080
231
  if (consumeIf("Tp")) {
6081
230
    Node *P = parseTemplateParamDecl(Params);
6082
230
    if (!P)
6083
1
      return nullptr;
6084
229
    return make<TemplateParamPackDecl>(P);
6085
230
  }
6086
6087
1
  return nullptr;
6088
231
}
6089
6090
// <template-arg> ::= <type>                    # type or template
6091
//                ::= X <expression> E          # expression
6092
//                ::= <expr-primary>            # simple expressions
6093
//                ::= J <template-arg>* E       # argument pack
6094
//                ::= LZ <encoding> E           # extension
6095
//                ::= <template-param-decl> <template-arg>
6096
template <typename Derived, typename Alloc>
6097
1.34M
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
6098
1.34M
  switch (look()) {
6099
5.02k
  case 'X': {
6100
5.02k
    ++First;
6101
5.02k
    Node *Arg = getDerived().parseExpr();
6102
5.02k
    if (Arg == nullptr || !consumeIf('E'))
6103
724
      return nullptr;
6104
4.30k
    return Arg;
6105
5.02k
  }
6106
22.6k
  case 'J': {
6107
22.6k
    ++First;
6108
22.6k
    size_t ArgsBegin = Names.size();
6109
827k
    while (!consumeIf('E')) {
6110
811k
      Node *Arg = getDerived().parseTemplateArg();
6111
811k
      if (Arg == nullptr)
6112
6.95k
        return nullptr;
6113
804k
      Names.push_back(Arg);
6114
804k
    }
6115
15.6k
    NodeArray Args = popTrailingNodeArray(ArgsBegin);
6116
15.6k
    return make<TemplateArgumentPack>(Args);
6117
22.6k
  }
6118
315
  case 'L': {
6119
    //                ::= LZ <encoding> E           # extension
6120
315
    if (look(1) == 'Z') {
6121
0
      First += 2;
6122
0
      Node *Arg = getDerived().parseEncoding();
6123
0
      if (Arg == nullptr || !consumeIf('E'))
6124
0
        return nullptr;
6125
0
      return Arg;
6126
0
    }
6127
    //                ::= <expr-primary>            # simple expressions
6128
315
    return getDerived().parseExprPrimary();
6129
315
  }
6130
11.0k
  case 'T': {
6131
    // Either <template-param> or a <template-param-decl> <template-arg>.
6132
11.0k
    if (!getDerived().isTemplateParamDecl())
6133
11.0k
      return getDerived().parseType();
6134
1
    Node *Param = getDerived().parseTemplateParamDecl(nullptr);
6135
1
    if (!Param)
6136
0
      return nullptr;
6137
1
    Node *Arg = getDerived().parseTemplateArg();
6138
1
    if (!Arg)
6139
0
      return nullptr;
6140
1
    return make<TemplateParamQualifiedArg>(Param, Arg);
6141
1
  }
6142
1.30M
  default:
6143
1.30M
    return getDerived().parseType();
6144
1.34M
  }
6145
1.34M
}
6146
6147
// <template-args> ::= I <template-arg>* [Q <requires-clause expr>] E
6148
//     extension, the abi says <template-arg>+
6149
template <typename Derived, typename Alloc>
6150
Node *
6151
27.0k
AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
6152
27.0k
  if (!consumeIf('I'))
6153
0
    return nullptr;
6154
6155
  // <template-params> refer to the innermost <template-args>. Clear out any
6156
  // outer args that we may have inserted into TemplateParams.
6157
27.0k
  if (TagTemplates) {
6158
2.71k
    TemplateParams.clear();
6159
2.71k
    TemplateParams.push_back(&OuterTemplateParams);
6160
2.71k
    OuterTemplateParams.clear();
6161
2.71k
  }
6162
6163
27.0k
  size_t ArgsBegin = Names.size();
6164
27.0k
  Node *Requires = nullptr;
6165
288k
  while (!consumeIf('E')) {
6166
274k
    if (TagTemplates) {
6167
100k
      Node *Arg = getDerived().parseTemplateArg();
6168
100k
      if (Arg == nullptr)
6169
1.33k
        return nullptr;
6170
98.8k
      Names.push_back(Arg);
6171
98.8k
      Node *TableEntry = Arg;
6172
98.8k
      if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
6173
0
        TableEntry =
6174
0
            static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
6175
0
      }
6176
98.8k
      if (Arg->getKind() == Node::KTemplateArgumentPack) {
6177
1.37k
        TableEntry = make<ParameterPack>(
6178
1.37k
            static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
6179
1.37k
        if (!TableEntry)
6180
0
          return nullptr;
6181
1.37k
      }
6182
98.8k
      OuterTemplateParams.push_back(TableEntry);
6183
173k
    } else {
6184
173k
      Node *Arg = getDerived().parseTemplateArg();
6185
173k
      if (Arg == nullptr)
6186
10.7k
        return nullptr;
6187
163k
      Names.push_back(Arg);
6188
163k
    }
6189
261k
    if (consumeIf('Q')) {
6190
0
      Requires = getDerived().parseConstraintExpr();
6191
0
      if (!Requires || !consumeIf('E'))
6192
0
        return nullptr;
6193
0
      break;
6194
0
    }
6195
261k
  }
6196
14.9k
  return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
6197
27.0k
}
6198
6199
// <mangled-name> ::= _Z <encoding>
6200
//                ::= <type>
6201
// extension      ::= ___Z <encoding> _block_invoke
6202
// extension      ::= ___Z <encoding> _block_invoke<decimal-digit>+
6203
// extension      ::= ___Z <encoding> _block_invoke_<decimal-digit>+
6204
// extension      ::= __alloc_token__Z <encoding>
6205
// extension      ::= __alloc_token_<decimal-digit>+__Z <encoding>
6206
template <typename Derived, typename Alloc>
6207
22
Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
6208
22
  bool AllocToken = consumeIf("__alloc_token_");
6209
22
  if (AllocToken) {
6210
0
    const char *Saved = First;
6211
0
    if (parseNumber().empty() || !consumeIf('_'))
6212
0
      First = Saved;
6213
0
  }
6214
6215
22
  if (consumeIf("_Z") || consumeIf("__Z")) {
6216
10
    Node *Encoding = getDerived().parseEncoding(ParseParams);
6217
10
    if (Encoding == nullptr)
6218
9
      return nullptr;
6219
1
    if (look() == '.') {
6220
1
      Encoding =
6221
1
          make<DotSuffix>(Encoding, std::string_view(First, Last - First));
6222
1
      First = Last;
6223
1
    }
6224
1
    if (AllocToken)
6225
0
      Encoding = make<DotSuffix>(Encoding, ".alloc_token");
6226
1
    if (numLeft() != 0)
6227
0
      return nullptr;
6228
1
    return Encoding;
6229
1
  }
6230
6231
12
  if (consumeIf("___Z") || consumeIf("____Z")) {
6232
0
    Node *Encoding = getDerived().parseEncoding(ParseParams);
6233
0
    if (Encoding == nullptr || !consumeIf("_block_invoke"))
6234
0
      return nullptr;
6235
0
    bool RequireNumber = consumeIf('_');
6236
0
    if (parseNumber().empty() && RequireNumber)
6237
0
      return nullptr;
6238
0
    if (look() == '.')
6239
0
      First = Last;
6240
0
    if (numLeft() != 0)
6241
0
      return nullptr;
6242
0
    return make<SpecialName>("invocation function for block in ", Encoding);
6243
0
  }
6244
6245
12
  Node *Ty = getDerived().parseType();
6246
12
  if (numLeft() != 0)
6247
12
    return nullptr;
6248
0
  return Ty;
6249
12
}
6250
6251
template <typename Alloc>
6252
struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
6253
  using AbstractManglingParser<ManglingParser<Alloc>,
6254
                               Alloc>::AbstractManglingParser;
6255
};
6256
6257
244
inline void OutputBuffer::printLeft(const Node &N) { N.printLeft(*this); }
6258
6259
1
inline void OutputBuffer::printRight(const Node &N) { N.printRight(*this); }
6260
6261
DEMANGLE_NAMESPACE_END
6262
6263
#if defined(__clang__)
6264
#pragma clang diagnostic pop
6265
#endif
6266
6267
#endif // DEMANGLE_ITANIUMDEMANGLE_H