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