Skip to content

Commit

Permalink
PR14759: Debug info support for C++ member pointers.
Browse files Browse the repository at this point in the history
This works fine with GDB for member variable pointers, but GDB's support for
member function pointers seems to be quite unrelated to
DW_TAG_ptr_to_member_type. (see GDB bug 14998 for details)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171698 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dwblaikie committed Jan 7, 2013
1 parent 71ab7a7 commit 62fdfb5
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/llvm/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ namespace llvm {
uint64_t AlignInBits = 0,
StringRef Name = StringRef());

/// \brief Create debugging information entry for a pointer to member.
/// @param PointeeTy Type pointed to by this pointer.
/// @param Class Type for which this pointer points to members of.
DIType createMemberPointerType(DIType PointeeTy, DIType Class);

/// createReferenceType - Create debugging information entry for a c++
/// style reference or rvalue reference type.
DIType createReferenceType(unsigned Tag, DIType RTy);
Expand Down
5 changes: 5 additions & 0 deletions include/llvm/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ namespace llvm {
/// associated with one.
MDNode *getObjCProperty() const;

DIType getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
return getFieldAs<DIType>(10);
}

StringRef getObjCPropertyName() const {
if (getVersion() > LLVMDebugVersion11)
return StringRef();
Expand Down
3 changes: 3 additions & 0 deletions lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
if (Size && Tag != dwarf::DW_TAG_pointer_type)
addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);

if (Tag == dwarf::DW_TAG_ptr_to_member_type)
addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
getOrCreateTypeDIE(DTy.getClassType()));
// Add source line info if available and TyDesc is not a forward declaration.
if (!DTy.isForwardDecl())
addSourceLine(&Buffer, DTy);
Expand Down
18 changes: 18 additions & 0 deletions lib/IR/DIBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,24 @@ DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits,
return DIType(MDNode::get(VMContext, Elts));
}

DIType DIBuilder::createMemberPointerType(DIType PointeeTy, DIType Base) {
// Pointer types are encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_ptr_to_member_type),
NULL, //TheCU,
NULL,
NULL, // Filename
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
ConstantInt::get(Type::getInt64Ty(VMContext), 0),
ConstantInt::get(Type::getInt64Ty(VMContext), 0),
ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
PointeeTy,
Base
};
return DIType(MDNode::get(VMContext, Elts));
}

/// createReferenceType - Create debugging information entry for a reference
/// type.
DIType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) {
Expand Down
2 changes: 2 additions & 0 deletions lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ bool DIDescriptor::isDerivedType() const {
switch (getTag()) {
case dwarf::DW_TAG_typedef:
case dwarf::DW_TAG_pointer_type:
case dwarf::DW_TAG_ptr_to_member_type:
case dwarf::DW_TAG_reference_type:
case dwarf::DW_TAG_rvalue_reference_type:
case dwarf::DW_TAG_const_type:
Expand Down Expand Up @@ -423,6 +424,7 @@ bool DIType::Verify() const {
unsigned Tag = getTag();
if (!isBasicType() && Tag != dwarf::DW_TAG_const_type &&
Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type &&
Tag != dwarf::DW_TAG_ptr_to_member_type &&
Tag != dwarf::DW_TAG_reference_type &&
Tag != dwarf::DW_TAG_rvalue_reference_type &&
Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type &&
Expand Down
34 changes: 34 additions & 0 deletions test/DebugInfo/member-pointers.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; RUN: llc -filetype=obj -O0 < %s > %t
; RUN: llvm-dwarfdump %t | FileCheck %s
; CHECK: DW_TAG_ptr_to_member_type
; CHECK: DW_TAG_ptr_to_member_type
; IR generated from clang -g with the following source:
; struct S {
; };
;
; int S::*x = 0;
; void (S::*y)(int) = 0;

; ModuleID = 'simple.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@x = global i64 -1, align 8
@y = global { i64, i64 } zeroinitializer, align 8

!llvm.dbg.cu = !{!0}

!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"simple.cpp", metadata !"/home/blaikie/Development/scratch", metadata !"clang version 3.3 ", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !1, metadata !3} ; [ DW_TAG_compile_unit ] [/home/blaikie/Development/scratch/simple.cpp] [DW_LANG_C_plus_plus]
!1 = metadata !{metadata !2}
!2 = metadata !{i32 0}
!3 = metadata !{metadata !4}
!4 = metadata !{metadata !5, metadata !10}
!5 = metadata !{i32 786484, i32 0, null, metadata !"x", metadata !"x", metadata !"", metadata !6, i32 2, metadata !7, i32 0, i32 1, i64* @x} ; [ DW_TAG_variable ] [x] [line 2] [def]
!6 = metadata !{i32 786473, metadata !"simple.cpp", metadata !"/home/blaikie/Development/scratch", null} ; [ DW_TAG_file_type ]
!7 = metadata !{i32 786463, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !8, metadata !9} ; [ DW_TAG_ptr_to_member_type ] [line 0, size 0, align 0, offset 0] [from int]
!8 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
!9 = metadata !{i32 786451, null, metadata !"S", metadata !6, i32 1, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null} ; [ DW_TAG_structure_type ] [S] [line 1, size 8, align 8, offset 0] [from ]
!10 = metadata !{i32 786484, i32 0, null, metadata !"y", metadata !"y", metadata !"", metadata !6, i32 3, metadata !11, i32 0, i32 1, { i64, i64 }* @y} ; [ DW_TAG_variable ] [y] [line 3] [def]
!11 = metadata !{i32 786463, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !12, metadata !9} ; [ DW_TAG_ptr_to_member_type ] [line 0, size 0, align 0, offset 0] [from ]
!12 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !13, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!13 = metadata !{null, metadata !8}

0 comments on commit 62fdfb5

Please sign in to comment.