xref: /freebsd/contrib/llvm-project/lldb/source/Core/DemangledNameInfo.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
shouldTrack() const15 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 
canFinalize() const28 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 
updateBasenameEnd()41 void TrackingOutputBuffer::updateBasenameEnd() {
42   if (!shouldTrack())
43     return;
44 
45   NameInfo.BasenameRange.second = getCurrentPosition();
46 }
47 
updateScopeStart()48 void TrackingOutputBuffer::updateScopeStart() {
49   if (!shouldTrack())
50     return;
51 
52   NameInfo.ScopeRange.first = getCurrentPosition();
53 }
54 
updateScopeEnd()55 void TrackingOutputBuffer::updateScopeEnd() {
56   if (!shouldTrack())
57     return;
58 
59   NameInfo.ScopeRange.second = getCurrentPosition();
60 }
61 
finalizeArgumentEnd()62 void TrackingOutputBuffer::finalizeArgumentEnd() {
63   if (!canFinalize())
64     return;
65 
66   NameInfo.ArgumentsRange.second = getCurrentPosition();
67 }
68 
finalizeQualifiersStart()69 void TrackingOutputBuffer::finalizeQualifiersStart() {
70   if (!canFinalize())
71     return;
72 
73   NameInfo.QualifiersRange.first = getCurrentPosition();
74 }
75 
finalizeQualifiersEnd()76 void TrackingOutputBuffer::finalizeQualifiersEnd() {
77   if (!canFinalize())
78     return;
79 
80   NameInfo.QualifiersRange.second = getCurrentPosition();
81 }
82 
finalizeStart()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 
finalizeEnd()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 
enterFunctionTypePrinting()108 ScopedOverride<unsigned> TrackingOutputBuffer::enterFunctionTypePrinting() {
109   return {FunctionPrintingDepth, FunctionPrintingDepth + 1};
110 }
111 
isPrintingTopLevelFunctionType() const112 bool TrackingOutputBuffer::isPrintingTopLevelFunctionType() const {
113   return FunctionPrintingDepth == 1;
114 }
115 
printLeft(const Node & N)116 void TrackingOutputBuffer::printLeft(const Node &N) {
117   switch (N.getKind()) {
118   case Node::KFunctionType:
119     printLeftImpl(static_cast<const FunctionType &>(N));
120     break;
121   case Node::KFunctionEncoding:
122     printLeftImpl(static_cast<const FunctionEncoding &>(N));
123     break;
124   case Node::KNestedName:
125     printLeftImpl(static_cast<const NestedName &>(N));
126     break;
127   case Node::KNameWithTemplateArgs:
128     printLeftImpl(static_cast<const NameWithTemplateArgs &>(N));
129     break;
130   default:
131     OutputBuffer::printLeft(N);
132   }
133 }
134 
printRight(const Node & N)135 void TrackingOutputBuffer::printRight(const Node &N) {
136   switch (N.getKind()) {
137   case Node::KFunctionType:
138     printRightImpl(static_cast<const FunctionType &>(N));
139     break;
140   case Node::KFunctionEncoding:
141     printRightImpl(static_cast<const FunctionEncoding &>(N));
142     break;
143   default:
144     OutputBuffer::printRight(N);
145   }
146 }
147 
printLeftImpl(const FunctionType & N)148 void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) {
149   auto Scoped = enterFunctionTypePrinting();
150   OutputBuffer::printLeft(N);
151 }
152 
printRightImpl(const FunctionType & N)153 void TrackingOutputBuffer::printRightImpl(const FunctionType &N) {
154   auto Scoped = enterFunctionTypePrinting();
155   OutputBuffer::printRight(N);
156 }
157 
printLeftImpl(const FunctionEncoding & N)158 void TrackingOutputBuffer::printLeftImpl(const FunctionEncoding &N) {
159   auto Scoped = enterFunctionTypePrinting();
160 
161   const Node *Ret = N.getReturnType();
162   if (Ret) {
163     printLeft(*Ret);
164     if (!Ret->hasRHSComponent(*this))
165       *this += " ";
166   }
167 
168   updateScopeStart();
169 
170   N.getName()->print(*this);
171 }
172 
printRightImpl(const FunctionEncoding & N)173 void TrackingOutputBuffer::printRightImpl(const FunctionEncoding &N) {
174   auto Scoped = enterFunctionTypePrinting();
175   finalizeStart();
176 
177   printOpen();
178   N.getParams().printWithComma(*this);
179   printClose();
180 
181   finalizeArgumentEnd();
182 
183   const Node *Ret = N.getReturnType();
184 
185   if (Ret)
186     printRight(*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(*this);
207   if (Requires != nullptr) {
208     *this += " requires ";
209     Requires->print(*this);
210   }
211 
212   finalizeQualifiersEnd();
213   finalizeEnd();
214 }
215 
printLeftImpl(const NestedName & N)216 void TrackingOutputBuffer::printLeftImpl(const NestedName &N) {
217   N.Qual->print(*this);
218   *this += "::";
219   updateScopeEnd();
220   N.Name->print(*this);
221   updateBasenameEnd();
222 }
223 
printLeftImpl(const NameWithTemplateArgs & N)224 void TrackingOutputBuffer::printLeftImpl(const NameWithTemplateArgs &N) {
225   N.Name->print(*this);
226   updateBasenameEnd();
227   N.TemplateArgs->print(*this);
228 }
229 
230 } // namespace lldb_private
231