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