Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- LVSupport.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
// This file defines support functions.
10
//
11
//===----------------------------------------------------------------------===//
12
 
13
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
14
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
15
 
16
#include "llvm/ADT/SmallBitVector.h"
17
#include "llvm/ADT/SmallString.h"
18
#include "llvm/ADT/Twine.h"
19
#include "llvm/DebugInfo/LogicalView/Core/LVStringPool.h"
20
#include "llvm/Support/Debug.h"
21
#include "llvm/Support/Format.h"
22
#include "llvm/Support/Path.h"
23
#include "llvm/Support/raw_ostream.h"
24
#include <cctype>
25
#include <map>
26
#include <sstream>
27
 
28
namespace llvm {
29
namespace logicalview {
30
 
31
// Returns the unique string pool instance.
32
LVStringPool &getStringPool();
33
 
34
template <typename T>
35
using TypeIsValid = std::bool_constant<std::is_pointer<T>::value>;
36
 
37
// Utility class to help memory management and perform an automatic cleaning.
38
template <typename T, unsigned N = 8>
39
class LVAutoSmallVector : public SmallVector<T, N> {
40
  static_assert(TypeIsValid<T>::value, "T must be a pointer type");
41
 
42
public:
43
  using iterator = typename SmallVector<T, N>::iterator;
44
  LVAutoSmallVector() : SmallVector<T, N>::SmallVector() {}
45
 
46
  ~LVAutoSmallVector() {
47
    // Destroy the constructed elements in the vector.
48
    for (auto *Item : *this)
49
      delete Item;
50
  }
51
};
52
 
53
// Used to record specific characteristics about the objects.
54
template <typename T> class LVProperties {
55
  SmallBitVector Bits = SmallBitVector(static_cast<unsigned>(T::LastEntry) + 1);
56
 
57
public:
58
  LVProperties() = default;
59
 
60
  void set(T Idx) { Bits[static_cast<unsigned>(Idx)] = 1; }
61
  void reset(T Idx) { Bits[static_cast<unsigned>(Idx)] = 0; }
62
  bool get(T Idx) const { return Bits[static_cast<unsigned>(Idx)]; }
63
};
64
 
65
// Generate get, set and reset 'bool' functions for LVProperties instances.
66
// FAMILY: instance name.
67
// ENUM: enumeration instance.
68
// FIELD: enumerator instance.
69
// F1, F2, F3: optional 'set' functions to be called.
70
#define BOOL_BIT(FAMILY, ENUM, FIELD)                                          \
71
  bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); }                  \
72
  void set##FIELD() { FAMILY.set(ENUM::FIELD); }                               \
73
  void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
74
 
75
#define BOOL_BIT_1(FAMILY, ENUM, FIELD, F1)                                    \
76
  bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); }                  \
77
  void set##FIELD() {                                                          \
78
    FAMILY.set(ENUM::FIELD);                                                   \
79
    set##F1();                                                                 \
80
  }                                                                            \
81
  void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
82
 
83
#define BOOL_BIT_2(FAMILY, ENUM, FIELD, F1, F2)                                \
84
  bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); }                  \
85
  void set##FIELD() {                                                          \
86
    FAMILY.set(ENUM::FIELD);                                                   \
87
    set##F1();                                                                 \
88
    set##F2();                                                                 \
89
  }                                                                            \
90
  void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
91
 
92
#define BOOL_BIT_3(FAMILY, ENUM, FIELD, F1, F2, F3)                            \
93
  bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); }                  \
94
  void set##FIELD() {                                                          \
95
    FAMILY.set(ENUM::FIELD);                                                   \
96
    set##F1();                                                                 \
97
    set##F2();                                                                 \
98
    set##F3();                                                                 \
99
  }                                                                            \
100
  void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
101
 
