mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Support the DW_AT_noreturn DWARF flag.
This is used to mark functions with the C++11 [[ noreturn ]] or C11 _Noreturn attributes. Patch by Victor Leschuk! https://reviews.llvm.org/D23167 llvm-svn: 278940
This commit is contained in:
parent
aa24d0013d
commit
5d182b6cce
@ -38,5 +38,6 @@ HANDLE_DI_FLAG((2 << 16), MultipleInheritance)
|
||||
HANDLE_DI_FLAG((3 << 16), VirtualInheritance)
|
||||
HANDLE_DI_FLAG((1 << 18), IntroducedVirtual)
|
||||
HANDLE_DI_FLAG((1 << 19), BitField)
|
||||
HANDLE_DI_FLAG((1 << 20), NoReturn)
|
||||
|
||||
#undef HANDLE_DI_FLAG
|
||||
|
@ -1419,6 +1419,13 @@ public:
|
||||
return getFlags() & FlagRValueReference;
|
||||
}
|
||||
|
||||
/// \brief Check if this is marked as noreturn.
|
||||
///
|
||||
/// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
|
||||
unsigned isNoReturn() const {
|
||||
return getFlags() & FlagNoReturn;
|
||||
}
|
||||
|
||||
DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
|
||||
|
||||
StringRef getName() const { return getStringOperand(2); }
|
||||
|
@ -197,6 +197,7 @@ enum Attribute : uint16_t {
|
||||
DW_AT_reference = 0x77,
|
||||
DW_AT_rvalue_reference = 0x78,
|
||||
DW_AT_macros = 0x79,
|
||||
DW_AT_noreturn = 0x87,
|
||||
|
||||
DW_AT_lo_user = 0x2000,
|
||||
DW_AT_hi_user = 0x3fff,
|
||||
|
@ -1248,6 +1248,9 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
|
||||
if (SP->isRValueReference())
|
||||
addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
|
||||
|
||||
if (SP->isNoReturn())
|
||||
addFlag(SPDie, dwarf::DW_AT_noreturn);
|
||||
|
||||
if (SP->isProtected())
|
||||
addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
|
||||
dwarf::DW_ACCESS_protected);
|
||||
|
@ -147,6 +147,7 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
|
||||
case DW_AT_dwo_name: return "DW_AT_dwo_name";
|
||||
case DW_AT_reference: return "DW_AT_reference";
|
||||
case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference";
|
||||
case DW_AT_noreturn: return "DW_AT_noreturn";
|
||||
case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
|
||||
case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
|
||||
case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
|
||||
|
@ -28,13 +28,13 @@ define void @_Z3foov() !dbg !9 {
|
||||
; CHECK: !9 = !DISubprogram(scope: null, isLocal: false, isDefinition: false, isOptimized: false)
|
||||
!9 = !DISubprogram(isDefinition: false)
|
||||
|
||||
; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, isLocal: true, isDefinition: true, scopeLine: 8, containingType: !4, virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !8, templateParams: !5, declaration: !9, variables: !6)
|
||||
; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, isLocal: true, isDefinition: true, scopeLine: 8, containingType: !4, virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, isOptimized: true, unit: !8, templateParams: !5, declaration: !9, variables: !6)
|
||||
!10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, isLocal: true,
|
||||
isDefinition: true, scopeLine: 8,
|
||||
containingType: !4,
|
||||
virtuality: DW_VIRTUALITY_pure_virtual,
|
||||
virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped,
|
||||
virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn,
|
||||
isOptimized: true, unit: !8, templateParams: !5,
|
||||
declaration: !9, variables: !6)
|
||||
|
||||
|
50
test/DebugInfo/noreturn_c11.ll
Normal file
50
test/DebugInfo/noreturn_c11.ll
Normal file
@ -0,0 +1,50 @@
|
||||
; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
||||
; REQUIRES: object-emission
|
||||
|
||||
; Generated by clang -S -c -std=c++11 --emit-llvm -g from the following C11 source:
|
||||
; _Noreturn void f() {
|
||||
; throw 1;
|
||||
; }
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}"f"
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_noreturn
|
||||
|
||||
; ModuleID = './test.c'
|
||||
source_filename = "./test.c"
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: noreturn
|
||||
define void @f() #0 !dbg !6 {
|
||||
entry:
|
||||
call void @exit(i32 0) #2, !dbg !10
|
||||
unreachable, !dbg !10
|
||||
|
||||
return: ; No predecessors!
|
||||
ret void, !dbg !11
|
||||
}
|
||||
|
||||
; Function Attrs: noreturn
|
||||
declare void @exit(i32) #1
|
||||
|
||||
attributes #0 = { noreturn }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
!llvm.ident = !{!5}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
||||
!1 = !DIFile(filename: "test.c", directory: "/home/del/test")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"}
|
||||
!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2)
|
||||
!7 = !DIFile(filename: "./test.c", directory: "/home/del/test")
|
||||
!8 = !DISubroutineType(types: !9)
|
||||
!9 = !{null}
|
||||
!10 = !DILocation(line: 5, column: 3, scope: !6)
|
||||
!11 = !DILocation(line: 6, column: 1, scope: !6)
|
57
test/DebugInfo/noreturn_cpp11.ll
Normal file
57
test/DebugInfo/noreturn_cpp11.ll
Normal file
@ -0,0 +1,57 @@
|
||||
; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
||||
; REQUIRES: object-emission
|
||||
|
||||
; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source:
|
||||
; [[ noreturn ]] void f() {
|
||||
; throw 1;
|
||||
; }
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}"f"
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_noreturn
|
||||
|
||||
; ModuleID = 'test.cpp'
|
||||
source_filename = "test.cpp"
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@_ZTIi = external constant i8*
|
||||
|
||||
; Function Attrs: noreturn
|
||||
define void @_Z1fv() #0 !dbg !6 {
|
||||
entry:
|
||||
%exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9
|
||||
%0 = bitcast i8* %exception to i32*, !dbg !9
|
||||
store i32 1, i32* %0, align 16, !dbg !9
|
||||
call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10
|
||||
unreachable, !dbg !9
|
||||
|
||||
return: ; No predecessors!
|
||||
ret void, !dbg !12
|
||||
}
|
||||
|
||||
declare i8* @__cxa_allocate_exception(i64)
|
||||
|
||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
||||
|
||||
attributes #0 = { noreturn }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
!llvm.ident = !{!5}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "/home/del/test")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"}
|
||||
!6 = distinct !DISubprogram(name: "f", linkageName: "_Z1fv", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped | DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2)
|
||||
!7 = !DISubroutineType(types: !8)
|
||||
!8 = !{null}
|
||||
!9 = !DILocation(line: 2, column: 5, scope: !6)
|
||||
!10 = !DILocation(line: 2, column: 5, scope: !11)
|
||||
!11 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 1)
|
||||
!12 = !DILocation(line: 3, column: 1, scope: !6)
|
52
test/DebugInfo/noreturn_objc.ll
Normal file
52
test/DebugInfo/noreturn_objc.ll
Normal file
@ -0,0 +1,52 @@
|
||||
; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
||||
; REQUIRES: object-emission
|
||||
|
||||
; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source:
|
||||
; #include <stdlib.h>
|
||||
; __attribute__ ((noreturn)) void f()
|
||||
; {
|
||||
; exit(0);
|
||||
; }
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}"f"
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_noreturn
|
||||
|
||||
; ModuleID = './test.m'
|
||||
source_filename = "./test.m"
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: noreturn
|
||||
define void @f() #0 !dbg !6 {
|
||||
entry:
|
||||
call void @exit(i32 0) #2, !dbg !10
|
||||
unreachable, !dbg !10
|
||||
|
||||
return: ; No predecessors!
|
||||
ret void, !dbg !11
|
||||
}
|
||||
|
||||
; Function Attrs: noreturn
|
||||
declare void @exit(i32) #1
|
||||
|
||||
attributes #0 = { noreturn }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
!llvm.ident = !{!5}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2)
|
||||
!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"}
|
||||
!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2)
|
||||
!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc")
|
||||
!8 = !DISubroutineType(types: !9)
|
||||
!9 = !{null}
|
||||
!10 = !DILocation(line: 4, column: 3, scope: !6)
|
||||
!11 = !DILocation(line: 5, column: 1, scope: !6)
|
@ -73,8 +73,9 @@ TEST(DINodeTest, splitFlags) {
|
||||
CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u);
|
||||
unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector};
|
||||
CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u);
|
||||
CHECK_SPLIT(0x100000u, {}, 0x100000u);
|
||||
CHECK_SPLIT(0x100000u | DINode::FlagVector, {DINode::FlagVector}, 0x100000u);
|
||||
CHECK_SPLIT(0x200000u, {}, 0x200000u);
|
||||
CHECK_SPLIT(0x200000u | DINode::FlagVector, {DINode::FlagVector}, 0x200000u);
|
||||
CHECK_SPLIT(0x200000u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x200000u);
|
||||
#undef CHECK_SPLIT
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user