1 //===-- DemangledNameInfo.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 #ifndef LLDB_CORE_DEMANGLEDNAMEINFO_H 10 #define LLDB_CORE_DEMANGLEDNAMEINFO_H 11 12 #include "llvm/Demangle/ItaniumDemangle.h" 13 #include "llvm/Demangle/Utility.h" 14 15 #include <cstddef> 16 #include <utility> 17 18 namespace lldb_private { 19 20 /// Stores information about where certain portions of a demangled 21 /// function name begin and end. 22 struct DemangledNameInfo { 23 /// A [start, end) pair for the function basename. 24 /// The basename is the name without scope qualifiers 25 /// and without template parameters. E.g., 26 /// \code{.cpp} 27 /// void foo::bar<int>::someFunc<float>(int) const && 28 /// ^ ^ 29 /// start end 30 /// \endcode 31 std::pair<size_t, size_t> BasenameRange; 32 33 /// A [start, end) pair for the function scope qualifiers. 34 /// E.g., for 35 /// \code{.cpp} 36 /// void foo::bar<int>::qux<float>(int) const && 37 /// ^ ^ 38 /// start end 39 /// \endcode 40 std::pair<size_t, size_t> ScopeRange; 41 42 /// Indicates the [start, end) of the function argument list. 43 /// E.g., 44 /// \code{.cpp} 45 /// int (*getFunc<float>(float, double))(int, int) 46 /// ^ ^ 47 /// start end 48 /// \endcode 49 std::pair<size_t, size_t> ArgumentsRange; 50 51 /// Indicates the [start, end) of the function qualifiers 52 /// (e.g., CV-qualifiers, reference qualifiers, requires clauses). 53 /// 54 /// E.g., 55 /// \code{.cpp} 56 /// void foo::bar<int>::qux<float>(int) const && 57 /// ^ ^ 58 /// start end 59 /// \endcode 60 std::pair<size_t, size_t> QualifiersRange; 61 62 /// Indicates the [start, end) of the function's prefix. This is a 63 /// catch-all range for anything that is not tracked by the rest of 64 /// the pairs. 65 std::pair<size_t, size_t> PrefixRange; 66 67 /// Indicates the [start, end) of the function's suffix. This is a 68 /// catch-all range for anything that is not tracked by the rest of 69 /// the pairs. 70 std::pair<size_t, size_t> SuffixRange; 71 72 /// Returns \c true if this object holds a valid basename range. hasBasenameDemangledNameInfo73 bool hasBasename() const { 74 // A function always has a name. 75 return BasenameRange.second > BasenameRange.first; 76 } 77 78 /// Returns \c true if this object holds a valid scope range. hasScopeDemangledNameInfo79 bool hasScope() const { return ScopeRange.second >= ScopeRange.first; } 80 81 /// Returns \c true if this object holds a valid arguments range. hasArgumentsDemangledNameInfo82 bool hasArguments() const { 83 return ArgumentsRange.second >= ArgumentsRange.first; 84 } 85 86 /// Returns \c true if this object holds a valid qualifiers range. hasQualifiersDemangledNameInfo87 bool hasQualifiers() const { 88 return QualifiersRange.second >= QualifiersRange.first; 89 } 90 91 /// Returns \c true if this object holds a valid prefix range. hasPrefixDemangledNameInfo92 bool hasPrefix() const { return PrefixRange.second >= PrefixRange.first; } 93 94 /// Returns \c true if this object holds a valid suffix range. hasSuffixDemangledNameInfo95 bool hasSuffix() const { return SuffixRange.second >= SuffixRange.first; } 96 }; 97 98 /// An OutputBuffer which keeps a record of where certain parts of a 99 /// demangled name begin/end (e.g., basename, scope, argument list, etc.). 100 /// The tracking occurs during printing of the Itanium demangle tree. 101 /// 102 /// Usage: 103 /// \code{.cpp} 104 /// 105 /// Node *N = mangling_parser.parseType(); 106 /// 107 /// TrackingOutputBuffer buffer; 108 /// N->printLeft(OB); 109 /// 110 /// assert (buffer.NameInfo.hasBasename()); 111 /// 112 /// \endcode 113 struct TrackingOutputBuffer : public llvm::itanium_demangle::OutputBuffer { 114 using OutputBuffer::OutputBuffer; 115 116 /// Holds information about the demangled name that is 117 /// being printed into this buffer. 118 DemangledNameInfo NameInfo; 119 120 void printLeft(const llvm::itanium_demangle::Node &N) override; 121 void printRight(const llvm::itanium_demangle::Node &N) override; 122 123 private: 124 void printLeftImpl(const llvm::itanium_demangle::FunctionType &N); 125 void printRightImpl(const llvm::itanium_demangle::FunctionType &N); 126 127 void printLeftImpl(const llvm::itanium_demangle::FunctionEncoding &N); 128 void printRightImpl(const llvm::itanium_demangle::FunctionEncoding &N); 129 130 void printLeftImpl(const llvm::itanium_demangle::NestedName &N); 131 void printLeftImpl(const llvm::itanium_demangle::NameWithTemplateArgs &N); 132 133 /// Called whenever we start printing a function type in the Itanium 134 /// mangling scheme. Examples include \ref FunctionEncoding, \ref 135 /// FunctionType, etc. 136 /// 137 /// \returns A ScopedOverride which will update the nesting depth of 138 /// currently printed function types on destruction. 139 [[nodiscard]] llvm::itanium_demangle::ScopedOverride<unsigned> 140 enterFunctionTypePrinting(); 141 142 /// Returns \c true if we're not printing any nested function types, 143 /// just a \ref FunctionEncoding in the Itanium mangling scheme. 144 bool isPrintingTopLevelFunctionType() const; 145 146 /// If this object \ref shouldTrack, then update the end of 147 /// the basename range to the current \c OB position. 148 void updateBasenameEnd(); 149 150 /// If this object \ref shouldTrack, then update the beginning 151 /// of the scope range to the current \c OB position. 152 void updateScopeStart(); 153 154 /// If this object \ref shouldTrack, then update the end of 155 /// the scope range to the current \c OB position. 156 void updateScopeEnd(); 157 158 /// Returns \c true if the members of this object can be 159 /// updated. E.g., when we're printing nested template 160 /// arguments, we don't need to be tracking basename 161 /// locations. 162 bool shouldTrack() const; 163 164 /// Helpers called to track beginning and end of the function 165 /// arguments. 166 void finalizeArgumentEnd(); 167 void finalizeStart(); 168 void finalizeEnd(); 169 void finalizeQualifiersStart(); 170 void finalizeQualifiersEnd(); 171 172 /// Helper used in the finalize APIs. 173 bool canFinalize() const; 174 175 /// Incremented each time we start printing a function type node 176 /// in the Itanium mangling scheme (e.g., \ref FunctionEncoding 177 /// or \ref FunctionType). 178 unsigned FunctionPrintingDepth = 0; 179 }; 180 } // namespace lldb_private 181 182 #endif // LLDB_CORE_DEMANGLEDNAMEINFO_H 183