aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-07-24 01:40:49 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-07-24 01:40:49 +0000
commit78d1a10e13a1abfd4830bccf2a97b2993da1ed5c (patch)
tree1cdf9d8bfd0887ab21721de66e769ddba67fb233
parentf50b6fe092091a700cee7a708d509ae7c49709f6 (diff)
Emit debug info for dynamic initializers. Permit __attribute__((nodebug)) on
variables that have static storage duration, it removes debug info on the emitted initializer function but not all debug info about this variable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160659 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp7
-rw-r--r--lib/Sema/SemaDeclAttr.cpp12
-rw-r--r--test/CodeGenCXX/debug-info-globalinit.cpp30
-rw-r--r--test/CodeGenCXX/debug-info-template-limit.cpp5
-rw-r--r--test/CodeGenCXX/debug-info-union.cpp8
-rw-r--r--test/CodeGenCXX/debug-lambda-expressions.cpp20
-rw-r--r--test/Sema/attr-nodebug.c7
8 files changed, 68 insertions, 24 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 18b63decee..5c3f1150c3 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1716,6 +1716,9 @@ def warn_pointer_attribute_wrong_type : Warning<
def warn_objc_object_attribute_wrong_type : Warning<
"'%0' only applies to Objective-C object or block pointer types; type here is %1">,
InGroup<IgnoredAttributes>;
+def warn_attribute_requires_functions_or_static_globals : Warning<
+ "%0 only applies to variables with static storage duration and functions">,
+ InGroup<IgnoredAttributes>;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">,
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 893628e08a..492b95ad15 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -321,9 +321,12 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
const VarDecl *D,
llvm::GlobalVariable *Addr,
bool PerformInit) {
- StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
+ if (CGM.getModuleDebugInfo() && !D->hasAttr<NoDebugAttr>())
+ DebugInfo = CGM.getModuleDebugInfo();
+
+ StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
getTypes().arrangeNullaryFunction(),
- FunctionArgList(), SourceLocation());
+ FunctionArgList(), D->getInit()->getExprLoc());
// Use guarded initialization if the global variable is weak. This
// occurs for, e.g., instantiated static data members and
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 717d131fe4..987a969f1f 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -3313,9 +3313,15 @@ static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
if (!checkAttributeNumArgs(S, Attr, 0))
return;
- if (!isFunctionOrMethod(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << ExpectedFunction;
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (!VD->hasGlobalStorage())
+ S.Diag(Attr.getLoc(),
+ diag::warn_attribute_requires_functions_or_static_globals)
+ << Attr.getName();
+ } else if (!isFunctionOrMethod(D)) {
+ S.Diag(Attr.getLoc(),
+ diag::warn_attribute_requires_functions_or_static_globals)
+ << Attr.getName();
return;
}
diff --git a/test/CodeGenCXX/debug-info-globalinit.cpp b/test/CodeGenCXX/debug-info-globalinit.cpp
new file mode 100644
index 0000000000..b8a23baba9
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-globalinit.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -std=c++11 -g | FileCheck %s
+
+void crash() {
+ volatile char *ptr = 0;
+ char x = *ptr;
+}
+
+int test() {
+ crash();
+ return 1;
+}
+
+static int i = test();
+__attribute__((nodebug)) static int j = test();
+
+int main(void) {}
+
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: %call = call i32 @_Z4testv(), !dbg ![[LINE:.*]]
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: store i32 %call, i32* @_ZL1i, align 4, !dbg
+//
+// CHECK: define internal void @__cxx_global_var_init1()
+// CHECK-NOT: dbg
+// CHECK: %call = call i32 @_Z4testv()
+// CHECK-NOT: dbg
+// CHECK: store i32 %call, i32* @_ZL1j, align 4
+//
+// CHECK: ![[LINE]] = metadata !{i32 13, i32 16
diff --git a/test/CodeGenCXX/debug-info-template-limit.cpp b/test/CodeGenCXX/debug-info-template-limit.cpp
index 796a80fd62..afad31b14e 100644
--- a/test/CodeGenCXX/debug-info-template-limit.cpp
+++ b/test/CodeGenCXX/debug-info-template-limit.cpp
@@ -1,8 +1,8 @@
// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s
// Check that this pointer type is TC<int>
-// CHECK: !10} ; [ DW_TAG_pointer_type
-// CHECK-NEXT: !10 ={{.*}}"TC<int>"
+// CHECK: ![[LINE:[0-9]+]]} ; [ DW_TAG_pointer_type ]{{.*}}[from TC<int>]
+// CHECK-NEXT: ![[LINE]] ={{.*}}"TC<int>"
template<typename T>
class TC {
@@ -12,4 +12,3 @@ public:
};
TC<int> tci;
-
diff --git a/test/CodeGenCXX/debug-info-union.cpp b/test/CodeGenCXX/debug-info-union.cpp
index e4e1abb261..588fa20336 100644
--- a/test/CodeGenCXX/debug-info-union.cpp
+++ b/test/CodeGenCXX/debug-info-union.cpp
@@ -10,7 +10,7 @@ union E {
E e;
-// CHECK: metadata !{i32 {{.*}}, null, metadata !"E", metadata !6, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_union_type ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !10, metadata !"bb", metadata !"bb", metadata !"_ZN1E2bbEv", metadata !6, i32 6, metadata !17, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !19, i32 6} ; [ DW_TAG_subprogram ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !10, metadata !"aa", metadata !"aa", metadata !"_ZN1E2aaEv", metadata !6, i32 7, metadata !22, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !24, i32 7} ; [ DW_TAG_subprogram ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !10, metadata !"E", metadata !"E", metadata !"", metadata !6, i32 8, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !27, i32 8} ; [ DW_TAG_subprogram ]
+// CHECK: metadata !{i32 {{.*}}, null, metadata !"E", metadata !{{.*}}, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !{{.*}}, i32 0, null} ; [ DW_TAG_union_type ]
+// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"bb", metadata !"bb", metadata !"_ZN1E2bbEv", metadata !{{.*}}, i32 6, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 6} ; [ DW_TAG_subprogram ]
+// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"aa", metadata !"aa", metadata !"_ZN1E2aaEv", metadata !{{.*}}, i32 7, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 7} ; [ DW_TAG_subprogram ]
+// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"E", metadata !"E", metadata !"", metadata !{{.*}}, i32 8, metadata !{{.*}}, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !{{.*}}, i32 8} ; [ DW_TAG_subprogram ]
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index ade2c5c233..aed3731e4a 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -14,22 +14,22 @@ struct D { D(); D(const D&); int x; };
int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
-// A: 5
-// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE:.*]], metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 [[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ]
-
// Randomness for file. -- 6
-// CHECK: [[FILE]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
+// CHECK: [[FILE:.*]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
+
+// A: 10
+// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 [[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ]
-// B: 12
+// B: 14
// CHECK: [[B_FUNC:.*]] = metadata !{i32 786478, i32 0, metadata [[FILE]], metadata !"b", metadata !"b", metadata !"_Z1bi", metadata [[FILE]], i32 [[B_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1bi, null, null, {{.*}} ; [ DW_TAG_subprogram ]
// C: 17
// CHECK: [[C_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"c", metadata !"c", metadata !"_Z1ci", metadata [[FILE]], i32 [[C_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1ci, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
-// D: 20
+// D: 18
// CHECK: [[D_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"d", metadata !"d", metadata !"_Z1di", metadata [[FILE]], i32 [[D_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1di, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
-// Back to D. -- 120
+// Back to D. -- 24
// CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]]}
// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 14, i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
@@ -37,7 +37,7 @@ int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
// CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// Back to C. -- 159
+// Back to C. -- 55
// CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata !"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]]}
// Ignoring the member type for now.
@@ -45,14 +45,14 @@ int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
// CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// Back to B. -- 179
+// Back to B. -- 67
// CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata !"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]]}
// CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata !"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ]
// CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
-// Back to A. -- 204
+// Back to A. -- 78
// CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata !"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]]}
// CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
diff --git a/test/Sema/attr-nodebug.c b/test/Sema/attr-nodebug.c
index a66e96168d..3cc4088e4b 100644
--- a/test/Sema/attr-nodebug.c
+++ b/test/Sema/attr-nodebug.c
@@ -1,8 +1,11 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
-int a __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only applies to functions}}
+int a __attribute__((nodebug));
+
+void b() {
+ int b __attribute__((nodebug)); // expected-warning {{'nodebug' only applies to variables with static storage duration and functions}}
+}
void t1() __attribute__((nodebug));
void t2() __attribute__((nodebug(2))); // expected-error {{attribute takes no arguments}}
-