106f32e7eSjoerg //===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg 
906f32e7eSjoerg #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
1006f32e7eSjoerg 
1106f32e7eSjoerg #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
1206f32e7eSjoerg 
1306f32e7eSjoerg #include <cassert>
1406f32e7eSjoerg 
1506f32e7eSjoerg using namespace llvm;
1606f32e7eSjoerg using namespace llvm::codeview;
1706f32e7eSjoerg using namespace llvm::pdb;
1806f32e7eSjoerg 
NativeTypeUDT(NativeSession & Session,SymIndexId Id,codeview::TypeIndex TI,codeview::ClassRecord CR)1906f32e7eSjoerg NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
2006f32e7eSjoerg                              codeview::TypeIndex TI, codeview::ClassRecord CR)
2106f32e7eSjoerg     : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
2206f32e7eSjoerg       Class(std::move(CR)), Tag(Class.getPointer()) {}
2306f32e7eSjoerg 
NativeTypeUDT(NativeSession & Session,SymIndexId Id,codeview::TypeIndex TI,codeview::UnionRecord UR)2406f32e7eSjoerg NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
2506f32e7eSjoerg                              codeview::TypeIndex TI, codeview::UnionRecord UR)
2606f32e7eSjoerg     : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
2706f32e7eSjoerg       Union(std::move(UR)), Tag(Union.getPointer()) {}
2806f32e7eSjoerg 
NativeTypeUDT(NativeSession & Session,SymIndexId Id,NativeTypeUDT & UnmodifiedType,codeview::ModifierRecord Modifier)2906f32e7eSjoerg NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
3006f32e7eSjoerg                              NativeTypeUDT &UnmodifiedType,
3106f32e7eSjoerg                              codeview::ModifierRecord Modifier)
3206f32e7eSjoerg     : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
3306f32e7eSjoerg       UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
3406f32e7eSjoerg 
~NativeTypeUDT()3506f32e7eSjoerg NativeTypeUDT::~NativeTypeUDT() {}
3606f32e7eSjoerg 
dump(raw_ostream & OS,int Indent,PdbSymbolIdField ShowIdFields,PdbSymbolIdField RecurseIdFields) const3706f32e7eSjoerg void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
3806f32e7eSjoerg                          PdbSymbolIdField ShowIdFields,
3906f32e7eSjoerg                          PdbSymbolIdField RecurseIdFields) const {
4006f32e7eSjoerg 
4106f32e7eSjoerg   NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
4206f32e7eSjoerg 
4306f32e7eSjoerg   dumpSymbolField(OS, "name", getName(), Indent);
4406f32e7eSjoerg   dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
4506f32e7eSjoerg                     PdbSymbolIdField::LexicalParent, ShowIdFields,
4606f32e7eSjoerg                     RecurseIdFields);
4706f32e7eSjoerg   if (Modifiers.hasValue())
4806f32e7eSjoerg     dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
4906f32e7eSjoerg                       Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
5006f32e7eSjoerg                       RecurseIdFields);
5106f32e7eSjoerg   if (getUdtKind() != PDB_UdtType::Union)
5206f32e7eSjoerg     dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
5306f32e7eSjoerg                     Indent);
5406f32e7eSjoerg   dumpSymbolField(OS, "length", getLength(), Indent);
5506f32e7eSjoerg   dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
5606f32e7eSjoerg   dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
5706f32e7eSjoerg   dumpSymbolField(OS, "constType", isConstType(), Indent);
5806f32e7eSjoerg   dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
5906f32e7eSjoerg   dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
6006f32e7eSjoerg   dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
6106f32e7eSjoerg   dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
6206f32e7eSjoerg   dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
6306f32e7eSjoerg   dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
6406f32e7eSjoerg   dumpSymbolField(OS, "nested", isNested(), Indent);
6506f32e7eSjoerg   dumpSymbolField(OS, "packed", isPacked(), Indent);
6606f32e7eSjoerg   dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
6706f32e7eSjoerg   dumpSymbolField(OS, "scoped", isScoped(), Indent);
6806f32e7eSjoerg   dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
6906f32e7eSjoerg   dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
7006f32e7eSjoerg   dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
7106f32e7eSjoerg }
7206f32e7eSjoerg 
getName() const7306f32e7eSjoerg std::string NativeTypeUDT::getName() const {
7406f32e7eSjoerg   if (UnmodifiedType)
7506f32e7eSjoerg     return UnmodifiedType->getName();
7606f32e7eSjoerg 
77*da58b97aSjoerg   return std::string(Tag->getName());
7806f32e7eSjoerg }
7906f32e7eSjoerg 
getLexicalParentId() const8006f32e7eSjoerg SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
8106f32e7eSjoerg 
getUnmodifiedTypeId() const8206f32e7eSjoerg SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
8306f32e7eSjoerg   if (UnmodifiedType)
8406f32e7eSjoerg     return UnmodifiedType->getSymIndexId();
8506f32e7eSjoerg 
8606f32e7eSjoerg   return 0;
8706f32e7eSjoerg }
8806f32e7eSjoerg 
getVirtualTableShapeId() const8906f32e7eSjoerg SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
9006f32e7eSjoerg   if (UnmodifiedType)
9106f32e7eSjoerg     return UnmodifiedType->getVirtualTableShapeId();
9206f32e7eSjoerg 
9306f32e7eSjoerg   if (Class)
9406f32e7eSjoerg     return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
9506f32e7eSjoerg 
9606f32e7eSjoerg   return 0;
9706f32e7eSjoerg }
9806f32e7eSjoerg 
getLength() const9906f32e7eSjoerg uint64_t NativeTypeUDT::getLength() const {
10006f32e7eSjoerg   if (UnmodifiedType)
10106f32e7eSjoerg     return UnmodifiedType->getLength();
10206f32e7eSjoerg 
10306f32e7eSjoerg   if (Class)
10406f32e7eSjoerg     return Class->getSize();
10506f32e7eSjoerg 
10606f32e7eSjoerg   return Union->getSize();
10706f32e7eSjoerg }
10806f32e7eSjoerg 
getUdtKind() const10906f32e7eSjoerg PDB_UdtType NativeTypeUDT::getUdtKind() const {
11006f32e7eSjoerg   if (UnmodifiedType)
11106f32e7eSjoerg     return UnmodifiedType->getUdtKind();
11206f32e7eSjoerg 
11306f32e7eSjoerg   switch (Tag->Kind) {
11406f32e7eSjoerg   case TypeRecordKind::Class:
11506f32e7eSjoerg     return PDB_UdtType::Class;
11606f32e7eSjoerg   case TypeRecordKind::Union:
11706f32e7eSjoerg     return PDB_UdtType::Union;
11806f32e7eSjoerg   case TypeRecordKind::Struct:
11906f32e7eSjoerg     return PDB_UdtType::Struct;
12006f32e7eSjoerg   case TypeRecordKind::Interface:
12106f32e7eSjoerg     return PDB_UdtType::Interface;
12206f32e7eSjoerg   default:
123*da58b97aSjoerg     llvm_unreachable("Unexpected udt kind");
12406f32e7eSjoerg   }
12506f32e7eSjoerg }
12606f32e7eSjoerg 
hasConstructor() const12706f32e7eSjoerg bool NativeTypeUDT::hasConstructor() const {
12806f32e7eSjoerg   if (UnmodifiedType)
12906f32e7eSjoerg     return UnmodifiedType->hasConstructor();
13006f32e7eSjoerg 
13106f32e7eSjoerg   return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
13206f32e7eSjoerg          ClassOptions::None;
13306f32e7eSjoerg }
13406f32e7eSjoerg 
isConstType() const13506f32e7eSjoerg bool NativeTypeUDT::isConstType() const {
13606f32e7eSjoerg   if (!Modifiers)
13706f32e7eSjoerg     return false;
13806f32e7eSjoerg   return (Modifiers->Modifiers & ModifierOptions::Const) !=
13906f32e7eSjoerg          ModifierOptions::None;
14006f32e7eSjoerg }
14106f32e7eSjoerg 
hasAssignmentOperator() const14206f32e7eSjoerg bool NativeTypeUDT::hasAssignmentOperator() const {
14306f32e7eSjoerg   if (UnmodifiedType)
14406f32e7eSjoerg     return UnmodifiedType->hasAssignmentOperator();
14506f32e7eSjoerg 
14606f32e7eSjoerg   return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
14706f32e7eSjoerg          ClassOptions::None;
14806f32e7eSjoerg }
14906f32e7eSjoerg 
hasCastOperator() const15006f32e7eSjoerg bool NativeTypeUDT::hasCastOperator() const {
15106f32e7eSjoerg   if (UnmodifiedType)
15206f32e7eSjoerg     return UnmodifiedType->hasCastOperator();
15306f32e7eSjoerg 
15406f32e7eSjoerg   return (Tag->Options & ClassOptions::HasConversionOperator) !=
15506f32e7eSjoerg          ClassOptions::None;
15606f32e7eSjoerg }
15706f32e7eSjoerg 
hasNestedTypes() const15806f32e7eSjoerg bool NativeTypeUDT::hasNestedTypes() const {
15906f32e7eSjoerg   if (UnmodifiedType)
16006f32e7eSjoerg     return UnmodifiedType->hasNestedTypes();
16106f32e7eSjoerg 
16206f32e7eSjoerg   return (Tag->Options & ClassOptions::ContainsNestedClass) !=
16306f32e7eSjoerg          ClassOptions::None;
16406f32e7eSjoerg }
16506f32e7eSjoerg 
hasOverloadedOperator() const16606f32e7eSjoerg bool NativeTypeUDT::hasOverloadedOperator() const {
16706f32e7eSjoerg   if (UnmodifiedType)
16806f32e7eSjoerg     return UnmodifiedType->hasOverloadedOperator();
16906f32e7eSjoerg 
17006f32e7eSjoerg   return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
17106f32e7eSjoerg          ClassOptions::None;
17206f32e7eSjoerg }
17306f32e7eSjoerg 
isInterfaceUdt() const17406f32e7eSjoerg bool NativeTypeUDT::isInterfaceUdt() const { return false; }
17506f32e7eSjoerg 
isIntrinsic() const17606f32e7eSjoerg bool NativeTypeUDT::isIntrinsic() const {
17706f32e7eSjoerg   if (UnmodifiedType)
17806f32e7eSjoerg     return UnmodifiedType->isIntrinsic();
17906f32e7eSjoerg 
18006f32e7eSjoerg   return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
18106f32e7eSjoerg }
18206f32e7eSjoerg 
isNested() const18306f32e7eSjoerg bool NativeTypeUDT::isNested() const {
18406f32e7eSjoerg   if (UnmodifiedType)
18506f32e7eSjoerg     return UnmodifiedType->isNested();
18606f32e7eSjoerg 
18706f32e7eSjoerg   return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
18806f32e7eSjoerg }
18906f32e7eSjoerg 
isPacked() const19006f32e7eSjoerg bool NativeTypeUDT::isPacked() const {
19106f32e7eSjoerg   if (UnmodifiedType)
19206f32e7eSjoerg     return UnmodifiedType->isPacked();
19306f32e7eSjoerg 
19406f32e7eSjoerg   return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
19506f32e7eSjoerg }
19606f32e7eSjoerg 
isRefUdt() const19706f32e7eSjoerg bool NativeTypeUDT::isRefUdt() const { return false; }
19806f32e7eSjoerg 
isScoped() const19906f32e7eSjoerg bool NativeTypeUDT::isScoped() const {
20006f32e7eSjoerg   if (UnmodifiedType)
20106f32e7eSjoerg     return UnmodifiedType->isScoped();
20206f32e7eSjoerg 
20306f32e7eSjoerg   return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
20406f32e7eSjoerg }
20506f32e7eSjoerg 
isValueUdt() const20606f32e7eSjoerg bool NativeTypeUDT::isValueUdt() const { return false; }
20706f32e7eSjoerg 
isUnalignedType() const20806f32e7eSjoerg bool NativeTypeUDT::isUnalignedType() const {
20906f32e7eSjoerg   if (!Modifiers)
21006f32e7eSjoerg     return false;
21106f32e7eSjoerg   return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
21206f32e7eSjoerg          ModifierOptions::None;
21306f32e7eSjoerg }
21406f32e7eSjoerg 
isVolatileType() const21506f32e7eSjoerg bool NativeTypeUDT::isVolatileType() const {
21606f32e7eSjoerg   if (!Modifiers)
21706f32e7eSjoerg     return false;
21806f32e7eSjoerg   return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
21906f32e7eSjoerg          ModifierOptions::None;
22006f32e7eSjoerg }
221