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
simpleTypeName(TypeIndex TI)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
printTypeIndex(ScopedPrinter & Printer,StringRef FieldName,TypeIndex TI,TypeCollection & Types)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