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
14using namespace llvm;
15using namespace llvm::codeview;
16
17namespace {
18struct 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.
26static 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
71StringRef 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
93void 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