Coverage Report

Created: 2025-07-23 07:11

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