Index: lldb/lit/SymbolFile/NativePDB/member-function-types.cpp =================================================================== --- lldb/lit/SymbolFile/NativePDB/member-function-types.cpp +++ lldb/lit/SymbolFile/NativePDB/member-function-types.cpp @@ -11,7 +11,15 @@ void MemberFn() { } void ConstFn() const {} void ConstVolFn() const volatile {} - void RefFn() && {} + + void Overloaded(int x) {} + void Overloaded(int x) const {} + void Overloaded(double x) {} + + void RefOverload(double x) & {} + void RefOverload(double x) && {} + + int DataMember = 0; }; auto sfn = &Foo::StaticFn; @@ -22,7 +30,7 @@ auto cvfn = &Foo::ConstVolFn; -auto rfn = &Foo::RefFn; +auto dm = &Foo::DataMember; int main(int argc, char **argv) { return 0; Index: llvm/include/llvm/DebugInfo/CodeView/CodeView.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/CodeView.h +++ llvm/include/llvm/DebugInfo/CodeView/CodeView.h @@ -352,16 +352,23 @@ /// Equivalent to misc lfPointerAttr bitfields. enum class PointerOptions : uint32_t { - None = 0x00000000, - Flat32 = 0x00000100, - Volatile = 0x00000200, - Const = 0x00000400, - Unaligned = 0x00000800, - Restrict = 0x00001000, - WinRTSmartPointer = 0x00080000 + None = 0x00, + Flat32 = 0x01, + Volatile = 0x02, + Const = 0x04, + Unaligned = 0x08, + Restrict = 0x10, }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerOptions) +enum class PointerQualifier : uint32_t { + None = 0x0, + WinRTSmartPointer = 0x01, + ThisPtrLValueRef = 0x02, + ThisPtrRValueRef = 0x04 +}; +CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerQualifier) + /// Equivalent to CV_pmtype_e. enum class PointerToMemberRepresentation : uint16_t { Unknown = 0x00, // not specified (pre VC8) Index: llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -264,16 +264,26 @@ // LF_POINTER class PointerRecord : public TypeRecord { public: + // See the lfPointer::lfPointerAttr enumeration in cvinfo.h + // ---------------------------XXXXX static const uint32_t PointerKindShift = 0; static const uint32_t PointerKindMask = 0x1F; + // ------------------------XXX----- static const uint32_t PointerModeShift = 5; static const uint32_t PointerModeMask = 0x07; - static const uint32_t PointerOptionMask = 0xFF; + // -------------------XXXXX-------- + static const uint32_t PointerOptionShift = 8; + static const uint32_t PointerOptionMask = 0x1F; + // -------------XXXXXX------------- static const uint32_t PointerSizeShift = 13; - static const uint32_t PointerSizeMask = 0xFF; + static const uint32_t PointerSizeMask = 0x3F; + + // ----------XXX------------------- + static const uint32_t PointerQualifierShift = 19; + static const uint32_t PointerQualifierMask = 0x07; PointerRecord() = default; explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} @@ -283,14 +293,15 @@ Attrs(Attrs) {} PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, - PointerOptions PO, uint8_t Size) + PointerOptions PO, PointerQualifier PQ, uint8_t Size) : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), - Attrs(calcAttrs(PK, PM, PO, Size)) {} + Attrs(calcAttrs(PK, PM, PO, PQ, Size)) {} PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, - PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI) + PointerOptions PO, PointerQualifier PQ, uint8_t Size, + const MemberPointerInfo &MPI) : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), - Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {} + Attrs(calcAttrs(PK, PM, PO, PQ, Size)), MemberInfo(MPI) {} TypeIndex getReferentType() const { return ReferentType; } @@ -305,7 +316,13 @@ } PointerOptions getOptions() const { - return static_cast(Attrs); + return static_cast((Attrs >> PointerOptionShift) & + PointerOptionMask); + } + + PointerQualifier getQualifier() const { + return static_cast((Attrs >> PointerQualifierShift) & + PointerQualifierMask); } uint8_t getSize() const { @@ -319,19 +336,33 @@ getMode() == PointerMode::PointerToMemberFunction; } - bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); } - bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); } + bool isFlat() const { + return (getOptions() & PointerOptions::Flat32) != PointerOptions::None; + } + bool isConst() const { + return (getOptions() & PointerOptions::Const) != PointerOptions::None; + } bool isVolatile() const { - return !!(Attrs & uint32_t(PointerOptions::Volatile)); + return (getOptions() & PointerOptions::Volatile) != PointerOptions::None; } bool isUnaligned() const { - return !!(Attrs & uint32_t(PointerOptions::Unaligned)); + return (getOptions() & PointerOptions::Unaligned) != PointerOptions::None; } bool isRestrict() const { - return !!(Attrs & uint32_t(PointerOptions::Restrict)); + return (getOptions() & PointerOptions::Restrict) != PointerOptions::None; + } + + bool isThisPtrLValueRefQual() const { + return (getQualifier() & PointerQualifier::ThisPtrLValueRef) != + PointerQualifier::None; + } + + bool isThisPtrRValueRefQual() const { + return (getQualifier() & PointerQualifier::ThisPtrRValueRef) != + PointerQualifier::None; } TypeIndex ReferentType; @@ -339,18 +370,19 @@ Optional MemberInfo; void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO, - uint8_t Size) { - Attrs = calcAttrs(PK, PM, PO, Size); + PointerQualifier PQ, uint8_t Size) { + Attrs = calcAttrs(PK, PM, PO, PQ, Size); } private: static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO, - uint8_t Size) { + PointerQualifier PQ, uint8_t Size) { uint32_t A = 0; A |= static_cast(PK); - A |= static_cast(PO); + A |= (static_cast(PO) << PointerOptionShift); A |= (static_cast(PM) << PointerModeShift); A |= (static_cast(Size) << PointerSizeShift); + A |= (static_cast(PQ) << PointerQualifierShift); return A; } }; Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -345,6 +345,10 @@ codeview::TypeIndex getTypeIndexForReferenceTo(DITypeRef TypeRef); + codeview::TypeIndex + getTypeIndexForThisPtr(DITypeRef TypeRef, + const DISubroutineType *SubroutineTy); + codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, const DICompositeType *Class); @@ -362,7 +366,8 @@ codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); codeview::TypeIndex lowerTypePointer( const DIDerivedType *Ty, - codeview::PointerOptions PO = codeview::PointerOptions::None); + codeview::PointerOptions PO = codeview::PointerOptions::None, + codeview::PointerQualifier PQ = codeview::PointerQualifier::None); codeview::TypeIndex lowerTypeMemberPointer( const DIDerivedType *Ty, codeview::PointerOptions PO = codeview::PointerOptions::None); Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1683,7 +1683,8 @@ } TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty, - PointerOptions PO) { + PointerOptions PO, + PointerQualifier PQ) { TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType()); // Pointers to simple types without any options can use SimpleTypeMode, rather @@ -1713,7 +1714,7 @@ break; } - PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8); + PointerRecord PR(PointeeTI, PK, PM, PO, PQ, Ty->getSizeInBits() / 8); return TypeTable.writeLeafType(PR); } @@ -1765,7 +1766,8 @@ uint8_t SizeInBytes = Ty->getSizeInBits() / 8; MemberPointerInfo MPI( ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags())); - PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI); + PointerRecord PR(PointeeTI, PK, PM, PO, PointerQualifier::None, SizeInBytes, + MPI); return TypeTable.writeLeafType(PR); } @@ -1877,26 +1879,21 @@ // Lower the containing class type. TypeIndex ClassType = getTypeIndex(ClassTy); - SmallVector ReturnAndArgTypeIndices; - for (DITypeRef ArgTypeRef : Ty->getTypeArray()) - ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); + DITypeRefArray ReturnAndArgs = Ty->getTypeArray(); - // MSVC uses type none for variadic argument. - if (ReturnAndArgTypeIndices.size() > 1 && - ReturnAndArgTypeIndices.back() == TypeIndex::Void()) { - ReturnAndArgTypeIndices.back() = TypeIndex::None(); - } - TypeIndex ReturnTypeIndex = TypeIndex::Void(); - ArrayRef ArgTypeIndices = None; - if (!ReturnAndArgTypeIndices.empty()) { - auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); - ReturnTypeIndex = ReturnAndArgTypesRef.front(); - ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); - } + unsigned Index = 0; + SmallVector ArgTypeIndices; + TypeIndex ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); TypeIndex ThisTypeIndex; - if (!IsStaticMethod && !ArgTypeIndices.empty()) { - ThisTypeIndex = ArgTypeIndices.front(); - ArgTypeIndices = ArgTypeIndices.drop_front(); + if (!IsStaticMethod && ReturnAndArgs.size() > 1) + ThisTypeIndex = getTypeIndexForThisPtr(ReturnAndArgs[Index++], Ty); + + while (Index < ReturnAndArgs.size()) + ArgTypeIndices.push_back(getTypeIndex(ReturnAndArgs[Index++])); + + // MSVC uses type none for variadic argument. + if (!ArgTypeIndices.empty() && ArgTypeIndices.back() == TypeIndex::Void()) { + ArgTypeIndices.back() = TypeIndex::None(); } ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); @@ -2417,7 +2414,8 @@ : PointerKind::Near32; PointerMode PM = PointerMode::Pointer; PointerOptions PO = PointerOptions::None; - PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes()); + PointerRecord PR(ModifiedTI, PK, PM, PO, PointerQualifier::None, + getPointerSizeInBytes()); VBPType = TypeTable.writeLeafType(PR); } @@ -2444,13 +2442,45 @@ return recordTypeIndexForDINode(Ty, TI, ClassTy); } +TypeIndex +CodeViewDebug::getTypeIndexForThisPtr(DITypeRef TypeRef, + const DISubroutineType *SubroutineTy) { + const DIType *Ty = TypeRef.resolve(); + + PointerQualifier PQ = PointerQualifier::None; + if (SubroutineTy->getFlags() & DINode::DIFlags::FlagLValueReference) + PQ = PointerQualifier::ThisPtrLValueRef; + else if (SubroutineTy->getFlags() & DINode::DIFlags::FlagRValueReference) + PQ = PointerQualifier::ThisPtrRValueRef; + + // Check if we've already translated this type. If there is no ref qualifier + // on the function then we look up this pointer type with no associated class + // so that the TypeIndex for the this pointer can be shared with the type + // index for other pointers to this class type. If there is a ref qualifier + // then we lookup the pointer using the subroutine as the parent type. + const DIType *ParentTy = nullptr; + if (PQ != PointerQualifier::None) + ParentTy = SubroutineTy; + + auto I = TypeIndices.find({Ty, ParentTy}); + if (I != TypeIndices.end()) + return I->second; + + assert(Ty->getTag() == dwarf::DW_TAG_pointer_type); + + TypeLoweringScope S(*this); + TypeIndex TI = + lowerTypePointer(cast(Ty), PointerOptions::None, PQ); + return recordTypeIndexForDINode(Ty, TI, ParentTy); +} + TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) { DIType *Ty = TypeRef.resolve(); PointerRecord PR(getTypeIndex(Ty), getPointerSizeInBytes() == 8 ? PointerKind::Near64 : PointerKind::Near32, PointerMode::LValueReference, PointerOptions::None, - Ty->getSizeInBits() / 8); + PointerQualifier::None, Ty->getSizeInBits() / 8); return TypeTable.writeLeafType(PR); } Index: llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -361,7 +361,6 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) { printTypeIndex("PointeeType", Ptr.getReferentType()); - W->printHex("PointerAttributes", uint32_t(Ptr.getOptions())); W->printEnum("PtrType", unsigned(Ptr.getPointerKind()), makeArrayRef(PtrKindNames)); W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames)); @@ -371,6 +370,8 @@ W->printNumber("IsVolatile", Ptr.isVolatile()); W->printNumber("IsUnaligned", Ptr.isUnaligned()); W->printNumber("IsRestrict", Ptr.isRestrict()); + W->printNumber("IsThisPtr&", Ptr.isThisPtrLValueRefQual()); + W->printNumber("IsThisPtr&&", Ptr.isThisPtrRValueRefQual()); W->printNumber("SizeOf", Ptr.getSize()); if (Ptr.isPointerToMember()) { Index: llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp =================================================================== --- llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -333,8 +333,6 @@ IO.bitSetCase(Options, "Const", PointerOptions::Const); IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); - IO.bitSetCase(Options, "WinRTSmartPointer", - PointerOptions::WinRTSmartPointer); } void ScalarBitSetTraits::bitset(IO &IO, Index: llvm/test/DebugInfo/COFF/defer-complete-type.ll =================================================================== --- llvm/test/DebugInfo/COFF/defer-complete-type.ll +++ llvm/test/DebugInfo/COFF/defer-complete-type.ll @@ -30,7 +30,6 @@ ; CHECK: Pointer (0x1001) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: A (0x1000) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -72,7 +71,6 @@ ; CHECK: Pointer (0x1005) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: B (0x1004) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/globals.ll =================================================================== --- llvm/test/DebugInfo/COFF/globals.ll +++ llvm/test/DebugInfo/COFF/globals.ll @@ -59,7 +59,6 @@ ; OBJ: Pointer (0x1001) { ; OBJ: TypeLeafKind: LF_POINTER (0x1002) ; OBJ: PointeeType: const int (0x1000) -; OBJ: PointerAttributes: 0x1000C ; OBJ: PtrType: Near64 (0xC) ; OBJ: PtrMode: Pointer (0x0) ; OBJ: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/type-quals.ll =================================================================== --- llvm/test/DebugInfo/COFF/type-quals.ll +++ llvm/test/DebugInfo/COFF/type-quals.ll @@ -52,7 +52,6 @@ ; CHECK: Pointer (0x1001) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: const volatile int (0x1000) -; CHECK: PointerAttributes: 0x1100C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -99,7 +98,6 @@ ; CHECK: Pointer (0x1006) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x1100C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -112,7 +110,6 @@ ; CHECK: Pointer (0x1007) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: float (0x40) -; CHECK: PointerAttributes: 0x1100C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -125,7 +122,6 @@ ; CHECK: Pointer (0x1008) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x1120C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -170,7 +166,6 @@ ; CHECK: Pointer (0x100E) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: const int (0x100D) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -183,7 +178,6 @@ ; CHECK: Pointer (0x100F) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x1102C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: LValueReference (0x1) ; CHECK: IsFlat: 0 @@ -252,7 +246,6 @@ ; CHECK: Pointer (0x1017) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: h::Foo (0x1016) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -313,7 +306,6 @@ ; CHECK: Pointer (0x101D) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x904C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -328,7 +320,6 @@ ; CHECK: Pointer (0x101E) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int h::Foo::(int) (0x1019) -; CHECK: PointerAttributes: 0x1006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-array-advanced.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-array-advanced.ll +++ llvm/test/DebugInfo/COFF/types-array-advanced.ll @@ -53,7 +53,6 @@ ; CHECK: Pointer (0x1004) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: 0x1003 -; CHECK: PointerAttributes: 0x2A ; CHECK: PtrType: Near32 (0xA) ; CHECK: PtrMode: LValueReference (0x1) ; CHECK: IsFlat: 0 @@ -107,7 +106,6 @@ ; CHECK: Pointer (0x100A) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: 0x1009 -; CHECK: PointerAttributes: 0x800A ; CHECK: PtrType: Near32 (0xA) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-basic.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-basic.ll +++ llvm/test/DebugInfo/COFF/types-basic.ll @@ -69,7 +69,6 @@ ; CHECK: Pointer (0x1004) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: const int (0x1003) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -92,7 +91,6 @@ ; CHECK: Pointer (0x1006) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x804C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -105,7 +103,6 @@ ; CHECK: Pointer (0x1007) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: A (0x1005) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -170,7 +167,6 @@ ; CHECK: Pointer (0x100E) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void A::() (0x1009) -; CHECK: PointerAttributes: 0x1006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 @@ -190,7 +186,6 @@ ; CHECK: Pointer (0x1010) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: const void (0x100F) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-calling-conv.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-calling-conv.ll +++ llvm/test/DebugInfo/COFF/types-calling-conv.ll @@ -30,7 +30,6 @@ ; CHECK: Pointer (0x1001) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: A (0x1000) -; CHECK: PointerAttributes: 0x800A ; CHECK: PtrType: Near32 (0xA) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-data-members.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-data-members.ll +++ llvm/test/DebugInfo/COFF/types-data-members.ll @@ -247,7 +247,6 @@ ; CHECK: Pointer (0x1012) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: const int (0x1004) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -263,7 +262,6 @@ ; CHECK: Pointer (0x1014) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: (0x1013) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -362,7 +360,6 @@ ; CHECK: Pointer (0x101C) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: DerivedClass (0x1011) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-method-ref-qualifiers.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/COFF/types-method-ref-qualifiers.ll @@ -0,0 +1,89 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s + +; C++ source to regenerate: +; struct A { +; int NoRefQual(); +; +; int RefQual() &; +; int RefQual() &&; +; +; int LValueRef() &; +; +; int RValueRef() &&; +; }; +; +; void foo() { +; A *GenericPtr = nullptr; +; A a; +; } + + +; ModuleID = 'foo.cpp' +source_filename = "foo.cpp" +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.15.26732" + +%struct.A = type { i8 } + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?foo@@YAXXZ"() #0 !dbg !10 { +entry: + %GenericPtr = alloca %struct.A*, align 8 + %a = alloca %struct.A, align 1 + call void @llvm.dbg.declare(metadata %struct.A** %GenericPtr, metadata !13, metadata !DIExpression()), !dbg !28 + store %struct.A* null, %struct.A** %GenericPtr, align 8, !dbg !28 + call void @llvm.dbg.declare(metadata %struct.A* %a, metadata !29, metadata !DIExpression()), !dbg !30 + ret void, !dbg !31 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.linker.options = !{!3, !4} +!llvm.module.flags = !{!5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "foo.cpp", directory: "D:\5C\5Csrc\5C\5Cllvmbuild\5C\5Cninja-x64", checksumkind: CSK_MD5, checksum: "d1b6ae9dc9ab85ca0a41c8b8c79a0b6a") +!2 = !{} +!3 = !{!"/DEFAULTLIB:libcmt.lib"} +!4 = !{!"/DEFAULTLIB:oldnames.lib"} +!5 = !{i32 2, !"CodeView", i32 1} +!6 = !{i32 2, !"Debug Info Version", i32 3} +!7 = !{i32 1, !"wchar_size", i32 2} +!8 = !{i32 7, !"PIC Level", i32 2} +!9 = !{!"clang version 8.0.0 "} +!10 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXXZ", scope: !1, file: !1, line: 12, type: !11, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocalVariable(name: "GenericPtr", scope: !10, file: !1, line: 13, type: !14) +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 64) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !16, identifier: ".?AUA@@") +!16 = !{!17, !22, !24, !26, !27} +!17 = !DISubprogram(name: "NoRefQual", linkageName: "?NoRefQual@A@@QEAAHXZ", scope: !15, file: !1, line: 2, type: !18, isLocal: false, isDefinition: false, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false) +!18 = !DISubroutineType(types: !19) +!19 = !{!20, !21} +!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!22 = !DISubprogram(name: "RefQual", linkageName: "?RefQual@A@@QEGAAHXZ", scope: !15, file: !1, line: 4, type: !23, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPrototyped | DIFlagLValueReference, isOptimized: false) +!23 = !DISubroutineType(flags: DIFlagLValueReference, types: !19) +!24 = !DISubprogram(name: "RefQual", linkageName: "?RefQual@A@@QEHAAHXZ", scope: !15, file: !1, line: 5, type: !25, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPrototyped | DIFlagRValueReference, isOptimized: false) +!25 = !DISubroutineType(flags: DIFlagRValueReference, types: !19) +!26 = !DISubprogram(name: "LValueRef", linkageName: "?LValueRef@A@@QEGAAHXZ", scope: !15, file: !1, line: 7, type: !23, isLocal: false, isDefinition: false, scopeLine: 7, flags: DIFlagPrototyped | DIFlagLValueReference, isOptimized: false) +!27 = !DISubprogram(name: "RValueRef", linkageName: "?RValueRef@A@@QEHAAHXZ", scope: !15, file: !1, line: 9, type: !25, isLocal: false, isDefinition: false, scopeLine: 9, flags: DIFlagPrototyped | DIFlagRValueReference, isOptimized: false) +!28 = !DILocation(line: 13, scope: !10) +!29 = !DILocalVariable(name: "a", scope: !10, file: !1, line: 14, type: !15) +!30 = !DILocation(line: 14, scope: !10) +!31 = !DILocation(line: 15, scope: !10) + + + + +; CHECK: CodeViewTypes [ +; CHECK: Section: .debug$T (7) +; CHECK: Magic: 0x4 +; CHECK: ] Index: llvm/test/DebugInfo/COFF/types-non-virtual-methods.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-non-virtual-methods.ll +++ llvm/test/DebugInfo/COFF/types-non-virtual-methods.ll @@ -64,7 +64,6 @@ ; CHECK: Pointer (0x1004) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: A (0x1003) -; CHECK: PointerAttributes: 0x800A ; CHECK: PtrType: Near32 (0xA) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 @@ -144,7 +143,6 @@ ; CHECK: Pointer (0x100B) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: B (0x100A) -; CHECK: PointerAttributes: 0x800A ; CHECK: PtrType: Near32 (0xA) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-ptr-to-member.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-ptr-to-member.ll +++ llvm/test/DebugInfo/COFF/types-ptr-to-member.ll @@ -27,7 +27,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x804C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -41,7 +40,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x804C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -55,7 +53,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x1004C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -69,7 +66,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int (0x74) -; CHECK: PointerAttributes: 0x1804C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -86,7 +82,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void A::() -; CHECK: PointerAttributes: 0x1006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 @@ -100,7 +95,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void C::() -; CHECK: PointerAttributes: 0x2006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 @@ -114,7 +108,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void D::() -; CHECK: PointerAttributes: 0x2006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 @@ -128,7 +121,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void E::() -; CHECK: PointerAttributes: 0x3006C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 @@ -144,7 +136,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: int -; CHECK: PointerAttributes: 0x4C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToDataMember (0x2) ; CHECK: IsFlat: 0 @@ -160,7 +151,6 @@ ; CHECK: Pointer ({{.*}}) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: void Incomplete::() -; CHECK: PointerAttributes: 0x6C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: PointerToMemberFunction (0x3) ; CHECK: IsFlat: 0 Index: llvm/test/DebugInfo/COFF/types-recursive-struct.ll =================================================================== --- llvm/test/DebugInfo/COFF/types-recursive-struct.ll +++ llvm/test/DebugInfo/COFF/types-recursive-struct.ll @@ -69,7 +69,6 @@ ; CHECK: Pointer (0x1005) { ; CHECK: TypeLeafKind: LF_POINTER (0x1002) ; CHECK: PointeeType: B (0x1004) -; CHECK: PointerAttributes: 0x1000C ; CHECK: PtrType: Near64 (0xC) ; CHECK: PtrMode: Pointer (0x0) ; CHECK: IsFlat: 0 Index: llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp =================================================================== --- llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp +++ llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp @@ -81,7 +81,16 @@ PUSH_FLAG(PointerOptions, Const, Options, "const"); PUSH_FLAG(PointerOptions, Unaligned, Options, "unaligned"); PUSH_FLAG(PointerOptions, Restrict, Options, "restrict"); - PUSH_FLAG(PointerOptions, WinRTSmartPointer, Options, "winrt"); + if (Opts.empty()) + return "None"; + return join(Opts, " | "); +} + +static std::string pointerQualifier(PointerQualifier Qualifier) { + std::vector Opts; + PUSH_FLAG(PointerQualifier, WinRTSmartPointer, Qualifier, "winrt"); + PUSH_FLAG(PointerQualifier, ThisPtrLValueRef, Qualifier, "&"); + PUSH_FLAG(PointerQualifier, ThisPtrRValueRef, Qualifier, "&&"); if (Opts.empty()) return "None"; return join(Opts, " | "); @@ -201,8 +210,10 @@ PointerMode Mode = Record.getMode(); PointerOptions Opts = Record.getOptions(); PointerKind Kind = Record.getPointerKind(); - return formatv("mode = {0}, opts = {1}, kind = {2}", formatPointerMode(Mode), - pointerOptions(Opts), pointerKind(Kind)); + PointerQualifier Qual = Record.getQualifier(); + return formatv("mode = {0}, opts = {1}, kind = {2}, qualifier = {3}", + formatPointerMode(Mode), pointerOptions(Opts), + pointerKind(Kind), pointerQualifier(Qual)); } static std::string formatFunctionOptions(FunctionOptions Options) {