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#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
11
12#include "llvm/DebugInfo/CodeView/CodeView.h"
13
14#include <cassert>
15
16using namespace llvm;
17using namespace llvm::codeview;
18using namespace llvm::pdb;
19
20NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
21 codeview::TypeIndex TI)
22 : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI) {
23 assert(TI.isSimple());
24 assert(TI.getSimpleMode() != SimpleTypeMode::Direct);
25}
26
27NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
28 codeview::TypeIndex TI,
29 codeview::PointerRecord Record)
30 : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI),
31 Record(std::move(Record)) {}
32
33NativeTypePointer::~NativeTypePointer() = default;
34
35void NativeTypePointer::dump(raw_ostream &OS, int Indent,
36 PdbSymbolIdField ShowIdFields,
37 PdbSymbolIdField RecurseIdFields) const {
38 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
39
40 if (isMemberPointer()) {
41 dumpSymbolIdField(OS, Name: "classParentId", Value: getClassParentId(), Indent, Session,
42 FieldId: PdbSymbolIdField::ClassParent, ShowFlags: ShowIdFields,
43 RecurseFlags: RecurseIdFields);
44 }
45 dumpSymbolIdField(OS, Name: "lexicalParentId", Value: 0, Indent, Session,
46 FieldId: PdbSymbolIdField::LexicalParent, ShowFlags: ShowIdFields,
47 RecurseFlags: RecurseIdFields);
48 dumpSymbolIdField(OS, Name: "typeId", Value: getTypeId(), Indent, Session,
49 FieldId: PdbSymbolIdField::Type, ShowFlags: ShowIdFields, RecurseFlags: RecurseIdFields);
50 dumpSymbolField(OS, Name: "length", Value: getLength(), Indent);
51 dumpSymbolField(OS, Name: "constType", Value: isConstType(), Indent);
52 dumpSymbolField(OS, Name: "isPointerToDataMember", Value: isPointerToDataMember(), Indent);
53 dumpSymbolField(OS, Name: "isPointerToMemberFunction", Value: isPointerToMemberFunction(),
54 Indent);
55 dumpSymbolField(OS, Name: "RValueReference", Value: isRValueReference(), Indent);
56 dumpSymbolField(OS, Name: "reference", Value: isReference(), Indent);
57 dumpSymbolField(OS, Name: "restrictedType", Value: isRestrictedType(), Indent);
58 if (isMemberPointer()) {
59 if (isSingleInheritance())
60 dumpSymbolField(OS, Name: "isSingleInheritance", Value: 1, Indent);
61 else if (isMultipleInheritance())
62 dumpSymbolField(OS, Name: "isMultipleInheritance", Value: 1, Indent);
63 else if (isVirtualInheritance())
64 dumpSymbolField(OS, Name: "isVirtualInheritance", Value: 1, Indent);
65 }
66 dumpSymbolField(OS, Name: "unalignedType", Value: isUnalignedType(), Indent);
67 dumpSymbolField(OS, Name: "volatileType", Value: isVolatileType(), Indent);
68}
69
70SymIndexId NativeTypePointer::getClassParentId() const {
71 if (!isMemberPointer())
72 return 0;
73
74 assert(Record);
75 const MemberPointerInfo &MPI = Record->getMemberInfo();
76 return Session.getSymbolCache().findSymbolByTypeIndex(TI: MPI.ContainingType);
77}
78
79uint64_t NativeTypePointer::getLength() const {
80 if (Record)
81 return Record->getSize();
82
83 switch (TI.getSimpleMode()) {
84 case SimpleTypeMode::NearPointer:
85 case SimpleTypeMode::FarPointer:
86 case SimpleTypeMode::HugePointer:
87 return 2;
88 case SimpleTypeMode::NearPointer32:
89 case SimpleTypeMode::FarPointer32:
90 return 4;
91 case SimpleTypeMode::NearPointer64:
92 return 8;
93 case SimpleTypeMode::NearPointer128:
94 return 16;
95 default:
96 assert(false && "invalid simple type mode!");
97 }
98 return 0;
99}
100
101SymIndexId NativeTypePointer::getTypeId() const {
102 // This is the pointee SymIndexId.
103 TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect();
104
105 return Session.getSymbolCache().findSymbolByTypeIndex(TI: Referent);
106}
107
108bool NativeTypePointer::isReference() const {
109 if (!Record)
110 return false;
111 return Record->getMode() == PointerMode::LValueReference;
112}
113
114bool NativeTypePointer::isRValueReference() const {
115 if (!Record)
116 return false;
117 return Record->getMode() == PointerMode::RValueReference;
118}
119
120bool NativeTypePointer::isPointerToDataMember() const {
121 if (!Record)
122 return false;
123 return Record->getMode() == PointerMode::PointerToDataMember;
124}
125
126bool NativeTypePointer::isPointerToMemberFunction() const {
127 if (!Record)
128 return false;
129 return Record->getMode() == PointerMode::PointerToMemberFunction;
130}
131
132bool NativeTypePointer::isConstType() const {
133 if (!Record)
134 return false;
135 return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None;
136}
137
138bool NativeTypePointer::isRestrictedType() const {
139 if (!Record)
140 return false;
141 return (Record->getOptions() & PointerOptions::Restrict) !=
142 PointerOptions::None;
143}
144
145bool NativeTypePointer::isVolatileType() const {
146 if (!Record)
147 return false;
148 return (Record->getOptions() & PointerOptions::Volatile) !=
149 PointerOptions::None;
150}
151
152bool NativeTypePointer::isUnalignedType() const {
153 if (!Record)
154 return false;
155 return (Record->getOptions() & PointerOptions::Unaligned) !=
156 PointerOptions::None;
157}
158
159static inline bool isInheritanceKind(const MemberPointerInfo &MPI,
160 PointerToMemberRepresentation P1,
161 PointerToMemberRepresentation P2) {
162 return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2);
163}
164
165bool NativeTypePointer::isSingleInheritance() const {
166 if (!isMemberPointer())
167 return false;
168 return isInheritanceKind(
169 MPI: Record->getMemberInfo(),
170 P1: PointerToMemberRepresentation::SingleInheritanceData,
171 P2: PointerToMemberRepresentation::SingleInheritanceFunction);
172}
173
174bool NativeTypePointer::isMultipleInheritance() const {
175 if (!isMemberPointer())
176 return false;
177 return isInheritanceKind(
178 MPI: Record->getMemberInfo(),
179 P1: PointerToMemberRepresentation::MultipleInheritanceData,
180 P2: PointerToMemberRepresentation::MultipleInheritanceFunction);
181}
182
183bool NativeTypePointer::isVirtualInheritance() const {
184 if (!isMemberPointer())
185 return false;
186 return isInheritanceKind(
187 MPI: Record->getMemberInfo(),
188 P1: PointerToMemberRepresentation::VirtualInheritanceData,
189 P2: PointerToMemberRepresentation::VirtualInheritanceFunction);
190}
191
192bool NativeTypePointer::isMemberPointer() const {
193 return isPointerToDataMember() || isPointerToMemberFunction();
194}
195

source code of llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp