| //===- NativeTypePointer.cpp - info about pointer type ----------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" |
| |
| #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" |
| |
| #include <cassert> |
| |
| using namespace llvm; |
| using namespace llvm::codeview; |
| using namespace llvm::pdb; |
| |
| NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id, |
| codeview::TypeIndex TI) |
| : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI) { |
| assert(TI.isSimple()); |
| assert(TI.getSimpleMode() != SimpleTypeMode::Direct); |
| } |
| |
| NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id, |
| codeview::TypeIndex TI, |
| codeview::PointerRecord Record) |
| : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI), |
| Record(std::move(Record)) {} |
| |
| NativeTypePointer::~NativeTypePointer() {} |
| |
| void NativeTypePointer::dump(raw_ostream &OS, int Indent, |
| PdbSymbolIdField ShowIdFields, |
| PdbSymbolIdField RecurseIdFields) const { |
| NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); |
| |
| if (isMemberPointer()) { |
| dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session, |
| PdbSymbolIdField::ClassParent, ShowIdFields, |
| RecurseIdFields); |
| } |
| dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, |
| PdbSymbolIdField::LexicalParent, ShowIdFields, |
| RecurseIdFields); |
| dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, |
| PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); |
| dumpSymbolField(OS, "length", getLength(), Indent); |
| dumpSymbolField(OS, "constType", isConstType(), Indent); |
| dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent); |
| dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(), |
| Indent); |
| dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent); |
| dumpSymbolField(OS, "reference", isReference(), Indent); |
| dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent); |
| if (isMemberPointer()) { |
| if (isSingleInheritance()) |
| dumpSymbolField(OS, "isSingleInheritance", 1, Indent); |
| else if (isMultipleInheritance()) |
| dumpSymbolField(OS, "isMultipleInheritance", 1, Indent); |
| else if (isVirtualInheritance()) |
| dumpSymbolField(OS, "isVirtualInheritance", 1, Indent); |
| } |
| dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); |
| dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); |
| } |
| |
| SymIndexId NativeTypePointer::getClassParentId() const { |
| if (!isMemberPointer()) |
| return 0; |
| |
| assert(Record); |
| const MemberPointerInfo &MPI = Record->getMemberInfo(); |
| return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType); |
| } |
| |
| uint64_t NativeTypePointer::getLength() const { |
| if (Record) |
| return Record->getSize(); |
| |
| switch (TI.getSimpleMode()) { |
| case SimpleTypeMode::NearPointer: |
| case SimpleTypeMode::FarPointer: |
| case SimpleTypeMode::HugePointer: |
| return 2; |
| case SimpleTypeMode::NearPointer32: |
| case SimpleTypeMode::FarPointer32: |
| return 4; |
| case SimpleTypeMode::NearPointer64: |
| return 8; |
| case SimpleTypeMode::NearPointer128: |
| return 16; |
| default: |
| assert(false && "invalid simple type mode!"); |
| } |
| return 0; |
| } |
| |
| SymIndexId NativeTypePointer::getTypeId() const { |
| // This is the pointee SymIndexId. |
| TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect(); |
| |
| return Session.getSymbolCache().findSymbolByTypeIndex(Referent); |
| } |
| |
| bool NativeTypePointer::isReference() const { |
| if (!Record) |
| return false; |
| return Record->getMode() == PointerMode::LValueReference; |
| } |
| |
| bool NativeTypePointer::isRValueReference() const { |
| if (!Record) |
| return false; |
| return Record->getMode() == PointerMode::RValueReference; |
| } |
| |
| bool NativeTypePointer::isPointerToDataMember() const { |
| if (!Record) |
| return false; |
| return Record->getMode() == PointerMode::PointerToDataMember; |
| } |
| |
| bool NativeTypePointer::isPointerToMemberFunction() const { |
| if (!Record) |
| return false; |
| return Record->getMode() == PointerMode::PointerToMemberFunction; |
| } |
| |
| bool NativeTypePointer::isConstType() const { |
| if (!Record) |
| return false; |
| return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None; |
| } |
| |
| bool NativeTypePointer::isRestrictedType() const { |
| if (!Record) |
| return false; |
| return (Record->getOptions() & PointerOptions::Restrict) != |
| PointerOptions::None; |
| } |
| |
| bool NativeTypePointer::isVolatileType() const { |
| if (!Record) |
| return false; |
| return (Record->getOptions() & PointerOptions::Volatile) != |
| PointerOptions::None; |
| } |
| |
| bool NativeTypePointer::isUnalignedType() const { |
| if (!Record) |
| return false; |
| return (Record->getOptions() & PointerOptions::Unaligned) != |
| PointerOptions::None; |
| } |
| |
| static inline bool isInheritanceKind(const MemberPointerInfo &MPI, |
| PointerToMemberRepresentation P1, |
| PointerToMemberRepresentation P2) { |
| return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2); |
| } |
| |
| bool NativeTypePointer::isSingleInheritance() const { |
| if (!isMemberPointer()) |
| return false; |
| return isInheritanceKind( |
| Record->getMemberInfo(), |
| PointerToMemberRepresentation::SingleInheritanceData, |
| PointerToMemberRepresentation::SingleInheritanceFunction); |
| } |
| |
| bool NativeTypePointer::isMultipleInheritance() const { |
| if (!isMemberPointer()) |
| return false; |
| return isInheritanceKind( |
| Record->getMemberInfo(), |
| PointerToMemberRepresentation::MultipleInheritanceData, |
| PointerToMemberRepresentation::MultipleInheritanceFunction); |
| } |
| |
| bool NativeTypePointer::isVirtualInheritance() const { |
| if (!isMemberPointer()) |
| return false; |
| return isInheritanceKind( |
| Record->getMemberInfo(), |
| PointerToMemberRepresentation::VirtualInheritanceData, |
| PointerToMemberRepresentation::VirtualInheritanceFunction); |
| } |
| |
| bool NativeTypePointer::isMemberPointer() const { |
| return isPointerToDataMember() || isPointerToMemberFunction(); |
| } |