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    {"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    {"char8_t*", SimpleTypeKind::Character8},
37    {"__int8*", SimpleTypeKind::SByte},
38    {"unsigned __int8*", SimpleTypeKind::Byte},
39    {"short*", SimpleTypeKind::Int16Short},
40    {"unsigned short*", SimpleTypeKind::UInt16Short},
41    {"__int16*", SimpleTypeKind::Int16},
42    {"unsigned __int16*", SimpleTypeKind::UInt16},
43    {"long*", SimpleTypeKind::Int32Long},
44    {"unsigned long*", SimpleTypeKind::UInt32Long},
45    {"int*", SimpleTypeKind::Int32},
46    {"unsigned*", SimpleTypeKind::UInt32},
47    {"__int64*", SimpleTypeKind::Int64Quad},
48    {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
49    {"__int64*", SimpleTypeKind::Int64},
50    {"unsigned __int64*", SimpleTypeKind::UInt64},
51    {"__int128*", SimpleTypeKind::Int128},
52    {"unsigned __int128*", SimpleTypeKind::UInt128},
53    {"__half*", SimpleTypeKind::Float16},
54    {"float*", SimpleTypeKind::Float32},
55    {"float*", SimpleTypeKind::Float32PartialPrecision},
56    {"__float48*", SimpleTypeKind::Float48},
57    {"double*", SimpleTypeKind::Float64},
58    {"long double*", SimpleTypeKind::Float80},
59    {"__float128*", SimpleTypeKind::Float128},
60    {"_Complex float*", SimpleTypeKind::Complex32},
61    {"_Complex double*", SimpleTypeKind::Complex64},
62    {"_Complex long double*", SimpleTypeKind::Complex80},
63    {"_Complex __float128*", SimpleTypeKind::Complex128},
64    {"bool*", SimpleTypeKind::Boolean8},
65    {"__bool16*", SimpleTypeKind::Boolean16},
66    {"__bool32*", SimpleTypeKind::Boolean32},
67    {"__bool64*", 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(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(TI);
101  }
102
103  if (!TypeName.empty())
104    Printer.printHex(FieldName, TypeName, TI.getIndex());
105  else
106    Printer.printHex(FieldName, TI.getIndex());
107}
108