1 //===- NativeTypePointer.cpp - info about pointer type ----------*- 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/PDB/Native/NativeTypePointer.h"
10
11 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
12
13 #include <cassert>
14
15 using namespace llvm;
16 using namespace llvm::codeview;
17 using namespace llvm::pdb;
18
NativeTypePointer(NativeSession & Session,SymIndexId Id,codeview::TypeIndex TI)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);
24 }
25
NativeTypePointer(NativeSession & Session,SymIndexId Id,codeview::TypeIndex TI,codeview::PointerRecord Record)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)) {}
31
~NativeTypePointer()32 NativeTypePointer::~NativeTypePointer() {}
33
dump(raw_ostream & OS,int Indent,PdbSymbolIdField ShowIdFields,PdbSymbolIdField RecurseIdFields) const34 void NativeTypePointer::dump(raw_ostream &OS, int Indent,
35 PdbSymbolIdField ShowIdFields,
36 PdbSymbolIdField RecurseIdFields) const {
37 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
38
39 if (isMemberPointer()) {
40 dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
41 PdbSymbolIdField::ClassParent, ShowIdFields,
42 RecurseIdFields);
43 }
44 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
45 PdbSymbolIdField::LexicalParent, ShowIdFields,
46 RecurseIdFields);
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(),
53 Indent);
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);
64 }
65 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
66 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
67 }
68
getClassParentId() const69 SymIndexId NativeTypePointer::getClassParentId() const {
70 if (!isMemberPointer())
71 return 0;
72
73 assert(Record);
74 const MemberPointerInfo &MPI = Record->getMemberInfo();
75 return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType);
76 }
77
getLength() const78 uint64_t NativeTypePointer::getLength() const {
79 if (Record)
80 return Record->getSize();
81
82 switch (TI.getSimpleMode()) {
83 case SimpleTypeMode::NearPointer:
84 case SimpleTypeMode::FarPointer:
85 case SimpleTypeMode::HugePointer:
86 return 2;
87 case SimpleTypeMode::NearPointer32:
88 case SimpleTypeMode::FarPointer32:
89 return 4;
90 case SimpleTypeMode::NearPointer64:
91 return 8;
92 case SimpleTypeMode::NearPointer128:
93 return 16;
94 default:
95 assert(false && "invalid simple type mode!");
96 }
97 return 0;
98 }
99
getTypeId() const100 SymIndexId NativeTypePointer::getTypeId() const {
101 // This is the pointee SymIndexId.
102 TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect();
103
104 return Session.getSymbolCache().findSymbolByTypeIndex(Referent);
105 }
106
isReference() const107 bool NativeTypePointer::isReference() const {
108 if (!Record)
109 return false;
110 return Record->getMode() == PointerMode::LValueReference;
111 }
112
isRValueReference() const113 bool NativeTypePointer::isRValueReference() const {
114 if (!Record)
115 return false;
116 return Record->getMode() == PointerMode::RValueReference;
117 }
118
isPointerToDataMember() const119 bool NativeTypePointer::isPointerToDataMember() const {
120 if (!Record)
121 return false;
122 return Record->getMode() == PointerMode::PointerToDataMember;
123 }
124
isPointerToMemberFunction() const125 bool NativeTypePointer::isPointerToMemberFunction() const {
126 if (!Record)
127 return false;
128 return Record->getMode() == PointerMode::PointerToMemberFunction;
129 }
130
isConstType() const131 bool NativeTypePointer::isConstType() const {
132 if (!Record)
133 return false;
134 return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None;
135 }
136
isRestrictedType() const137 bool NativeTypePointer::isRestrictedType() const {
138 if (!Record)
139 return false;
140 return (Record->getOptions() & PointerOptions::Restrict) !=
141 PointerOptions::None;
142 }
143
isVolatileType() const144 bool NativeTypePointer::isVolatileType() const {
145 if (!Record)
146 return false;
147 return (Record->getOptions() & PointerOptions::Volatile) !=
148 PointerOptions::None;
149 }
150
isUnalignedType() const151 bool NativeTypePointer::isUnalignedType() const {
152 if (!Record)
153 return false;
154 return (Record->getOptions() & PointerOptions::Unaligned) !=
155 PointerOptions::None;
156 }
157
isInheritanceKind(const MemberPointerInfo & MPI,PointerToMemberRepresentation P1,PointerToMemberRepresentation P2)158 static inline bool isInheritanceKind(const MemberPointerInfo &MPI,
159 PointerToMemberRepresentation P1,
160 PointerToMemberRepresentation P2) {
161 return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2);
162 }
163
isSingleInheritance() const164 bool NativeTypePointer::isSingleInheritance() const {
165 if (!isMemberPointer())
166 return false;
167 return isInheritanceKind(
168 Record->getMemberInfo(),
169 PointerToMemberRepresentation::SingleInheritanceData,
170 PointerToMemberRepresentation::SingleInheritanceFunction);
171 }
172
isMultipleInheritance() const173 bool NativeTypePointer::isMultipleInheritance() const {
174 if (!isMemberPointer())
175 return false;
176 return isInheritanceKind(
177 Record->getMemberInfo(),
178 PointerToMemberRepresentation::MultipleInheritanceData,
179 PointerToMemberRepresentation::MultipleInheritanceFunction);
180 }
181
isVirtualInheritance() const182 bool NativeTypePointer::isVirtualInheritance() const {
183 if (!isMemberPointer())
184 return false;
185 return isInheritanceKind(
186 Record->getMemberInfo(),
187 PointerToMemberRepresentation::VirtualInheritanceData,
188 PointerToMemberRepresentation::VirtualInheritanceFunction);
189 }
190
isMemberPointer() const191 bool NativeTypePointer::isMemberPointer() const {
192 return isPointerToDataMember() || isPointerToMemberFunction();
193 }
194