Debug info: Implement (rvalue) reference qualifiers for C++11 non-static

member functions. Paired commit with CFE.

rdar://problem/15356637

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197613 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl 2013-12-18 21:48:19 +00:00
parent f5d3392e50
commit 5112542840
6 changed files with 170 additions and 19 deletions

View File

@ -415,10 +415,13 @@ namespace llvm {
StringRef UniqueIdentifier = StringRef());
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
/// @param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes);
/// @param File File in which this subroutine is defined.
/// @param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
/// @param Flags E.g.: LValueReference.
/// These flags are used to emit dwarf attributes.
DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes,
unsigned Flags = 0);
/// createArtificialType - Create a new DIType with "artificial" flag set.
DIType createArtificialType(DIType Ty);

View File

@ -64,20 +64,22 @@ class DIDescriptor {
public:
enum {
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5,
FlagArtificial = 1 << 6,
FlagExplicit = 1 << 7,
FlagPrototyped = 1 << 8,
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5,
FlagArtificial = 1 << 6,
FlagExplicit = 1 << 7,
FlagPrototyped = 1 << 8,
FlagObjcClassComplete = 1 << 9,
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
FlagStaticMember = 1 << 12,
FlagIndirectVariable = 1 << 13
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
FlagStaticMember = 1 << 12,
FlagIndirectVariable = 1 << 13,
FlagLValueReference = 1 << 14,
FlagRValueReference = 1 << 15
};
protected:
@ -313,6 +315,12 @@ public:
}
bool isVector() const { return (getFlags() & FlagVector) != 0; }
bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
bool isLValueReference() const {
return (getFlags() & FlagLValueReference) != 0;
}
bool isRValueReference() const {
return (getFlags() & FlagRValueReference) != 0;
}
bool isValid() const { return DbgNode && isType(); }
/// replaceAllUsesWith - Replace all uses of debug info referenced by
@ -470,6 +478,19 @@ public:
return (getUnsignedField(13) & FlagPrototyped) != 0;
}
/// Return true if this subprogram is a C++11 reference-qualified
/// non-static member function (void foo() &).
unsigned isLValueReference() const {
return (getUnsignedField(13) & FlagLValueReference) != 0;
}
/// Return true if this subprogram is a C++11
/// rvalue-reference-qualified non-static member function
/// (void foo() &&).
unsigned isRValueReference() const {
return (getUnsignedField(13) & FlagRValueReference) != 0;
}
unsigned isOptimized() const;
/// Verify - Verify that a subprogram descriptor is well formed.

View File

@ -1218,6 +1218,12 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
(Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
Language == dwarf::DW_LANG_ObjC))
addFlag(&Buffer, dwarf::DW_AT_prototyped);
if (CTy.isLValueReference())
addFlag(&Buffer, dwarf::DW_AT_reference);
if (CTy.isRValueReference())
addFlag(&Buffer, dwarf::DW_AT_rvalue_reference);
} break;
case dwarf::DW_TAG_structure_type:
case dwarf::DW_TAG_union_type:
@ -1520,6 +1526,12 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
}
if (SP.isLValueReference())
addFlag(SPDie, dwarf::DW_AT_reference);
if (SP.isRValueReference())
addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
return SPDie;
}

View File

