1 //===- NativeTypePointer.cpp - info about pointer type ----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
11 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
16 using namespace llvm::codeview
;
17 using namespace llvm::pdb
;
19 NativeTypePointer::NativeTypePointer(NativeSession
&Session
, SymIndexId Id
,
20 codeview::TypeIndex TI
)
21 : NativeRawSymbol(Session
, PDB_SymType::PointerType
, Id
), TI(TI
) {
22 assert(TI
.isSimple());
23 assert(TI
.getSimpleMode() != SimpleTypeMode::Direct
);
26 NativeTypePointer::NativeTypePointer(NativeSession
&Session
, SymIndexId Id
,
27 codeview::TypeIndex TI
,
28 codeview::PointerRecord Record
)
29 : NativeRawSymbol(Session
, PDB_SymType::PointerType
, Id
), TI(TI
),
30 Record(std::move(Record
)) {}
32 NativeTypePointer::~NativeTypePointer() {}
34 void NativeTypePointer::dump(raw_ostream
&OS
, int Indent
,
35 PdbSymbolIdField ShowIdFields
,
36 PdbSymbolIdField RecurseIdFields
) const {
37 NativeRawSymbol::dump(OS
, Indent
, ShowIdFields
, RecurseIdFields
);
39 if (isMemberPointer()) {
40 dumpSymbolIdField(OS
, "classParentId", getClassParentId(), Indent
, Session
,
41 PdbSymbolIdField::ClassParent
, ShowIdFields
,
44 dumpSymbolIdField(OS
, "lexicalParentId", 0, Indent
, Session
,
45 PdbSymbolIdField::LexicalParent
, ShowIdFields
,
47 dumpSymbolIdField(OS
, "typeId", getTypeId(), Indent
, Session
,
48 PdbSymbolIdField::Type
, ShowIdFields
, RecurseIdFields
);
49 dumpSymbolField(OS
, "length", getLength(), Indent
);
50 dumpSymbolField(OS
, "constType", isConstType(), Indent
);
51 dumpSymbolField(OS
, "isPointerToDataMember", isPointerToDataMember(), Indent
);
52 dumpSymbolField(OS
, "isPointerToMemberFunction", isPointerToMemberFunction(),
54 dumpSymbolField(OS
, "RValueReference", isRValueReference(), Indent
);
55 dumpSymbolField(OS
, "reference", isReference(), Indent
);
56 dumpSymbolField(OS
, "restrictedType", isRestrictedType(), Indent
);
57 if (isMemberPointer()) {
58 if (isSingleInheritance())
59 dumpSymbolField(OS
, "isSingleInheritance", 1, Indent
);
60 else if (isMultipleInheritance())
61 dumpSymbolField(OS
, "isMultipleInheritance", 1, Indent
);
62 else if (isVirtualInheritance())
63 dumpSymbolField(OS
, "isVirtualInheritance", 1, Indent
);
65 dumpSymbolField(OS
, "unalignedType", isUnalignedType(), Indent
);
66 dumpSymbolField(OS
, "volatileType", isVolatileType(), Indent
);
69 SymIndexId
NativeTypePointer::getClassParentId() const {
70 if (!isMemberPointer())
74 const MemberPointerInfo
&MPI
= Record
->getMemberInfo();
75 return Session
.getSymbolCache().findSymbolByTypeIndex(MPI
.ContainingType
);
78 uint64_t NativeTypePointer::getLength() const {
80 return Record
->getSize();
82 switch (TI
.getSimpleMode()) {
83 case SimpleTypeMode::NearPointer
:
84 case SimpleTypeMode::FarPointer
:
85 case SimpleTypeMode::HugePointer
:
87 case SimpleTypeMode::NearPointer32
:
88 case SimpleTypeMode::FarPointer32
:
90 case SimpleTypeMode::NearPointer64
:
92 case SimpleTypeMode::NearPointer128
:
95 assert(false && "invalid simple type mode!");
100 SymIndexId
NativeTypePointer::getTypeId() const {
101 // This is the pointee SymIndexId.
102 TypeIndex Referent
= Record
? Record
->ReferentType
: TI
.makeDirect();
104 return Session
.getSymbolCache().findSymbolByTypeIndex(Referent
);
107 bool NativeTypePointer::isReference() const {
110 return Record
->getMode() == PointerMode::LValueReference
;
113 bool NativeTypePointer::isRValueReference() const {
116 return Record
->getMode() == PointerMode::RValueReference
;
119 bool NativeTypePointer::isPointerToDataMember() const {
122 return Record
->getMode() == PointerMode::PointerToDataMember
;
125 bool NativeTypePointer::isPointerToMemberFunction() const {
128 return Record
->getMode() == PointerMode::PointerToMemberFunction
;
131 bool NativeTypePointer::isConstType() const {
134 return (Record
->getOptions() & PointerOptions::Const
) != PointerOptions::None
;
137 bool NativeTypePointer::isRestrictedType() const {
140 return (Record
->getOptions() & PointerOptions::Restrict
) !=
141 PointerOptions::None
;
144 bool NativeTypePointer::isVolatileType() const {
147 return (Record
->getOptions() & PointerOptions::Volatile
) !=
148 PointerOptions::None
;
151 bool NativeTypePointer::isUnalignedType() const {
154 return (Record
->getOptions() & PointerOptions::Unaligned
) !=
155 PointerOptions::None
;
158 static inline bool isInheritanceKind(const MemberPointerInfo
&MPI
,
159 PointerToMemberRepresentation P1
,
160 PointerToMemberRepresentation P2
) {
161 return (MPI
.getRepresentation() == P1
|| MPI
.getRepresentation() == P2
);
164 bool NativeTypePointer::isSingleInheritance() const {
165 if (!isMemberPointer())
167 return isInheritanceKind(
168 Record
->getMemberInfo(),
169 PointerToMemberRepresentation::SingleInheritanceData
,
170 PointerToMemberRepresentation::SingleInheritanceFunction
);
173 bool NativeTypePointer::isMultipleInheritance() const {
174 if (!isMemberPointer())
176 return isInheritanceKind(
177 Record
->getMemberInfo(),
178 PointerToMemberRepresentation::MultipleInheritanceData
,
179 PointerToMemberRepresentation::MultipleInheritanceFunction
);
182 bool NativeTypePointer::isVirtualInheritance() const {
183 if (!isMemberPointer())
185 return isInheritanceKind(
186 Record
->getMemberInfo(),
187 PointerToMemberRepresentation::VirtualInheritanceData
,
188 PointerToMemberRepresentation::VirtualInheritanceFunction
);
191 bool NativeTypePointer::isMemberPointer() const {
192 return isPointerToDataMember() || isPointerToMemberFunction();