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() const15bool 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() const28bool 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()41void TrackingOutputBuffer::updateBasenameEnd() { 42 if (!shouldTrack()) 43 return; 44 45 NameInfo.BasenameRange.second = getCurrentPosition(); 46 } 47 updateScopeStart()48void TrackingOutputBuffer::updateScopeStart() { 49 if (!shouldTrack()) 50 return; 51 52 NameInfo.ScopeRange.first = getCurrentPosition(); 53 } 54 updateScopeEnd()55void TrackingOutputBuffer::updateScopeEnd() { 56 if (!shouldTrack()) 57 return; 58 59 NameInfo.ScopeRange.second = getCurrentPosition(); 60 } 61 finalizeArgumentEnd()62void TrackingOutputBuffer::finalizeArgumentEnd() { 63 if (!canFinalize()) 64 return; 65 66 NameInfo.ArgumentsRange.second = getCurrentPosition(); 67 } 68 finalizeQualifiersStart()69void TrackingOutputBuffer::finalizeQualifiersStart() { 70 if (!canFinalize()) 71 return; 72 73 NameInfo.QualifiersRange.first = getCurrentPosition(); 74 } 75 finalizeQualifiersEnd()76void TrackingOutputBuffer::finalizeQualifiersEnd() { 77 if (!canFinalize()) 78 return; 79 80 NameInfo.QualifiersRange.second = getCurrentPosition(); 81 } 82 finalizeStart()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 finalizeEnd()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 enterFunctionTypePrinting()108ScopedOverride<unsigned> TrackingOutputBuffer::enterFunctionTypePrinting() { 109 return {FunctionPrintingDepth, FunctionPrintingDepth + 1}; 110 } 111 isPrintingTopLevelFunctionType() const112bool TrackingOutputBuffer::isPrintingTopLevelFunctionType() const { 113 return FunctionPrintingDepth == 1; 114 } 115 printLeft(const Node & N)116void 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)135void 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)148void TrackingOutputBuffer::printLeftImpl(const FunctionType &N) { 149 auto Scoped = enterFunctionTypePrinting(); 150 OutputBuffer::printLeft(N); 151 } 152 printRightImpl(const FunctionType & N)153void TrackingOutputBuffer::printRightImpl(const FunctionType &N) { 154 auto Scoped = enterFunctionTypePrinting(); 155 OutputBuffer::printRight(N); 156 } 157 printLeftImpl(const FunctionEncoding & N)158void 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)173void 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)216void 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)224void TrackingOutputBuffer::printLeftImpl(const NameWithTemplateArgs &N) { 225 N.Name->print(*this); 226 updateBasenameEnd(); 227 N.TemplateArgs->print(*this); 228 } 229 230 } // namespace lldb_private 231