10b57cec5SDimitry Andric //===-- TypeIndex.cpp - CodeView type index ---------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeCollection.h"
120b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace llvm;
150b57cec5SDimitry Andric using namespace llvm::codeview;
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric namespace {
180b57cec5SDimitry Andric struct SimpleTypeEntry {
190b57cec5SDimitry Andric   StringRef Name;
200b57cec5SDimitry Andric   SimpleTypeKind Kind;
210b57cec5SDimitry Andric };
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric /// The names here all end in "*". If the simple type is a pointer type, we
240b57cec5SDimitry Andric /// return the whole name. Otherwise we lop off the last character in our
250b57cec5SDimitry Andric /// StringRef.
260b57cec5SDimitry Andric static const SimpleTypeEntry SimpleTypeNames[] = {
270b57cec5SDimitry Andric     {"void*", SimpleTypeKind::Void},
280b57cec5SDimitry Andric     {"<not translated>*", SimpleTypeKind::NotTranslated},
290b57cec5SDimitry Andric     {"HRESULT*", SimpleTypeKind::HResult},
300b57cec5SDimitry Andric     {"signed char*", SimpleTypeKind::SignedCharacter},
310b57cec5SDimitry Andric     {"unsigned char*", SimpleTypeKind::UnsignedCharacter},
320b57cec5SDimitry Andric     {"char*", SimpleTypeKind::NarrowCharacter},
330b57cec5SDimitry Andric     {"wchar_t*", SimpleTypeKind::WideCharacter},
340b57cec5SDimitry Andric     {"char16_t*", SimpleTypeKind::Character16},
350b57cec5SDimitry Andric     {"char32_t*", SimpleTypeKind::Character32},
3681ad6265SDimitry Andric     {"char8_t*", SimpleTypeKind::Character8},
370b57cec5SDimitry Andric     {"__int8*", SimpleTypeKind::SByte},
380b57cec5SDimitry Andric     {"unsigned __int8*", SimpleTypeKind::Byte},
390b57cec5SDimitry Andric     {"short*", SimpleTypeKind::Int16Short},
400b57cec5SDimitry Andric     {"unsigned short*", SimpleTypeKind::UInt16Short},
410b57cec5SDimitry Andric     {"__int16*", SimpleTypeKind::Int16},
420b57cec5SDimitry Andric     {"unsigned __int16*", SimpleTypeKind::UInt16},
430b57cec5SDimitry Andric     {"long*", SimpleTypeKind::Int32Long},
440b57cec5SDimitry Andric     {"unsigned long*", SimpleTypeKind::UInt32Long},
450b57cec5SDimitry Andric     {"int*", SimpleTypeKind::Int32},
460b57cec5SDimitry Andric     {"unsigned*", SimpleTypeKind::UInt32},
470b57cec5SDimitry Andric     {"__int64*", SimpleTypeKind::Int64Quad},
480b57cec5SDimitry Andric     {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
490b57cec5SDimitry Andric     {"__int64*", SimpleTypeKind::Int64},
500b57cec5SDimitry Andric     {"unsigned __int64*", SimpleTypeKind::UInt64},
510b57cec5SDimitry Andric     {"__int128*", SimpleTypeKind::Int128},
520b57cec5SDimitry Andric     {"unsigned __int128*", SimpleTypeKind::UInt128},
530b57cec5SDimitry Andric     {"__half*", SimpleTypeKind::Float16},
540b57cec5SDimitry Andric     {"float*", SimpleTypeKind::Float32},
550b57cec5SDimitry Andric     {"float*", SimpleTypeKind::Float32PartialPrecision},
560b57cec5SDimitry Andric     {"__float48*", SimpleTypeKind::Float48},
570b57cec5SDimitry Andric     {"double*", SimpleTypeKind::Float64},
580b57cec5SDimitry Andric     {"long double*", SimpleTypeKind::Float80},
590b57cec5SDimitry Andric     {"__float128*", SimpleTypeKind::Float128},
600b57cec5SDimitry Andric     {"_Complex float*", SimpleTypeKind::Complex32},
610b57cec5SDimitry Andric     {"_Complex double*", SimpleTypeKind::Complex64},
620b57cec5SDimitry Andric     {"_Complex long double*", SimpleTypeKind::Complex80},
630b57cec5SDimitry Andric     {"_Complex __float128*", SimpleTypeKind::Complex128},
640b57cec5SDimitry Andric     {"bool*", SimpleTypeKind::Boolean8},
650b57cec5SDimitry Andric     {"__bool16*", SimpleTypeKind::Boolean16},
660b57cec5SDimitry Andric     {"__bool32*", SimpleTypeKind::Boolean32},
670b57cec5SDimitry Andric     {"__bool64*", SimpleTypeKind::Boolean64},
680b57cec5SDimitry Andric };
690b57cec5SDimitry Andric } // namespace
700b57cec5SDimitry Andric 
simpleTypeName(TypeIndex TI)710b57cec5SDimitry Andric StringRef TypeIndex::simpleTypeName(TypeIndex TI) {
720b57cec5SDimitry Andric   assert(TI.isNoneType() || TI.isSimple());
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   if (TI.isNoneType())
750b57cec5SDimitry Andric     return "<no type>";
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   if (TI == TypeIndex::NullptrT())
780b57cec5SDimitry Andric     return "std::nullptr_t";
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   // This is a simple type.
810b57cec5SDimitry Andric   for (const auto &SimpleTypeName : SimpleTypeNames) {
820b57cec5SDimitry Andric     if (SimpleTypeName.Kind == TI.getSimpleKind()) {
830b57cec5SDimitry Andric       if (TI.getSimpleMode() == SimpleTypeMode::Direct)
840b57cec5SDimitry Andric         return SimpleTypeName.Name.drop_back(1);
850b57cec5SDimitry Andric       // Otherwise, this is a pointer type. We gloss over the distinction
860b57cec5SDimitry Andric       // between near, far, 64, 32, etc, and just give a pointer type.
870b57cec5SDimitry Andric       return SimpleTypeName.Name;
880b57cec5SDimitry Andric     }
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric   return "<unknown simple type>";
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
printTypeIndex(ScopedPrinter & Printer,StringRef FieldName,TypeIndex TI,TypeCollection & Types)930b57cec5SDimitry Andric void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
940b57cec5SDimitry Andric                                     TypeIndex TI, TypeCollection &Types) {
950b57cec5SDimitry Andric   StringRef TypeName;
960b57cec5SDimitry Andric   if (!TI.isNoneType()) {
970b57cec5SDimitry Andric     if (TI.isSimple())
980b57cec5SDimitry Andric       TypeName = TypeIndex::simpleTypeName(TI);
990b57cec5SDimitry Andric     else
1000b57cec5SDimitry Andric       TypeName = Types.getTypeName(TI);
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   if (!TypeName.empty())
1040b57cec5SDimitry Andric     Printer.printHex(FieldName, TypeName, TI.getIndex());
1050b57cec5SDimitry Andric   else
1060b57cec5SDimitry Andric     Printer.printHex(FieldName, TI.getIndex());
1070b57cec5SDimitry Andric }
108