Coverage Report

Created: 2023-06-07 06:52

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