@ -706,7 +706,8 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
/// createSubroutineType - Create subroutine type.
DICompositeType DIBuilder::createSubroutineType(DIFile File,
DIArray ParameterTypes) {
DIArray ParameterTypes,
unsigned Flags) {
// TAG_subroutine_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type),
@ -717,7 +718,7 @@ DICompositeType DIBuilder::createSubroutineType(DIFile File,
ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size
ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align
ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags
ConstantInt::get(Type::getInt32Ty(VMContext), Flags), // Flags
NULL,
ParameterTypes,
ConstantInt::get(Type::getInt32Ty(VMContext), 0),

View File

@ -504,6 +504,10 @@ bool DICompositeType::Verify() const {
if (!fieldIsMDString(DbgNode, 14))
return false;
// A subroutine type can't be both & and &&.
if (isLValueReference() && isRValueReference())
return false;
return DbgNode->getNumOperands() == 15;
}
@ -520,6 +524,11 @@ bool DISubprogram::Verify() const {
// Containing type @ field 12.
if (!fieldIsTypeRef(DbgNode, 12))
return false;
// A subprogram can't be both & and &&.
if (isLValueReference() && isRValueReference())
return false;
return DbgNode->getNumOperands() == 20;
}
@ -1297,6 +1306,12 @@ void DIType::printInternal(raw_ostream &OS) const {
OS << " [vector]";
if (isStaticMember())
OS << " [static]";
if (isLValueReference())
OS << " [reference]";
if (isRValueReference())
OS << " [rvalue reference]";
}
void DIDerivedType::printInternal(raw_ostream &OS) const {
@ -1336,6 +1351,12 @@ void DISubprogram::printInternal(raw_ostream &OS) const {
else if (isProtected())
OS << " [protected]";
if (isLValueReference())
OS << " [reference]";
if (isRValueReference())
OS << " [rvalue reference]";
StringRef Res = getName();
if (!Res.empty())
OS << " [" << Res << ']';

View File

@ -0,0 +1,93 @@
; Test (r)value qualifiers on C++11 non-static member functions.
; Generated from tools/clang/test/CodeGenCXX/debug-info-qualifiers.cpp
;
; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s
; CHECK: DW_TAG_subroutine_type DW_CHILDREN_yes
; CHECK-NEXT: DW_AT_reference DW_FORM_flag_present
; CHECK: DW_TAG_subroutine_type DW_CHILDREN_yes
; CHECK-NEXT: DW_AT_rvalue_reference DW_FORM_flag_present
;
; CHECK: DW_TAG_subprogram
;
; CHECK: DW_TAG_subprogram
; CHECK-NOT: DW_TAG_subprogram
; CHECK: DW_AT_name {{.*}}"l"
; CHECK-NOT: DW_TAG_subprogram
; CHECK: DW_AT_reference [DW_FORM_flag_present] (true)
; CHECK: DW_TAG_subprogram
; CHECK-NOT: DW_TAG_subprogram
; CHECK: DW_AT_name {{.*}}"r"
; CHECK-NOT: DW_TAG_subprogram
; CHECK: DW_AT_rvalue_reference [DW_FORM_flag_present] (true)
target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin"
%class.A = type { i8 }
; Function Attrs: nounwind
define void @_Z1gv() #0 {
%a = alloca %class.A, align 1
%pl = alloca { i64, i64 }, align 8
%pr = alloca { i64, i64 }, align 8
call void @llvm.dbg.declare(metadata !{%class.A* %a}, metadata !24), !dbg !25
call void @llvm.dbg.declare(metadata !{{ i64, i64 }* %pl}, metadata !26), !dbg !31
store { i64, i64 } { i64 ptrtoint (void (%class.A*)* @_ZNKR1A1lEv to i64), i64 0 }, { i64, i64 }* %pl, align 8, !dbg !31
call void @llvm.dbg.declare(metadata !{{ i64, i64 }* %pr}, metadata !32), !dbg !35
store { i64, i64 } { i64 ptrtoint (void (%class.A*)* @_ZNKO1A1rEv to i64), i64 0 }, { i64, i64 }* %pr, align 8, !dbg !35
ret void, !dbg !36
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata) #1
declare void @_ZNKR1A1lEv(%class.A*)
declare void @_ZNKO1A1rEv(%class.A*)
attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!21, !22}
!llvm.ident = !{!23}
!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !16, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [] [DW_LANG_C_plus_plus]
!1 = metadata !{metadata !"", metadata !""}
!2 = metadata !{i32 0}
!3 = metadata !{metadata !4}
!4 = metadata !{i32 786434, metadata !5, null, metadata !"A", i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !6, i32 0, null, null, metadata !"_ZTS1A"} ; [ DW_TAG_class_type ] [A] [line 2, size 8, align 8, offset 0] [def] [from ]
!5 = metadata !{metadata !"debug-info-qualifiers.cpp", metadata !""}
!6 = metadata !{metadata !7, metadata !13}
!7 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"l", metadata !"l", metadata !"_ZNKR1A1lEv", i32 5, metadata !8, i1 false, i1 false, i32 0, i32 0, null, i32 16640, i1 false, null, null, i32 0, metadata !12, i32 5} ; [ DW_TAG_subprogram ] [line 5] [reference] [l]
!8 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 16384, null, metadata !9, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [reference] [from ]
!9 = metadata !{null, metadata !10}
!10 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !11} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from ]
!11 = metadata !{i32 786470, null, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, metadata !"_ZTS1A"} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from _ZTS1A]
!12 = metadata !{i32 786468}
!13 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"r", metadata !"r", metadata !"_ZNKO1A1rEv", i32 7, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i32 33024, i1 false, null, null, i32 0, metadata !15, i32 7} ; [ DW_TAG_subprogram ] [line 7] [rvalue reference] [r]
!14 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 32768, null, metadata !9, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [rvalue reference] [from ]
!15 = metadata !{i32 786468}
!16 = metadata !{metadata !17}
!17 = metadata !{i32 786478, metadata !5, metadata !18, metadata !"g", metadata !"g", metadata !"_Z1gv", i32 10, metadata !19, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void ()* @_Z1gv, null, null, metadata !2, i32 10} ; [ DW_TAG_subprogram ] [line 10] [def] [g]
!18 = metadata !{i32 786473, metadata !5} ; [ DW_TAG_file_type ]
!19 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !20, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!20 = metadata !{null}
!21 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
!22 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
!23 = metadata !{metadata !"clang version 3.5 "}
!24 = metadata !{i32 786688, metadata !17, metadata !"a", metadata !18, i32 11, metadata !4, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [line 11]
!25 = metadata !{i32 11, i32 0, metadata !17, null}
!26 = metadata !{i32 786688, metadata !17, metadata !"pl", metadata !18, i32 16, metadata !27, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [pl] [line 16]
!27 = metadata !{i32 786463, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !28, metadata !"_ZTS1A"} ; [ DW_TAG_ptr_to_member_type ] [line 0, size 0, align 0, offset 0] [from ]
!28 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 16384, null, metadata !29, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [reference] [from ]
!29 = metadata !{null, metadata !30}
!30 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A]
!31 = metadata !{i32 16, i32 0, metadata !17, null}
!32 = metadata !{i32 786688, metadata !17, metadata !"pr", metadata !18, i32 21, metadata !33, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [pr] [line 21]
!33 = metadata !{i32 786463, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !34, metadata !"_ZTS1A"} ; [ DW_TAG_ptr_to_member_type ] [line 0, size 0, align 0, offset 0] [from ]
!34 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 32768, null, metadata !29, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [rvalue reference] [from ]
!35 = metadata !{i32 21, i32 0, metadata !17, null}
!36 = metadata !{i32 22, i32 0, metadata !17, null}