102
// Generate get, set and reset functions for 'properties'.
103
#define PROPERTY(ENUM, FIELD) BOOL_BIT(Properties, ENUM, FIELD)
104
#define PROPERTY_1(ENUM, FIELD, F1) BOOL_BIT_1(Properties, ENUM, FIELD, F1)
105
#define PROPERTY_2(ENUM, FIELD, F1, F2)                                        \
106
  BOOL_BIT_2(Properties, ENUM, FIELD, F1, F2)
107
#define PROPERTY_3(ENUM, FIELD, F1, F2, F3)                                    \
108
  BOOL_BIT_3(Properties, ENUM, FIELD, F1, F2, F3)
109
 
110
// Generate get, set and reset functions for 'kinds'.
111
#define KIND(ENUM, FIELD) BOOL_BIT(Kinds, ENUM, FIELD)
112
#define KIND_1(ENUM, FIELD, F1) BOOL_BIT_1(Kinds, ENUM, FIELD, F1)
113
#define KIND_2(ENUM, FIELD, F1, F2) BOOL_BIT_2(Kinds, ENUM, FIELD, F1, F2)
114
#define KIND_3(ENUM, FIELD, F1, F2, F3)                                        \
115
  BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3)
116
 
117
const int HEX_WIDTH = 12;
118
inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH,
119
                                bool Upper = false) {
120
  return format_hex(N, Width, Upper);
121
}
122
 
123
// Output the hexadecimal representation of 'Value' using '[0x%08x]' format.
124
inline std::string hexString(uint64_t Value, size_t Width = HEX_WIDTH) {
125
  std::string String;
126
  raw_string_ostream Stream(String);
127
  Stream << hexValue(Value, Width, false);
128
  return Stream.str();
129
}
130
 
131
// Get a hexadecimal string representation for the given value.
132
inline std::string hexSquareString(uint64_t Value) {
133
  return (Twine("[") + Twine(hexString(Value)) + Twine("]")).str();
134
}
135
 
136
// Return a string with the First and Others separated by spaces.
137
template <typename... Args>
138
std::string formatAttributes(const StringRef First, Args... Others) {
139
  const auto List = {First, Others...};
140
  std::stringstream Stream;
141
  size_t Size = 0;
142
  for (const StringRef &Item : List) {
143
    Stream << (Size ? " " : "") << Item.str();
144
    Size = Item.size();
145
  }
146
  Stream << (Size ? " " : "");
147
  return Stream.str();
148
}
149
 
150
// Add an item to a map with second being a list.
151
template <typename MapType, typename ListType, typename KeyType,
152
          typename ValueType>
153
void addItem(MapType *Map, KeyType Key, ValueType Value) {
154
  ListType *List = nullptr;
155
  typename MapType::const_iterator Iter = Map->find(Key);
156
  if (Iter != Map->end())
157
    List = Iter->second;
158
  else {
159
    List = new ListType();
160
    Map->emplace(Key, List);
161
  }
162
  List->push_back(Value);
163
}
164
 
165
// Delete the map contained list.
166
template <typename MapType> void deleteList(MapType &Map) {
167
  for (typename MapType::const_reference Entry : Map)
168
    delete Entry.second;
169
}
170
 
171
// Double map data structure.
172
template <typename FirstKeyType, typename SecondKeyType, typename ValueType>
173
class LVDoubleMap {
174
  static_assert(std::is_pointer<ValueType>::value,
175
                "ValueType must be a pointer.");
176
  using LVSecondMapType = std::map<SecondKeyType, ValueType>;
177
  using LVFirstMapType = std::map<FirstKeyType, LVSecondMapType *>;
178
  using LVAuxMapType = std::map<SecondKeyType, FirstKeyType>;
179
  using LVValueTypes = std::vector<ValueType>;
180
  LVFirstMapType FirstMap;
181
  LVAuxMapType AuxMap;
182
 
183
public:
184
  LVDoubleMap() = default;
185
  ~LVDoubleMap() {
186
    for (auto &Entry : FirstMap)
187
      delete Entry.second;
188
  }
189
 
190
  void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) {
191
    LVSecondMapType *SecondMap = nullptr;
192
    typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey);
