Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- TypeIndex.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 LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
  10. #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
  11.  
  12. #include "llvm/ADT/DenseMapInfo.h"
  13. #include "llvm/Support/Endian.h"
  14. #include <cassert>
  15. #include <cinttypes>
  16.  
  17. namespace llvm {
  18.  
  19. class ScopedPrinter;
  20. class StringRef;
  21.  
  22. namespace codeview {
  23.  
  24. class TypeCollection;
  25.  
  26. enum class SimpleTypeKind : uint32_t {
  27.   None = 0x0000,          // uncharacterized type (no type)
  28.   Void = 0x0003,          // void
  29.   NotTranslated = 0x0007, // type not translated by cvpack
  30.   HResult = 0x0008,       // OLE/COM HRESULT
  31.  
  32.   SignedCharacter = 0x0010,   // 8 bit signed
  33.   UnsignedCharacter = 0x0020, // 8 bit unsigned
  34.   NarrowCharacter = 0x0070,   // really a char
  35.   WideCharacter = 0x0071,     // wide char
  36.   Character16 = 0x007a,       // char16_t
  37.   Character32 = 0x007b,       // char32_t
  38.   Character8 = 0x007c,        // char8_t
  39.  
  40.   SByte = 0x0068,       // 8 bit signed int
  41.   Byte = 0x0069,        // 8 bit unsigned int
  42.   Int16Short = 0x0011,  // 16 bit signed
  43.   UInt16Short = 0x0021, // 16 bit unsigned
  44.   Int16 = 0x0072,       // 16 bit signed int
  45.   UInt16 = 0x0073,      // 16 bit unsigned int
  46.   Int32Long = 0x0012,   // 32 bit signed
  47.   UInt32Long = 0x0022,  // 32 bit unsigned
  48.   Int32 = 0x0074,       // 32 bit signed int
  49.   UInt32 = 0x0075,      // 32 bit unsigned int
  50.   Int64Quad = 0x0013,   // 64 bit signed
  51.   UInt64Quad = 0x0023,  // 64 bit unsigned
  52.   Int64 = 0x0076,       // 64 bit signed int
  53.   UInt64 = 0x0077,      // 64 bit unsigned int
  54.   Int128Oct = 0x0014,   // 128 bit signed int
  55.   UInt128Oct = 0x0024,  // 128 bit unsigned int
  56.   Int128 = 0x0078,      // 128 bit signed int
  57.   UInt128 = 0x0079,     // 128 bit unsigned int
  58.  
  59.   Float16 = 0x0046,                 // 16 bit real
  60.   Float32 = 0x0040,                 // 32 bit real
  61.   Float32PartialPrecision = 0x0045, // 32 bit PP real
  62.   Float48 = 0x0044,                 // 48 bit real
  63.   Float64 = 0x0041,                 // 64 bit real
  64.   Float80 = 0x0042,                 // 80 bit real
  65.   Float128 = 0x0043,                // 128 bit real
  66.  
  67.   Complex16 = 0x0056,                 // 16 bit complex
  68.   Complex32 = 0x0050,                 // 32 bit complex
  69.   Complex32PartialPrecision = 0x0055, // 32 bit PP complex
  70.   Complex48 = 0x0054,                 // 48 bit complex
  71.   Complex64 = 0x0051,                 // 64 bit complex
  72.   Complex80 = 0x0052,                 // 80 bit complex
  73.   Complex128 = 0x0053,                // 128 bit complex
  74.  
  75.   Boolean8 = 0x0030,   // 8 bit boolean
  76.   Boolean16 = 0x0031,  // 16 bit boolean
  77.   Boolean32 = 0x0032,  // 32 bit boolean
  78.   Boolean64 = 0x0033,  // 64 bit boolean
  79.   Boolean128 = 0x0034, // 128 bit boolean
  80. };
  81.  
  82. enum class SimpleTypeMode : uint32_t {
  83.   Direct = 0x00000000,        // Not a pointer
  84.   NearPointer = 0x00000100,   // Near pointer
  85.   FarPointer = 0x00000200,    // Far pointer
  86.   HugePointer = 0x00000300,   // Huge pointer
  87.   NearPointer32 = 0x00000400, // 32 bit near pointer
  88.   FarPointer32 = 0x00000500,  // 32 bit far pointer
  89.   NearPointer64 = 0x00000600, // 64 bit near pointer
  90.   NearPointer128 = 0x00000700 // 128 bit near pointer
  91. };
  92.  
  93. /// A 32-bit type reference. Types are indexed by their order of appearance in
  94. /// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
  95. /// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
  96. class TypeIndex {
  97. public:
  98.   static const uint32_t FirstNonSimpleIndex = 0x1000;
  99.   static const uint32_t SimpleKindMask = 0x000000ff;
  100.   static const uint32_t SimpleModeMask = 0x00000700;
  101.   static const uint32_t DecoratedItemIdMask = 0x80000000;
  102.  
  103. public:
  104.   TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
  105.   explicit TypeIndex(uint32_t Index) : Index(Index) {}
  106.   explicit TypeIndex(SimpleTypeKind Kind)
  107.       : Index(static_cast<uint32_t>(Kind)) {}
  108.   TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
  109.       : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
  110.  
  111.   uint32_t getIndex() const { return Index; }
  112.   void setIndex(uint32_t I) { Index = I; }
  113.   bool isSimple() const { return Index < FirstNonSimpleIndex; }
  114.   bool isDecoratedItemId() const { return !!(Index & DecoratedItemIdMask); }
  115.  
  116.   bool isNoneType() const { return *this == None(); }
  117.  
  118.   uint32_t toArrayIndex() const {
  119.     assert(!isSimple());
  120.     return (getIndex() & ~DecoratedItemIdMask) - FirstNonSimpleIndex;
  121.   }
  122.  
  123.   static TypeIndex fromArrayIndex(uint32_t Index) {
  124.     return TypeIndex(Index + FirstNonSimpleIndex);
  125.   }
  126.  
  127.   static TypeIndex fromDecoratedArrayIndex(bool IsItem, uint32_t Index) {
  128.     return TypeIndex((Index + FirstNonSimpleIndex) |
  129.                      (IsItem ? DecoratedItemIdMask : 0));
  130.   }
  131.  
  132.   TypeIndex removeDecoration() {
  133.     return TypeIndex(Index & ~DecoratedItemIdMask);
  134.   }
  135.  
  136.   SimpleTypeKind getSimpleKind() const {
  137.     assert(isSimple());
  138.     return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
  139.   }
  140.  
  141.   SimpleTypeMode getSimpleMode() const {
  142.     assert(isSimple());
  143.     return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
  144.   }
  145.  
  146.   TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; }
  147.  
  148.   static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
  149.   static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
  150.   static TypeIndex VoidPointer32() {
  151.     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
  152.   }
  153.   static TypeIndex VoidPointer64() {
  154.     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64);
  155.   }
  156.  
  157.   static TypeIndex NullptrT() {
  158.     // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
  159.     // presumably because std::nullptr_t is intended to be compatible with any
  160.     // pointer type.
  161.     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer);
  162.   }
  163.  
  164.   static TypeIndex SignedCharacter() {
  165.     return TypeIndex(SimpleTypeKind::SignedCharacter);
  166.   }
  167.   static TypeIndex UnsignedCharacter() {
  168.     return TypeIndex(SimpleTypeKind::UnsignedCharacter);
  169.   }
  170.   static TypeIndex NarrowCharacter() {
  171.     return TypeIndex(SimpleTypeKind::NarrowCharacter);
  172.   }
  173.   static TypeIndex WideCharacter() {
  174.     return TypeIndex(SimpleTypeKind::WideCharacter);
  175.   }
  176.   static TypeIndex Int16Short() {
  177.     return TypeIndex(SimpleTypeKind::Int16Short);
  178.   }
  179.   static TypeIndex UInt16Short() {
  180.     return TypeIndex(SimpleTypeKind::UInt16Short);
  181.   }
  182.   static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
  183.   static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
  184.   static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
  185.   static TypeIndex UInt32Long() {
  186.     return TypeIndex(SimpleTypeKind::UInt32Long);
  187.   }
  188.   static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
  189.   static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
  190.   static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
  191.   static TypeIndex UInt64Quad() {
  192.     return TypeIndex(SimpleTypeKind::UInt64Quad);
  193.   }
  194.  
  195.   static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
  196.   static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
  197.  
  198.   TypeIndex &operator+=(unsigned N) {
  199.     Index += N;
  200.     return *this;
  201.   }
  202.  
  203.   TypeIndex &operator++() {
  204.     Index += 1;
  205.     return *this;
  206.   }
  207.  
  208.   TypeIndex operator++(int) {
  209.     TypeIndex Copy = *this;
  210.     operator++();
  211.     return Copy;
  212.   }
  213.  
  214.   TypeIndex &operator-=(unsigned N) {
  215.     assert(Index >= N);
  216.     Index -= N;
  217.     return *this;
  218.   }
  219.  
  220.   TypeIndex &operator--() {
  221.     Index -= 1;
  222.     return *this;
  223.   }
  224.  
  225.   TypeIndex operator--(int) {
  226.     TypeIndex Copy = *this;
  227.     operator--();
  228.     return Copy;
  229.   }
  230.  
  231.   friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
  232.     return A.getIndex() == B.getIndex();
  233.   }
  234.  
  235.   friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
  236.     return A.getIndex() != B.getIndex();
  237.   }
  238.  
  239.   friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
  240.     return A.getIndex() < B.getIndex();
  241.   }
  242.  
  243.   friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
  244.     return A.getIndex() <= B.getIndex();
  245.   }
  246.  
  247.   friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
  248.     return A.getIndex() > B.getIndex();
  249.   }
  250.  
  251.   friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
  252.     return A.getIndex() >= B.getIndex();
  253.   }
  254.  
  255.   friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
  256.     TypeIndex Result(A);
  257.     Result += N;
  258.     return Result;
  259.   }
  260.  
  261.   friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
  262.     assert(A.getIndex() >= N);
  263.     TypeIndex Result(A);
  264.     Result -= N;
  265.     return Result;
  266.   }
  267.  
  268.   friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
  269.     assert(A >= B);
  270.     return A.toArrayIndex() - B.toArrayIndex();
  271.   }
  272.  
  273.   static StringRef simpleTypeName(TypeIndex TI);
  274.  
  275. private:
  276.   support::ulittle32_t Index;
  277. };
  278.  
  279. // Used for pseudo-indexing an array of type records.  An array of such records
  280. // sorted by TypeIndex can allow log(N) lookups even though such a type record
  281. // stream does not provide random access.
  282. struct TypeIndexOffset {
  283.   TypeIndex Type;
  284.   support::ulittle32_t Offset;
  285. };
  286.  
  287. void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
  288.                     TypeCollection &Types);
  289. }
  290.  
  291. template <> struct DenseMapInfo<codeview::TypeIndex> {
  292.   static inline codeview::TypeIndex getEmptyKey() {
  293.     return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
  294.   }
  295.   static inline codeview::TypeIndex getTombstoneKey() {
  296.     return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
  297.   }
  298.   static unsigned getHashValue(const codeview::TypeIndex &TI) {
  299.     return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
  300.   }
  301.   static bool isEqual(const codeview::TypeIndex &LHS,
  302.                       const codeview::TypeIndex &RHS) {
  303.     return LHS == RHS;
  304.   }
  305. };
  306.  
  307. } // namespace llvm
  308.  
  309. #endif
  310.