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 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 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 32 NativeTypePointer::~NativeTypePointer() {} 33 34 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 69 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 78 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 100 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 107 bool NativeTypePointer::isReference() const { 108 if (!Record) 109 return false; 110 return Record->getMode() == PointerMode::LValueReference; 111 } 112 113 bool NativeTypePointer::isRValueReference() const { 114 if (!Record) 115 return false; 116 return Record->getMode() == PointerMode::RValueReference; 117 } 118 119 bool NativeTypePointer::isPointerToDataMember() const { 120 if (!Record) 121 return false; 122 return Record->getMode() == PointerMode::PointerToDataMember; 123 } 124 125 bool NativeTypePointer::isPointerToMemberFunction() const { 126 if (!Record) 127 return false; 128 return Record->getMode() == PointerMode::PointerToMemberFunction; 129 } 130 131 bool NativeTypePointer::isConstType() const { 132 if (!Record) 133 return false; 134 return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None; 135 } 136 137 bool NativeTypePointer::isRestrictedType() const { 138 if (!Record) 139 return false; 140 return (Record->getOptions() & PointerOptions::Restrict) != 141 PointerOptions::None; 142 } 143 144 bool NativeTypePointer::isVolatileType() const { 145 if (!Record) 146 return false; 147 return (Record->getOptions() & PointerOptions::Volatile) != 148 PointerOptions::None; 149 } 150 151 bool NativeTypePointer::isUnalignedType() const { 152 if (!Record) 153 return false; 154 return (Record->getOptions() & PointerOptions::Unaligned) != 155 PointerOptions::None; 156 } 157 158 static inline bool isInheritanceKind(const MemberPointerInfo &MPI, 159 PointerToMemberRepresentation P1, 160 PointerToMemberRepresentation P2) { 161 return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2); 162 } 163 164 bool NativeTypePointer::isSingleInheritance() const { 165 if (!isMemberPointer()) 166 return false; 167 return isInheritanceKind( 168 Record->getMemberInfo(), 169 PointerToMemberRepresentation::SingleInheritanceData, 170 PointerToMemberRepresentation::SingleInheritanceFunction); 171 } 172 173 bool NativeTypePointer::isMultipleInheritance() const { 174 if (!isMemberPointer()) 175 return false; 176 return isInheritanceKind( 177 Record->getMemberInfo(), 178 PointerToMemberRepresentation::MultipleInheritanceData, 179 PointerToMemberRepresentation::MultipleInheritanceFunction); 180 } 181 182 bool NativeTypePointer::isVirtualInheritance() const { 183 if (!isMemberPointer()) 184 return false; 185 return isInheritanceKind( 186 Record->getMemberInfo(), 187 PointerToMemberRepresentation::VirtualInheritanceData, 188 PointerToMemberRepresentation::VirtualInheritanceFunction); 189 } 190 191 bool NativeTypePointer::isMemberPointer() const { 192 return isPointerToDataMember() || isPointerToMemberFunction(); 193 } 194