Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:40

0001 //===- TypeIndex.h ----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
0011 
0012 #include "llvm/ADT/DenseMapInfo.h"
0013 #include "llvm/Support/Endian.h"
0014 #include <cassert>
0015 #include <cinttypes>
0016 
0017 namespace llvm {
0018 
0019 class ScopedPrinter;
0020 class StringRef;
0021 
0022 namespace codeview {
0023 
0024 class TypeCollection;
0025 
0026 enum class SimpleTypeKind : uint32_t {
0027   None = 0x0000,          // uncharacterized type (no type)
0028   Void = 0x0003,          // void
0029   NotTranslated = 0x0007, // type not translated by cvpack
0030   HResult = 0x0008,       // OLE/COM HRESULT
0031 
0032   SignedCharacter = 0x0010,   // 8 bit signed
0033   UnsignedCharacter = 0x0020, // 8 bit unsigned
0034   NarrowCharacter = 0x0070,   // really a char
0035   WideCharacter = 0x0071,     // wide char
0036   Character16 = 0x007a,       // char16_t
0037   Character32 = 0x007b,       // char32_t
0038   Character8 = 0x007c,        // char8_t
0039 
0040   SByte = 0x0068,       // 8 bit signed int
0041   Byte = 0x0069,        // 8 bit unsigned int
0042   Int16Short = 0x0011,  // 16 bit signed
0043   UInt16Short = 0x0021, // 16 bit unsigned
0044   Int16 = 0x0072,       // 16 bit signed int
0045   UInt16 = 0x0073,      // 16 bit unsigned int
0046   Int32Long = 0x0012,   // 32 bit signed
0047   UInt32Long = 0x0022,  // 32 bit unsigned
0048   Int32 = 0x0074,       // 32 bit signed int
0049   UInt32 = 0x0075,      // 32 bit unsigned int
0050   Int64Quad = 0x0013,   // 64 bit signed
0051   UInt64Quad = 0x0023,  // 64 bit unsigned
0052   Int64 = 0x0076,       // 64 bit signed int
0053   UInt64 = 0x0077,      // 64 bit unsigned int
0054   Int128Oct = 0x0014,   // 128 bit signed int
0055   UInt128Oct = 0x0024,  // 128 bit unsigned int
0056   Int128 = 0x0078,      // 128 bit signed int
0057   UInt128 = 0x0079,     // 128 bit unsigned int
0058 
0059   Float16 = 0x0046,                 // 16 bit real
0060   Float32 = 0x0040,                 // 32 bit real
0061   Float32PartialPrecision = 0x0045, // 32 bit PP real
0062   Float48 = 0x0044,                 // 48 bit real
0063   Float64 = 0x0041,                 // 64 bit real
0064   Float80 = 0x0042,                 // 80 bit real
0065   Float128 = 0x0043,                // 128 bit real
0066 
0067   Complex16 = 0x0056,                 // 16 bit complex
0068   Complex32 = 0x0050,                 // 32 bit complex
0069   Complex32PartialPrecision = 0x0055, // 32 bit PP complex
0070   Complex48 = 0x0054,                 // 48 bit complex
0071   Complex64 = 0x0051,                 // 64 bit complex
0072   Complex80 = 0x0052,                 // 80 bit complex
0073   Complex128 = 0x0053,                // 128 bit complex
0074 
0075   Boolean8 = 0x0030,   // 8 bit boolean
0076   Boolean16 = 0x0031,  // 16 bit boolean
0077   Boolean32 = 0x0032,  // 32 bit boolean
0078   Boolean64 = 0x0033,  // 64 bit boolean
0079   Boolean128 = 0x0034, // 128 bit boolean
0080 };
0081 
0082 enum class SimpleTypeMode : uint32_t {
0083   Direct = 0x00000000,        // Not a pointer
0084   NearPointer = 0x00000100,   // Near pointer
0085   FarPointer = 0x00000200,    // Far pointer
0086   HugePointer = 0x00000300,   // Huge pointer
0087   NearPointer32 = 0x00000400, // 32 bit near pointer
0088   FarPointer32 = 0x00000500,  // 32 bit far pointer
0089   NearPointer64 = 0x00000600, // 64 bit near pointer
0090   NearPointer128 = 0x00000700 // 128 bit near pointer
0091 };
0092 
0093 /// A 32-bit type reference. Types are indexed by their order of appearance in
0094 /// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
0095 /// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
0096 class TypeIndex {
0097 public:
0098   static const uint32_t FirstNonSimpleIndex = 0x1000;
0099   static const uint32_t SimpleKindMask = 0x000000ff;
0100   static const uint32_t SimpleModeMask = 0x00000700;
0101   static const uint32_t DecoratedItemIdMask = 0x80000000;
0102 
0103 public:
0104   TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
0105   explicit TypeIndex(uint32_t Index) : Index(Index) {}
0106   explicit TypeIndex(SimpleTypeKind Kind)
0107       : Index(static_cast<uint32_t>(Kind)) {}
0108   TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
0109       : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
0110 
0111   uint32_t getIndex() const { return Index; }
0112   void setIndex(uint32_t I) { Index = I; }
0113   bool isSimple() const { return Index < FirstNonSimpleIndex; }
0114   bool isDecoratedItemId() const { return !!(Index & DecoratedItemIdMask); }
0115 
0116   bool isNoneType() const { return *this == None(); }
0117 
0118   uint32_t toArrayIndex() const {
0119     assert(!isSimple());
0120     return (getIndex() & ~DecoratedItemIdMask) - FirstNonSimpleIndex;
0121   }
0122 
0123   static TypeIndex fromArrayIndex(uint32_t Index) {
0124     return TypeIndex(Index + FirstNonSimpleIndex);
0125   }
0126 
0127   static TypeIndex fromDecoratedArrayIndex(bool IsItem, uint32_t Index) {
0128     return TypeIndex((Index + FirstNonSimpleIndex) |
0129                      (IsItem ? DecoratedItemIdMask : 0));
0130   }
0131 
0132   TypeIndex removeDecoration() {
0133     return TypeIndex(Index & ~DecoratedItemIdMask);
0134   }
0135 
0136   SimpleTypeKind getSimpleKind() const {
0137     assert(isSimple());
0138     return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
0139   }
0140 
0141   SimpleTypeMode getSimpleMode() const {
0142     assert(isSimple());
0143     return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
0144   }
0145 
0146   TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; }
0147 
0148   static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
0149   static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
0150   static TypeIndex VoidPointer32() {
0151     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
0152   }
0153   static TypeIndex VoidPointer64() {
0154     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64);
0155   }
0156 
0157   static TypeIndex NullptrT() {
0158     // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
0159     // presumably because std::nullptr_t is intended to be compatible with any
0160     // pointer type.
0161     return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer);
0162   }
0163 
0164   static TypeIndex SignedCharacter() {
0165     return TypeIndex(SimpleTypeKind::SignedCharacter);
0166   }
0167   static TypeIndex UnsignedCharacter() {
0168     return TypeIndex(SimpleTypeKind::UnsignedCharacter);
0169   }
0170   static TypeIndex NarrowCharacter() {
0171     return TypeIndex(SimpleTypeKind::NarrowCharacter);
0172   }
0173   static TypeIndex WideCharacter() {
0174     return TypeIndex(SimpleTypeKind::WideCharacter);
0175   }
0176   static TypeIndex Int16Short() {
0177     return TypeIndex(SimpleTypeKind::Int16Short);
0178   }
0179   static TypeIndex UInt16Short() {
0180     return TypeIndex(SimpleTypeKind::UInt16Short);
0181   }
0182   static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
0183   static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
0184   static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
0185   static TypeIndex UInt32Long() {
0186     return TypeIndex(SimpleTypeKind::UInt32Long);
0187   }
0188   static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
0189   static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
0190   static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
0191   static TypeIndex UInt64Quad() {
0192     return TypeIndex(SimpleTypeKind::UInt64Quad);
0193   }
0194 
0195   static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
0196   static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
0197 
0198   TypeIndex &operator+=(unsigned N) {
0199     Index += N;
0200     return *this;
0201   }
0202 
0203   TypeIndex &operator++() {
0204     Index += 1;
0205     return *this;
0206   }
0207 
0208   TypeIndex operator++(int) {
0209     TypeIndex Copy = *this;
0210     operator++();
0211     return Copy;
0212   }
0213 
0214   TypeIndex &operator-=(unsigned N) {
0215     assert(Index >= N);
0216     Index -= N;
0217     return *this;
0218   }
0219 
0220   TypeIndex &operator--() {
0221     Index -= 1;
0222     return *this;
0223   }
0224 
0225   TypeIndex operator--(int) {
0226     TypeIndex Copy = *this;
0227     operator--();
0228     return Copy;
0229   }
0230 
0231   friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
0232     return A.getIndex() == B.getIndex();
0233   }
0234 
0235   friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
0236     return A.getIndex() != B.getIndex();
0237   }
0238 
0239   friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
0240     return A.getIndex() < B.getIndex();
0241   }
0242 
0243   friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
0244     return A.getIndex() <= B.getIndex();
0245   }
0246 
0247   friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
0248     return A.getIndex() > B.getIndex();
0249   }
0250 
0251   friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
0252     return A.getIndex() >= B.getIndex();
0253   }
0254 
0255   friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
0256     TypeIndex Result(A);
0257     Result += N;
0258     return Result;
0259   }
0260 
0261   friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
0262     assert(A.getIndex() >= N);
0263     TypeIndex Result(A);
0264     Result -= N;
0265     return Result;
0266   }
0267 
0268   friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
0269     assert(A >= B);
0270     return A.toArrayIndex() - B.toArrayIndex();
0271   }
0272 
0273   static StringRef simpleTypeName(TypeIndex TI);
0274 
0275 private:
0276   support::ulittle32_t Index;
0277 };
0278 
0279 // Used for pseudo-indexing an array of type records.  An array of such records
0280 // sorted by TypeIndex can allow log(N) lookups even though such a type record
0281 // stream does not provide random access.
0282 struct TypeIndexOffset {
0283   TypeIndex Type;
0284   support::ulittle32_t Offset;
0285 };
0286 
0287 void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
0288                     TypeCollection &Types);
0289 }
0290 
0291 template <> struct DenseMapInfo<codeview::TypeIndex> {
0292   static inline codeview::TypeIndex getEmptyKey() {
0293     return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
0294   }
0295   static inline codeview::TypeIndex getTombstoneKey() {
0296     return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
0297   }
0298   static unsigned getHashValue(const codeview::TypeIndex &TI) {
0299     return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
0300   }
0301   static bool isEqual(const codeview::TypeIndex &LHS,
0302                       const codeview::TypeIndex &RHS) {
0303     return LHS == RHS;
0304   }
0305 };
0306 
0307 } // namespace llvm
0308 
0309 #endif