193
    if (FirstIter == FirstMap.end()) {
194
      SecondMap = new LVSecondMapType();
195
      FirstMap.emplace(FirstKey, SecondMap);
196
    } else {
197
      SecondMap = FirstIter->second;
198
    }
199
 
200
    assert(SecondMap && "SecondMap is null.");
201
    if (SecondMap && SecondMap->find(SecondKey) == SecondMap->end())
202
      SecondMap->emplace(SecondKey, Value);
203
 
204
    typename LVAuxMapType::iterator AuxIter = AuxMap.find(SecondKey);
205
    if (AuxIter == AuxMap.end()) {
206
      AuxMap.emplace(SecondKey, FirstKey);
207
    }
208
  }
209
 
210
  LVSecondMapType *findMap(FirstKeyType FirstKey) const {
211
    typename LVFirstMapType::const_iterator FirstIter = FirstMap.find(FirstKey);
212
    if (FirstIter == FirstMap.end())
213
      return nullptr;
214
 
215
    LVSecondMapType *SecondMap = FirstIter->second;
216
    return SecondMap;
217
  }
218
 
219
  ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const {
220
    LVSecondMapType *SecondMap = findMap(FirstKey);
221
    if (!SecondMap)
222
      return nullptr;
223
 
224
    typename LVSecondMapType::const_iterator SecondIter =
225
        SecondMap->find(SecondKey);
226
    return (SecondIter != SecondMap->end()) ? SecondIter->second : nullptr;
227
  }
228
 
229
  ValueType find(SecondKeyType SecondKey) const {
230
    typename LVAuxMapType::const_iterator AuxIter = AuxMap.find(SecondKey);
231
    if (AuxIter == AuxMap.end())
232
      return nullptr;
233
    return find(AuxIter->second, SecondKey);
234
  }
235
 
236
  // Return a vector with all the 'ValueType' values.
237
  LVValueTypes find() const {
238
    LVValueTypes Values;
239
    if (FirstMap.empty())
240
      return Values;
241
    for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) {
242
      LVSecondMapType *SecondMap = FirstEntry.second;
243
      for (typename LVSecondMapType::const_reference SecondEntry : *SecondMap)
244
        Values.push_back(SecondEntry.second);
245
    }
246
    return Values;
247
  }
248
};
249
 
250
// Unified and flattened pathnames.
251
std::string transformPath(StringRef Path);
252
std::string flattenedFilePath(StringRef Path);
253
 
254
inline std::string formattedKind(StringRef Kind) {
255
  return (Twine("{") + Twine(Kind) + Twine("}")).str();
256
}
257
 
258
inline std::string formattedName(StringRef Name) {
259
  return (Twine("'") + Twine(Name) + Twine("'")).str();
260
}
261
 
262
inline std::string formattedNames(StringRef Name1, StringRef Name2) {
263
  return (Twine("'") + Twine(Name1) + Twine(Name2) + Twine("'")).str();
264
}
265
 
266
// These are the values assigned to the debug location record IDs.
267
// See DebugInfo/CodeView/CodeViewSymbols.def.
268
// S_DEFRANGE                               0x113f
269
// S_DEFRANGE_SUBFIELD                      0x1140
270
// S_DEFRANGE_REGISTER                      0x1141
271
// S_DEFRANGE_FRAMEPOINTER_REL              0x1142
272
// S_DEFRANGE_SUBFIELD_REGISTER             0x1143
273
// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE   0x1144
274
// S_DEFRANGE_REGISTER_REL                  0x1145
275
// When recording CodeView debug location, the above values are truncated
276
// to a uint8_t value in order to fit the 'OpCode' used for the logical
277
// debug location operations.
278
// Return the original CodeView enum value.
279
inline uint16_t getCodeViewOperationCode(uint8_t Code) { return 0x1100 | Code; }
280
 
281
} // end namespace logicalview
282
} // end namespace llvm
283
 
284
#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H