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    {"__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
70StringRef 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
92void 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