1//===-- DemangledNameInfo.cpp ---------------------------------------------===//
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#include "lldb/Core/DemangledNameInfo.h"
10
11using namespace llvm::itanium_demangle;
12
13namespace lldb_private {
14
15bool TrackingOutputBuffer::shouldTrack() const {
16 if (!isPrintingTopLevelFunctionType())
17 return false;
18
19 if (isGtInsideTemplateArgs())
20 return false;
21
22 if (NameInfo.ArgumentsRange.first > 0)
23 return false;
24
25 return true;
26}
27
28bool TrackingOutputBuffer::canFinalize() const {
29 if (!isPrintingTopLevelFunctionType())
30 return false;
31
32 if (isGtInsideTemplateArgs())
33 return false;
34
35 if (NameInfo.ArgumentsRange.first == 0)
36 return false;
37
38 return true;
39}
40
41void TrackingOutputBuffer::updateBasenameEnd() {
42 if (!shouldTrack())
43 return;
44
45 NameInfo.BasenameRange.second = getCurrentPosition();
46}
47
48void TrackingOutputBuffer::updateScopeStart() {
49 if (!shouldTrack())
50 return;
51
52 NameInfo.ScopeRange.first = getCurrentPosition();
53}
54
55void TrackingOutputBuffer::updateScopeEnd() {
56 if (!shouldTrack())
57 return;
58
59 NameInfo.ScopeRange.second = getCurrentPosition();
60}
61
62void TrackingOutputBuffer::finalizeArgumentEnd() {
63 if (!canFinalize())
64 return;
65
66 NameInfo.ArgumentsRange.second = getCurrentPosition();
67}
68
69void TrackingOutputBuffer::finalizeQualifiersStart() {
70 if (!canFinalize())
71 return;
72
73 NameInfo.QualifiersRange.first = getCurrentPosition();
74}
75
76void TrackingOutputBuffer::finalizeQualifiersEnd() {
77 if (!canFinalize())
78 return;
79
80 NameInfo.QualifiersRange.second = getCurrentPosition();
81}
82
83void TrackingOutputBuffer::finalizeStart() {
84 if (!shouldTrack())
85 return;
86
87 NameInfo.ArgumentsRange.first = getCurrentPosition();
88
89 // If nothing has set the end of the basename yet (for example when
90 // printing templates), then the beginning of the arguments is the end of
91 // the basename.
92 if (NameInfo.BasenameRange.second == 0)
93 NameInfo.BasenameRange.second = getCurrentPosition();
94
95 assert(!shouldTrack());
96 assert(canFinalize());
97}
98
99void TrackingOutputBuffer::finalizeEnd() {
100 if (!canFinalize())
101 return;
102
103 if (NameInfo.ScopeRange.first > NameInfo.ScopeRange.second)
104 NameInfo.ScopeRange.second = NameInfo.ScopeRange.first;
105 NameInfo.BasenameRange.first = NameInfo.ScopeRange.second;
106}
107
108ScopedOverride<unsigned> TrackingOutputBuffer::enterFunctionTypePrinting() {
109 return {FunctionPrintingDepth, FunctionPrintingDepth + 1};
110}
111
112bool TrackingOutputBuffer::isPrintingTopLevelFunctionType() const {
113 return FunctionPrintingDepth == 1;
114}
115
116void TrackingOutputBuffer::printLeft(const Node &N) {
117 switch (N.getKind()) {
118 case Node::KFunctionType:
119 printLeftImpl(N: static_cast<const FunctionType &>(N));
120 break;
121 case Node::KFunctionEncoding:
122 printLeftImpl(N: static_cast<const FunctionEncoding &>(N));
123 break;
124 case Node::KNestedName:
125 printLeftImpl(N: static_cast<const NestedName &>(N));
126 break;
127 case Node::KNameWithTemplateArgs:
128 printLeftImpl(N: static_cast<const NameWithTemplateArgs &>(N));
129 break;
130 default:
131 OutputBuffer::printLeft(N);
132 }
133}
134
135void TrackingOutputBuffer::printRight(const Node &N) {
136 switch (N.getKind()) {
137 case Node::KFunctionType:
138 printRightImpl(N: static_cast<const FunctionType &>(N));
139 break;
140 case Node::KFunctionEncoding:
141 printRightImpl(N: static_cast<const FunctionEncoding &>(N));
142 break;
143 default:
144 OutputBuffer::printRight(N);
145 }
146}
147
148void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
149 auto Scoped = enterFunctionTypePrinting();
150 OutputBuffer::printLeft(N);
151}
152
153void TrackingOutputBuffer::printRightImpl(const FunctionType &N) {
154 auto Scoped = enterFunctionTypePrinting();
155 OutputBuffer::printRight(N);
156}
157
158void TrackingOutputBuffer::printLeftImpl(const FunctionEncoding &N) {
159 auto Scoped = enterFunctionTypePrinting();
160
161 const Node *Ret = N.getReturnType();
162 if (Ret) {
163 printLeft(N: *Ret);
164 if (!Ret->hasRHSComponent(OB&: *this))
165 *this += " ";
166 }
167
168 updateScopeStart();
169
170 N.getName()->print(OB&: *this);
171}
172
173void TrackingOutputBuffer::printRightImpl(const FunctionEncoding &N) {
174 auto Scoped = enterFunctionTypePrinting();
175 finalizeStart();
176
177 printOpen();
178 N.getParams().printWithComma(OB&: *this);
179 printClose();
180
181 finalizeArgumentEnd();
182
183 const Node *Ret = N.getReturnType();
184
185 if (Ret)
186 printRight(N: *Ret);
187
188 finalizeQualifiersStart();
189
190 auto CVQuals = N.getCVQuals();
191 auto RefQual = N.getRefQual();
192 auto *Attrs = N.getAttrs();
193 auto *Requires = N.getRequires();
194
195 if (CVQuals & QualConst)
196 *this += " const";
197 if (CVQuals & QualVolatile)
198 *this += " volatile";
199 if (CVQuals & QualRestrict)
200 *this += " restrict";
201 if (RefQual == FrefQualLValue)
202 *this += " &";
203 else if (RefQual == FrefQualRValue)
204 *this += " &&";
205 if (Attrs != nullptr)
206 Attrs->print(OB&: *this);
207 if (Requires != nullptr) {
208 *this += " requires ";
209 Requires->print(OB&: *this);
210 }
211
212 finalizeQualifiersEnd();
213 finalizeEnd();
214}
215
216void TrackingOutputBuffer::printLeftImpl(const NestedName &N) {
217 N.Qual->print(OB&: *this);
218 *this += "::";
219 updateScopeEnd();
220 N.Name->print(OB&: *this);
221 updateBasenameEnd();
222}
223
224void TrackingOutputBuffer::printLeftImpl(const NameWithTemplateArgs &N) {
225 N.Name->print(OB&: *this);
226 updateBasenameEnd();
227 N.TemplateArgs->print(OB&: *this);
228}
229
230} // namespace lldb_private
231

source code of lldb/source/Core/DemangledNameInfo.cpp