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 16 using namespace llvm; 17 using namespace llvm::codeview; 18 using namespace llvm::pdb; 19 20 NativeTypePointer::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 27 NativeTypePointer::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 33 NativeTypePointer::~NativeTypePointer() = default; 34 35 void 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, "classParentId", getClassParentId(), Indent, Session, 42 PdbSymbolIdField::ClassParent, ShowIdFields, 43 RecurseIdFields); 44 } 45 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, 46 PdbSymbolIdField::LexicalParent, ShowIdFields, 47 RecurseIdFields); 48 dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, 49 PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); 50 dumpSymbolField(OS, "length", getLength(), Indent); 51 dumpSymbolField(OS, "constType", isConstType(), Indent); 52 dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent); 53 dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(), 54 Indent); 55 dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent); 56 dumpSymbolField(OS, "reference", isReference(), Indent); 57 dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent); 58 if (isMemberPointer()) { 59 if (isSingleInheritance()) 60 dumpSymbolField(OS, "isSingleInheritance", 1, Indent); 61 else if (isMultipleInheritance()) 62 dumpSymbolField(OS, "isMultipleInheritance", 1, Indent); 63 else if (isVirtualInheritance()) 64 dumpSymbolField(OS, "isVirtualInheritance", 1, Indent); 65 } 66 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); 67 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); 68 } 69 70 SymIndexId NativeTypePointer::getClassParentId() const { 71 if (!isMemberPointer()) 72 return 0; 73 74 assert(Record); 75 const MemberPointerInfo &MPI = Record->getMemberInfo(); 76 return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType); 77 } 78 79 uint64_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 101 SymIndexId NativeTypePointer::getTypeId() const { 102 // This is the pointee SymIndexId. 103 TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect(); 104 105 return Session.getSymbolCache().findSymbolByTypeIndex(Referent); 106 } 107 108 bool NativeTypePointer::isReference() const { 109 if (!Record) 110 return false; 111 return Record->getMode() == PointerMode::LValueReference; 112 } 113 114 bool NativeTypePointer::isRValueReference() const { 115 if (!Record) 116 return false; 117 return Record->getMode() == PointerMode::RValueReference; 118 } 119 120 bool NativeTypePointer::isPointerToDataMember() const { 121 if (!Record) 122 return false; 123 return Record->getMode() == PointerMode::PointerToDataMember; 124 } 125 126 bool NativeTypePointer::isPointerToMemberFunction() const { 127 if (!Record) 128 return false; 129 return Record->getMode() == PointerMode::PointerToMemberFunction; 130 } 131 132 bool NativeTypePointer::isConstType() const { 133 if (!Record) 134 return false; 135 return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None; 136 } 137 138 bool NativeTypePointer::isRestrictedType() const { 139 if (!Record) 140 return false; 141 return (Record->getOptions() & PointerOptions::Restrict) != 142 PointerOptions::None; 143 } 144 145 bool NativeTypePointer::isVolatileType() const { 146 if (!Record) 147 return false; 148 return (Record->getOptions() & PointerOptions::Volatile) != 149 PointerOptions::None; 150 } 151 152 bool NativeTypePointer::isUnalignedType() const { 153 if (!Record) 154 return false; 155 return (Record->getOptions() & PointerOptions::Unaligned) != 156 PointerOptions::None; 157 } 158 159 static inline bool isInheritanceKind(const MemberPointerInfo &MPI, 160 PointerToMemberRepresentation P1, 161 PointerToMemberRepresentation P2) { 162 return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2); 163 } 164 165 bool NativeTypePointer::isSingleInheritance() const { 166 if (!isMemberPointer()) 167 return false; 168 return isInheritanceKind( 169 Record->getMemberInfo(), 170 PointerToMemberRepresentation::SingleInheritanceData, 171 PointerToMemberRepresentation::SingleInheritanceFunction); 172 } 173 174 bool NativeTypePointer::isMultipleInheritance() const { 175 if (!isMemberPointer()) 176 return false; 177 return isInheritanceKind( 178 Record->getMemberInfo(), 179 PointerToMemberRepresentation::MultipleInheritanceData, 180 PointerToMemberRepresentation::MultipleInheritanceFunction); 181 } 182 183 bool NativeTypePointer::isVirtualInheritance() const { 184 if (!isMemberPointer()) 185 return false; 186 return isInheritanceKind( 187 Record->getMemberInfo(), 188 PointerToMemberRepresentation::VirtualInheritanceData, 189 PointerToMemberRepresentation::VirtualInheritanceFunction); 190 } 191 192 bool NativeTypePointer::isMemberPointer() const { 193 return isPointerToDataMember() || isPointerToMemberFunction(); 194 } 195