Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  285.