]> granicus.if.org Git - clang/commitdiff
Emit debug info for dynamic initializers. Permit __attribute__((nodebug)) on
authorNick Lewycky <nicholas@mxc.ca>
Tue, 24 Jul 2012 01:40:49 +0000 (01:40 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Tue, 24 Jul 2012 01:40:49 +0000 (01:40 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/CodeGen/CGDeclCXX.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGenCXX/debug-info-globalinit.cpp [new file with mode: 0644]
test/CodeGenCXX/debug-info-template-limit.cpp
test/CodeGenCXX/debug-info-union.cpp
test/CodeGenCXX/debug-lambda-expressions.cpp
test/Sema/attr-nodebug.c

index 18b63decee6fbd666235c7d39452af9eee9b076c..5c3f1150c36a3670a417e614739867aed27fbefb 100644 (file)
@@ -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">,
index 893628e08a87008458870800ebe01dfa2f43771f..492b95ad155b45a4674b11e50ac683c2fd4d67a5 100644 (file)
@@ -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
index 717d131fe45a1ff6d4b2a5acb12ead583d283268..987a969f1f30cdca076d9ce4728f26752495ae55 100644 (file)
@@ -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 (file)
index 0000000..b8a23ba
--- /dev/null
@@ -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
index 796a80fd627f5d70c826fddbcaf5378157636c04..afad31b14efa83e811cfd257f6002dac3447cba1 100644 (file)
@@ -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;
-
index e4e1abb26161e7e1fdf627e32dd02a3e1a3cb84b..588fa203367be7376eebca6cbd00847fcb4003a1 100644 (file)
@@ -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 ]
index ade2c5c23397793d8a0556454492e2d04ee1d395..aed3731e4a0c1f6d90719d78b6138c42a7cf82c0 100644 (file)
@@ -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 ]
index a66e96168dd6088b9783137a99ab2e14e8721b2a..3cc4088e4b3cf6fa6aa10864aecb09779e757eee 100644 (file)
@@ -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}}
-