1 //===-- TypeIndex.cpp - CodeView type index ---------------------*- 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 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 10 11 #include "llvm/DebugInfo/CodeView/TypeCollection.h" 12 #include "llvm/Support/ScopedPrinter.h" 13 14 using namespace llvm; 15 using namespace llvm::codeview; 16 17 namespace { 18 struct SimpleTypeEntry { 19 StringRef Name; 20 SimpleTypeKind Kind; 21 }; 22 23 /// The names here all end in "*". If the simple type is a pointer type, we 24 /// return the whole name. Otherwise we lop off the last character in our 25 /// StringRef. 26 static const SimpleTypeEntry SimpleTypeNames[] = { 27 {"void*", SimpleTypeKind::Void}, 28 {"<not translated>*", SimpleTypeKind::NotTranslated}, 29 {"HRESULT*", SimpleTypeKind::HResult}, 30 {"signed char*", SimpleTypeKind::SignedCharacter}, 31 {"unsigned char*", SimpleTypeKind::UnsignedCharacter}, 32 {"char*", SimpleTypeKind::NarrowCharacter}, 33 {"wchar_t*", SimpleTypeKind::WideCharacter}, 34 {"char16_t*", SimpleTypeKind::Character16}, 35 {"char32_t*", SimpleTypeKind::Character32}, 36 {"__int8*", SimpleTypeKind::SByte}, 37 {"unsigned __int8*", SimpleTypeKind::Byte}, 38 {"short*", SimpleTypeKind::Int16Short}, 39 {"unsigned short*", SimpleTypeKind::UInt16Short}, 40 {"__int16*", SimpleTypeKind::Int16}, 41 {"unsigned __int16*", SimpleTypeKind::UInt16}, 42 {"long*", SimpleTypeKind::Int32Long}, 43 {"unsigned long*", SimpleTypeKind::UInt32Long}, 44 {"int*", SimpleTypeKind::Int32}, 45 {"unsigned*", SimpleTypeKind::UInt32}, 46 {"__int64*", SimpleTypeKind::Int64Quad}, 47 {"unsigned __int64*", SimpleTypeKind::UInt64Quad}, 48 {"__int64*", SimpleTypeKind::Int64}, 49 {"unsigned __int64*", SimpleTypeKind::UInt64}, 50 {"__int128*", SimpleTypeKind::Int128}, 51 {"unsigned __int128*", SimpleTypeKind::UInt128}, 52 {"__half*", SimpleTypeKind::Float16}, 53 {"float*", SimpleTypeKind::Float32}, 54 {"float*", SimpleTypeKind::Float32PartialPrecision}, 55 {"__float48*", SimpleTypeKind::Float48}, 56 {"double*", SimpleTypeKind::Float64}, 57 {"long double*", SimpleTypeKind::Float80}, 58 {"__float128*", SimpleTypeKind::Float128}, 59 {"_Complex float*", SimpleTypeKind::Complex32}, 60 {"_Complex double*", SimpleTypeKind::Complex64}, 61 {"_Complex long double*", SimpleTypeKind::Complex80}, 62 {"_Complex __float128*", SimpleTypeKind::Complex128}, 63 {"bool*", SimpleTypeKind::Boolean8}, 64 {"__bool16*", SimpleTypeKind::Boolean16}, 65 {"__bool32*", SimpleTypeKind::Boolean32}, 66 {"__bool64*", SimpleTypeKind::Boolean64}, 67 }; 68 } // namespace 69 70 StringRef TypeIndex::simpleTypeName(TypeIndex TI) { 71 assert(TI.isNoneType() || TI.isSimple()); 72 73 if (TI.isNoneType()) 74 return "<no type>"; 75 76 if (TI == TypeIndex::NullptrT()) 77 return "std::nullptr_t"; 78 79 // This is a simple type. 80 for (const auto &SimpleTypeName : SimpleTypeNames) { 81 if (SimpleTypeName.Kind == TI.getSimpleKind()) { 82 if (TI.getSimpleMode() == SimpleTypeMode::Direct) 83 return SimpleTypeName.Name.drop_back(1); 84 // Otherwise, this is a pointer type. We gloss over the distinction 85 // between near, far, 64, 32, etc, and just give a pointer type. 86 return SimpleTypeName.Name; 87 } 88 } 89 return "<unknown simple type>"; 90 } 91 92 void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, 93 TypeIndex TI, TypeCollection &Types) { 94 StringRef TypeName; 95 if (!TI.isNoneType()) { 96 if (TI.isSimple()) 97 TypeName = TypeIndex::simpleTypeName(TI); 98 else 99 TypeName = Types.getTypeName(TI); 100 } 101 102 if (!TypeName.empty()) 103 Printer.printHex(FieldName, TypeName, TI.getIndex()); 104 else 105 Printer.printHex(FieldName, TI.getIndex()); 106 } 107