summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f5d3392)
raw | patch | inline | side by side (parent: f5d3392)
author | Adrian Prantl <aprantl@apple.com> | |
Wed, 18 Dec 2013 21:48:19 +0000 (21:48 +0000) | ||
committer | Adrian Prantl <aprantl@apple.com> | |
Wed, 18 Dec 2013 21:48:19 +0000 (21:48 +0000) |
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
rdar://problem/15356637
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197613 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/DIBuilder.h | patch | blob | history | |
include/llvm/DebugInfo.h | patch | blob | history | |
lib/CodeGen/AsmPrinter/DwarfUnit.cpp | patch | blob | history | |
lib/IR/DIBuilder.cpp | patch | blob | history | |
lib/IR/DebugInfo.cpp | patch | blob | history | |
test/DebugInfo/debug-info-qualifiers.ll | [new file with mode: 0644] | patch | blob |
index 924aab586fbe3bad989a51d3d3651101233bc98b..44f40819c71900436646d96da5f7fdfffdb1c8c4 100644 (file)
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
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);
index 768cf4ea10f22fa2c186ccf50c19e21d3b73a0e0..0a56e2f47d9201f0f34bfe3da4779d4129bd133f 100644 (file)
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
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:
}
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
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.
index 85a76287434ea3cf7bda955162016e2b16b300b1..69240f870f9e581661b7d18f8da9614d7005e5e9 100644 (file)
(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:
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;
}
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index c4a9f4113060bbbf63184da9694d83104766a3e2..c7e75849005f716f03ef0a557869d28b3eaf5695 100644 (file)
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
/// 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),
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),
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 75a70965a3a11ff071799433c1074121fff1d9cb..ba45e828636f87d5de6b6d49bb9a62ca48b90e4a 100644 (file)
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
if (!fieldIsMDString(DbgNode, 14))
return false;
+ // A subroutine type can't be both & and &&.
+ if (isLValueReference() && isRValueReference())
+ return false;
+
return DbgNode->getNumOperands() == 15;
}
// 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;
}
OS << " [vector]";
if (isStaticMember())
OS << " [static]";
+
+ if (isLValueReference())
+ OS << " [reference]";
+
+ if (isRValueReference())
+ OS << " [rvalue reference]";
}
void DIDerivedType::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 << ']';
diff --git a/test/DebugInfo/debug-info-qualifiers.ll b/test/DebugInfo/debug-info-qualifiers.ll
--- /dev/null
@@ -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}