1343171Sdim//===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===//
2343171Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343171Sdim//
7343171Sdim//===----------------------------------------------------------------------===//
8343171Sdim
9343171Sdim#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
10343171Sdim
11343171Sdim#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
12343171Sdim
13343171Sdim#include <cassert>
14343171Sdim
15343171Sdimusing namespace llvm;
16343171Sdimusing namespace llvm::codeview;
17343171Sdimusing namespace llvm::pdb;
18343171Sdim
19343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
20343171Sdim                             codeview::TypeIndex TI, codeview::ClassRecord CR)
21343171Sdim    : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
22343171Sdim      Class(std::move(CR)), Tag(Class.getPointer()) {}
23343171Sdim
24343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
25343171Sdim                             codeview::TypeIndex TI, codeview::UnionRecord UR)
26343171Sdim    : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
27343171Sdim      Union(std::move(UR)), Tag(Union.getPointer()) {}
28343171Sdim
29343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
30343171Sdim                             NativeTypeUDT &UnmodifiedType,
31343171Sdim                             codeview::ModifierRecord Modifier)
32343171Sdim    : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
33343171Sdim      UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
34343171Sdim
35343171SdimNativeTypeUDT::~NativeTypeUDT() {}
36343171Sdim
37343171Sdimvoid NativeTypeUDT::dump(raw_ostream &OS, int Indent,
38343171Sdim                         PdbSymbolIdField ShowIdFields,
39343171Sdim                         PdbSymbolIdField RecurseIdFields) const {
40343171Sdim
41343171Sdim  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
42343171Sdim
43343171Sdim  dumpSymbolField(OS, "name", getName(), Indent);
44343171Sdim  dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
45343171Sdim                    PdbSymbolIdField::LexicalParent, ShowIdFields,
46343171Sdim                    RecurseIdFields);
47343171Sdim  if (Modifiers.hasValue())
48343171Sdim    dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
49343171Sdim                      Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
50343171Sdim                      RecurseIdFields);
51343171Sdim  if (getUdtKind() != PDB_UdtType::Union)
52343171Sdim    dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
53343171Sdim                    Indent);
54343171Sdim  dumpSymbolField(OS, "length", getLength(), Indent);
55343171Sdim  dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
56343171Sdim  dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
57343171Sdim  dumpSymbolField(OS, "constType", isConstType(), Indent);
58343171Sdim  dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
59343171Sdim  dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
60343171Sdim  dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
61343171Sdim  dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
62343171Sdim  dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
63343171Sdim  dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
64343171Sdim  dumpSymbolField(OS, "nested", isNested(), Indent);
65343171Sdim  dumpSymbolField(OS, "packed", isPacked(), Indent);
66343171Sdim  dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
67343171Sdim  dumpSymbolField(OS, "scoped", isScoped(), Indent);
68343171Sdim  dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
69343171Sdim  dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
70343171Sdim  dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
71343171Sdim}
72343171Sdim
73343171Sdimstd::string NativeTypeUDT::getName() const {
74343171Sdim  if (UnmodifiedType)
75343171Sdim    return UnmodifiedType->getName();
76343171Sdim
77343171Sdim  return Tag->getName();
78343171Sdim}
79343171Sdim
80343171SdimSymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
81343171Sdim
82343171SdimSymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
83343171Sdim  if (UnmodifiedType)
84343171Sdim    return UnmodifiedType->getSymIndexId();
85343171Sdim
86343171Sdim  return 0;
87343171Sdim}
88343171Sdim
89343171SdimSymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
90343171Sdim  if (UnmodifiedType)
91343171Sdim    return UnmodifiedType->getVirtualTableShapeId();
92343171Sdim
93343171Sdim  if (Class)
94343171Sdim    return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
95343171Sdim
96343171Sdim  return 0;
97343171Sdim}
98343171Sdim
99343171Sdimuint64_t NativeTypeUDT::getLength() const {
100343171Sdim  if (UnmodifiedType)
101343171Sdim    return UnmodifiedType->getLength();
102343171Sdim
103343171Sdim  if (Class)
104343171Sdim    return Class->getSize();
105343171Sdim
106343171Sdim  return Union->getSize();
107343171Sdim}
108343171Sdim
109343171SdimPDB_UdtType NativeTypeUDT::getUdtKind() const {
110343171Sdim  if (UnmodifiedType)
111343171Sdim    return UnmodifiedType->getUdtKind();
112343171Sdim
113343171Sdim  switch (Tag->Kind) {
114343171Sdim  case TypeRecordKind::Class:
115343171Sdim    return PDB_UdtType::Class;
116343171Sdim  case TypeRecordKind::Union:
117343171Sdim    return PDB_UdtType::Union;
118343171Sdim  case TypeRecordKind::Struct:
119343171Sdim    return PDB_UdtType::Struct;
120343171Sdim  case TypeRecordKind::Interface:
121343171Sdim    return PDB_UdtType::Interface;
122343171Sdim  default:
123343171Sdim    llvm_unreachable("Unexected udt kind");
124343171Sdim  }
125343171Sdim}
126343171Sdim
127343171Sdimbool NativeTypeUDT::hasConstructor() const {
128343171Sdim  if (UnmodifiedType)
129343171Sdim    return UnmodifiedType->hasConstructor();
130343171Sdim
131343171Sdim  return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
132343171Sdim         ClassOptions::None;
133343171Sdim}
134343171Sdim
135343171Sdimbool NativeTypeUDT::isConstType() const {
136343171Sdim  if (!Modifiers)
137343171Sdim    return false;
138343171Sdim  return (Modifiers->Modifiers & ModifierOptions::Const) !=
139343171Sdim         ModifierOptions::None;
140343171Sdim}
141343171Sdim
142343171Sdimbool NativeTypeUDT::hasAssignmentOperator() const {
143343171Sdim  if (UnmodifiedType)
144343171Sdim    return UnmodifiedType->hasAssignmentOperator();
145343171Sdim
146343171Sdim  return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
147343171Sdim         ClassOptions::None;
148343171Sdim}
149343171Sdim
150343171Sdimbool NativeTypeUDT::hasCastOperator() const {
151343171Sdim  if (UnmodifiedType)
152343171Sdim    return UnmodifiedType->hasCastOperator();
153343171Sdim
154343171Sdim  return (Tag->Options & ClassOptions::HasConversionOperator) !=
155343171Sdim         ClassOptions::None;
156343171Sdim}
157343171Sdim
158343171Sdimbool NativeTypeUDT::hasNestedTypes() const {
159343171Sdim  if (UnmodifiedType)
160343171Sdim    return UnmodifiedType->hasNestedTypes();
161343171Sdim
162343171Sdim  return (Tag->Options & ClassOptions::ContainsNestedClass) !=
163343171Sdim         ClassOptions::None;
164343171Sdim}
165343171Sdim
166343171Sdimbool NativeTypeUDT::hasOverloadedOperator() const {
167343171Sdim  if (UnmodifiedType)
168343171Sdim    return UnmodifiedType->hasOverloadedOperator();
169343171Sdim
170343171Sdim  return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
171343171Sdim         ClassOptions::None;
172343171Sdim}
173343171Sdim
174343171Sdimbool NativeTypeUDT::isInterfaceUdt() const { return false; }
175343171Sdim
176343171Sdimbool NativeTypeUDT::isIntrinsic() const {
177343171Sdim  if (UnmodifiedType)
178343171Sdim    return UnmodifiedType->isIntrinsic();
179343171Sdim
180343171Sdim  return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
181343171Sdim}
182343171Sdim
183343171Sdimbool NativeTypeUDT::isNested() const {
184343171Sdim  if (UnmodifiedType)
185343171Sdim    return UnmodifiedType->isNested();
186343171Sdim
187343171Sdim  return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
188343171Sdim}
189343171Sdim
190343171Sdimbool NativeTypeUDT::isPacked() const {
191343171Sdim  if (UnmodifiedType)
192343171Sdim    return UnmodifiedType->isPacked();
193343171Sdim
194343171Sdim  return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
195343171Sdim}
196343171Sdim
197343171Sdimbool NativeTypeUDT::isRefUdt() const { return false; }
198343171Sdim
199343171Sdimbool NativeTypeUDT::isScoped() const {
200343171Sdim  if (UnmodifiedType)
201343171Sdim    return UnmodifiedType->isScoped();
202343171Sdim
203343171Sdim  return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
204343171Sdim}
205343171Sdim
206343171Sdimbool NativeTypeUDT::isValueUdt() const { return false; }
207343171Sdim
208343171Sdimbool NativeTypeUDT::isUnalignedType() const {
209343171Sdim  if (!Modifiers)
210343171Sdim    return false;
211343171Sdim  return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
212343171Sdim         ModifierOptions::None;
213343171Sdim}
214343171Sdim
215343171Sdimbool NativeTypeUDT::isVolatileType() const {
216343171Sdim  if (!Modifiers)
217343171Sdim    return false;
218343171Sdim  return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
219343171Sdim         ModifierOptions::None;
220343171Sdim}
221