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 | |
11 | using namespace llvm::itanium_demangle; |
12 | |
13 | namespace lldb_private { |
14 | |
15 | bool 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 | |
28 | bool 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 | |
41 | void TrackingOutputBuffer::updateBasenameEnd() { |
42 | if (!shouldTrack()) |
43 | return; |
44 | |
45 | NameInfo.BasenameRange.second = getCurrentPosition(); |
46 | } |
47 | |
48 | void TrackingOutputBuffer::updateScopeStart() { |
49 | if (!shouldTrack()) |
50 | return; |
51 | |
52 | NameInfo.ScopeRange.first = getCurrentPosition(); |
53 | } |
54 | |
55 | void TrackingOutputBuffer::updateScopeEnd() { |
56 | if (!shouldTrack()) |
57 | return; |
58 | |
59 | NameInfo.ScopeRange.second = getCurrentPosition(); |
60 | } |
61 | |
62 | void TrackingOutputBuffer::finalizeArgumentEnd() { |
63 | if (!canFinalize()) |
64 | return; |
65 | |
66 | NameInfo.ArgumentsRange.second = getCurrentPosition(); |
67 | } |
68 | |
69 | void TrackingOutputBuffer::finalizeQualifiersStart() { |
70 | if (!canFinalize()) |
71 | return; |
72 | |
73 | NameInfo.QualifiersRange.first = getCurrentPosition(); |
74 | } |
75 | |
76 | void TrackingOutputBuffer::finalizeQualifiersEnd() { |
77 | if (!canFinalize()) |
78 | return; |
79 | |
80 | NameInfo.QualifiersRange.second = getCurrentPosition(); |
81 | } |
82 | |
83 | void 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 | |
99 | void 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 | |
108 | ScopedOverride<unsigned> TrackingOutputBuffer::enterFunctionTypePrinting() { |
109 | return {FunctionPrintingDepth, FunctionPrintingDepth + 1}; |
110 | } |
111 | |
112 | bool TrackingOutputBuffer::isPrintingTopLevelFunctionType() const { |
113 | return FunctionPrintingDepth == 1; |
114 | } |
115 | |
116 | void 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 | |
135 | void 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 | |
148 | void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) { |
149 | auto Scoped = enterFunctionTypePrinting(); |
150 | OutputBuffer::printLeft(N); |
151 | } |
152 | |
153 | void TrackingOutputBuffer::printRightImpl(const FunctionType &N) { |
154 | auto Scoped = enterFunctionTypePrinting(); |
155 | OutputBuffer::printRight(N); |
156 | } |
157 | |
158 | void 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 | |
173 | void 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 | |
216 | void 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 | |
224 | void 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 |