File indexing completed on 2026-05-10 08:43:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
0014 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
0015
0016 #include "llvm/ADT/SmallBitVector.h"
0017 #include "llvm/ADT/Twine.h"
0018 #include "llvm/DebugInfo/LogicalView/Core/LVStringPool.h"
0019 #include "llvm/Support/Debug.h"
0020 #include "llvm/Support/Format.h"
0021 #include "llvm/Support/Path.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 #include <cctype>
0024 #include <map>
0025 #include <sstream>
0026
0027 namespace llvm {
0028 namespace logicalview {
0029
0030
0031 LVStringPool &getStringPool();
0032
0033 using LVStringRefs = std::vector<StringRef>;
0034 using LVLexicalComponent = std::tuple<StringRef, StringRef>;
0035 using LVLexicalIndex =
0036 std::tuple<LVStringRefs::size_type, LVStringRefs::size_type>;
0037
0038
0039 template <typename T> class LVProperties {
0040 SmallBitVector Bits = SmallBitVector(static_cast<unsigned>(T::LastEntry) + 1);
0041
0042 public:
0043 LVProperties() = default;
0044
0045 void set(T Idx) { Bits[static_cast<unsigned>(Idx)] = 1; }
0046 void reset(T Idx) { Bits[static_cast<unsigned>(Idx)] = 0; }
0047 bool get(T Idx) const { return Bits[static_cast<unsigned>(Idx)]; }
0048 };
0049
0050
0051
0052
0053
0054
0055 #define BOOL_BIT(FAMILY, ENUM, FIELD) \
0056 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
0057 void set##FIELD() { FAMILY.set(ENUM::FIELD); } \
0058 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
0059
0060 #define BOOL_BIT_1(FAMILY, ENUM, FIELD, F1) \
0061 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
0062 void set##FIELD() { \
0063 FAMILY.set(ENUM::FIELD); \
0064 set##F1(); \
0065 } \
0066 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
0067
0068 #define BOOL_BIT_2(FAMILY, ENUM, FIELD, F1, F2) \
0069 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
0070 void set##FIELD() { \
0071 FAMILY.set(ENUM::FIELD); \
0072 set##F1(); \
0073 set##F2(); \
0074 } \
0075 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
0076
0077 #define BOOL_BIT_3(FAMILY, ENUM, FIELD, F1, F2, F3) \
0078 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
0079 void set##FIELD() { \
0080 FAMILY.set(ENUM::FIELD); \
0081 set##F1(); \
0082 set##F2(); \
0083 set##F3(); \
0084 } \
0085 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
0086
0087
0088 #define PROPERTY(ENUM, FIELD) BOOL_BIT(Properties, ENUM, FIELD)
0089 #define PROPERTY_1(ENUM, FIELD, F1) BOOL_BIT_1(Properties, ENUM, FIELD, F1)
0090 #define PROPERTY_2(ENUM, FIELD, F1, F2) \
0091 BOOL_BIT_2(Properties, ENUM, FIELD, F1, F2)
0092 #define PROPERTY_3(ENUM, FIELD, F1, F2, F3) \
0093 BOOL_BIT_3(Properties, ENUM, FIELD, F1, F2, F3)
0094
0095
0096 #define KIND(ENUM, FIELD) BOOL_BIT(Kinds, ENUM, FIELD)
0097 #define KIND_1(ENUM, FIELD, F1) BOOL_BIT_1(Kinds, ENUM, FIELD, F1)
0098 #define KIND_2(ENUM, FIELD, F1, F2) BOOL_BIT_2(Kinds, ENUM, FIELD, F1, F2)
0099 #define KIND_3(ENUM, FIELD, F1, F2, F3) \
0100 BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3)
0101
0102 const int HEX_WIDTH = 12;
0103 inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH,
0104 bool Upper = false) {
0105 return format_hex(N, Width, Upper);
0106 }
0107
0108
0109 inline std::string hexString(uint64_t Value, size_t Width = HEX_WIDTH) {
0110 std::string String;
0111 raw_string_ostream Stream(String);
0112 Stream << hexValue(Value, Width, false);
0113 return String;
0114 }
0115
0116
0117 inline std::string hexSquareString(uint64_t Value) {
0118 return (Twine("[") + Twine(hexString(Value)) + Twine("]")).str();
0119 }
0120
0121
0122 template <typename... Args>
0123 std::string formatAttributes(const StringRef First, Args... Others) {
0124 const auto List = {First, Others...};
0125 std::stringstream Stream;
0126 size_t Size = 0;
0127 for (const StringRef &Item : List) {
0128 Stream << (Size ? " " : "") << Item.str();
0129 Size = Item.size();
0130 }
0131 Stream << (Size ? " " : "");
0132 return Stream.str();
0133 }
0134
0135
0136 template <typename MapType, typename KeyType, typename ValueType>
0137 void addItem(MapType *Map, KeyType Key, ValueType Value) {
0138 (*Map)[Key].push_back(Value);
0139 }
0140
0141
0142 template <typename FirstKeyType, typename SecondKeyType, typename ValueType>
0143 class LVDoubleMap {
0144 static_assert(std::is_pointer<ValueType>::value,
0145 "ValueType must be a pointer.");
0146 using LVSecondMapType = std::map<SecondKeyType, ValueType>;
0147 using LVFirstMapType =
0148 std::map<FirstKeyType, std::unique_ptr<LVSecondMapType>>;
0149 using LVAuxMapType = std::map<SecondKeyType, FirstKeyType>;
0150 using LVValueTypes = std::vector<ValueType>;
0151 LVFirstMapType FirstMap;
0152 LVAuxMapType AuxMap;
0153
0154 public:
0155 void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) {
0156 typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey);
0157 if (FirstIter == FirstMap.end()) {
0158 auto SecondMapSP = std::make_unique<LVSecondMapType>();
0159 SecondMapSP->emplace(SecondKey, Value);
0160 FirstMap.emplace(FirstKey, std::move(SecondMapSP));
0161 } else {
0162 LVSecondMapType *SecondMap = FirstIter->second.get();
0163 if (SecondMap->find(SecondKey) == SecondMap->end())
0164 SecondMap->emplace(SecondKey, Value);
0165 }
0166
0167 typename LVAuxMapType::iterator AuxIter = AuxMap.find(SecondKey);
0168 if (AuxIter == AuxMap.end()) {
0169 AuxMap.emplace(SecondKey, FirstKey);
0170 }
0171 }
0172
0173 LVSecondMapType *findMap(FirstKeyType FirstKey) const {
0174 typename LVFirstMapType::const_iterator FirstIter = FirstMap.find(FirstKey);
0175 if (FirstIter == FirstMap.end())
0176 return nullptr;
0177
0178 return FirstIter->second.get();
0179 }
0180
0181 ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const {
0182 LVSecondMapType *SecondMap = findMap(FirstKey);
0183 if (!SecondMap)
0184 return nullptr;
0185
0186 typename LVSecondMapType::const_iterator SecondIter =
0187 SecondMap->find(SecondKey);
0188 return (SecondIter != SecondMap->end()) ? SecondIter->second : nullptr;
0189 }
0190
0191 ValueType find(SecondKeyType SecondKey) const {
0192 typename LVAuxMapType::const_iterator AuxIter = AuxMap.find(SecondKey);
0193 if (AuxIter == AuxMap.end())
0194 return nullptr;
0195 return find(AuxIter->second, SecondKey);
0196 }
0197
0198
0199 LVValueTypes find() const {
0200 LVValueTypes Values;
0201 if (FirstMap.empty())
0202 return Values;
0203 for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) {
0204 LVSecondMapType &SecondMap = *FirstEntry.second;
0205 for (typename LVSecondMapType::const_reference SecondEntry : SecondMap)
0206 Values.push_back(SecondEntry.second);
0207 }
0208 return Values;
0209 }
0210 };
0211
0212
0213 std::string transformPath(StringRef Path);
0214 std::string flattenedFilePath(StringRef Path);
0215
0216 inline std::string formattedKind(StringRef Kind) {
0217 return (Twine("{") + Twine(Kind) + Twine("}")).str();
0218 }
0219
0220 inline std::string formattedName(StringRef Name) {
0221 return (Twine("'") + Twine(Name) + Twine("'")).str();
0222 }
0223
0224 inline std::string formattedNames(StringRef Name1, StringRef Name2) {
0225 return (Twine("'") + Twine(Name1) + Twine(Name2) + Twine("'")).str();
0226 }
0227
0228
0229
0230
0231
0232 LVLexicalComponent getInnerComponent(StringRef Name);
0233 LVStringRefs getAllLexicalComponents(StringRef Name);
0234 std::string getScopedName(const LVStringRefs &Components,
0235 StringRef BaseName = {});
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 inline uint16_t getCodeViewOperationCode(uint8_t Code) { return 0x1100 | Code; }
0251
0252 }
0253 }
0254
0255 #endif