1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +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:
Adrian Prantl 2016-08-17 16:02:43 +00:00
parent aa24d0013d
commit 5d182b6cce
10 changed files with 177 additions and 4 deletions

View File

@ -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

View File

@ -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); }

View File

@ -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,

View File

@ -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);

View File

@ -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";

View File

@ -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)

View 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)

View 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)

View 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)

View File

@ -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
}