]> granicus.if.org Git - clang/commitdiff
Allow 'nodebug' on local variables.
authorPaul Robinson <paul.robinson@sony.com>
Thu, 16 Jun 2016 00:42:36 +0000 (00:42 +0000)
committerPaul Robinson <paul.robinson@sony.com>
Thu, 16 Jun 2016 00:42:36 +0000 (00:42 +0000)
Parameters and non-static members of aggregates are still excluded,
and probably should remain that way.

Differential Revision: http://reviews.llvm.org/D19754

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272859 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
lib/CodeGen/CGDebugInfo.cpp
test/CodeGenCXX/debug-info-nodebug.cpp
test/CodeGenObjC/debug-info-nodebug.m [new file with mode: 0644]
test/Sema/attr-nodebug.c

index f483fc32341a964d99554b5d59f9ec936b31682f..fcf457a40cc9e699d3e7c2ee17a0c10aa5fcbcf5 100644 (file)
@@ -82,6 +82,8 @@ def NormalVar : SubsetSubject<Var,
                                 S->getKind() != Decl::ImplicitParam &&
                                 S->getKind() != Decl::ParmVar &&
                                 S->getKind() != Decl::NonTypeTemplateParm}]>;
+def NonParmVar : SubsetSubject<Var,
+                               [{S->getKind() != Decl::ParmVar}]>;
 def NonBitField : SubsetSubject<Field,
                                 [{!S->isBitField()}]>;
 
@@ -994,8 +996,8 @@ def NoCommon : InheritableAttr {
 
 def NoDebug : InheritableAttr {
   let Spellings = [GCC<"nodebug">];
-  let Subjects = SubjectList<[FunctionLike, ObjCMethod, GlobalVar], WarnDiag,
-                              "ExpectedFunctionGlobalVarMethodOrProperty">;
+  let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag,
+                              "ExpectedVariableOrFunction">;
   let Documentation = [NoDebugDocs];
 }
 
index 3f19772517ebfe42cf41c245d3972aed7d7bc1f2..dfaa2144f4cd0add5b998ca17f84aa54a32c5b37 100644 (file)
@@ -524,8 +524,8 @@ def NoDebugDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
 The ``nodebug`` attribute allows you to suppress debugging information for a
-function, or for a variable declared with static storage duration, such as
-globals, class static data members, and static locals.
+function or method, or for a variable that is not a parameter or a non-static
+data member.
   }];
 }
 
index e2000ea79aa7d261d2324263f7de81aa86f1ee04..0e756d348c45b93d55275ddaaaf6d5a1f2b31f90 100644 (file)
@@ -3019,6 +3019,8 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
                               CGBuilderTy &Builder) {
   assert(DebugKind >= codegenoptions::LimitedDebugInfo);
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
+  if (VD->hasAttr<NoDebugAttr>())
+    return;
 
   bool Unwritten =
       VD->isImplicit() || (isa<Decl>(VD->getDeclContext()) &&
@@ -3163,6 +3165,8 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
 
   if (Builder.GetInsertBlock() == nullptr)
     return;
+  if (VD->hasAttr<NoDebugAttr>())
+    return;
 
   bool isByRef = VD->hasAttr<BlocksAttr>();
 
index 7a10e6708cc313242aafdfa6bd0a9769bddf5be6..9f140efaed6fb85f4de5e6ca91f21e8413f2a28c 100644 (file)
@@ -44,9 +44,12 @@ void func3() {
 // YESINFO-DAG: !DIDerivedType({{.*}} name: "static_const_member"
 // NOINFO-NOT:  !DIDerivedType({{.*}} name: "static_const_member"
 
-// Function-local static variable.
+// Function-local static and auto variables.
 void func4() {
   NODEBUG static int static_local = 6;
+  NODEBUG        int normal_local = 7;
 }
 // YESINFO-DAG: !DIGlobalVariable(name: "static_local"
 // NOINFO-NOT:  !DIGlobalVariable(name: "static_local"
+// YESINFO-DAG: !DILocalVariable(name: "normal_local"
+// NOINFO-NOT:  !DILocalVariable(name: "normal_local"
diff --git a/test/CodeGenObjC/debug-info-nodebug.m b/test/CodeGenObjC/debug-info-nodebug.m
new file mode 100644 (file)
index 0000000..42d630b
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arm-apple-ios -emit-llvm -debug-info-kind=limited -fblocks  %s -o - | FileCheck %s
+// Objective-C code cargo-culted from debug-info-lifetime-crash.m.
+@protocol NSObject
+- (id)copy;
+@end
+@class W;
+@interface View1
+@end
+@implementation Controller {
+    void (^Block)(void);
+}
+- (void)View:(View1 *)View foo:(W *)W
+{
+  // The reference from inside the block implicitly creates another
+  // local variable for the referenced member. That is what gets
+  // suppressed by the attribute.  It still gets debug info as a
+  // member, though.
+  // CHECK-NOT: !DILocalVariable(name: "weakSelf"
+  // CHECK:     !DIDerivedType({{.*}} name: "weakSelf"
+  // CHECK-NOT: !DILocalVariable(name: "weakSelf"
+  __attribute__((nodebug)) __typeof(self) weakSelf = self;
+  Block = [^{
+    __typeof(self) strongSelf = weakSelf;
+    } copy];
+}
+@end
index 39643bfb70d95049a9906931709d48dc22ad9e26..e7ca58d3ba15ad82c78e5c192cfd5ccb29ec2724 100644 (file)
@@ -2,8 +2,8 @@
 
 int a __attribute__((nodebug));
 
-void b() {
-  int b __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only applies to functions and global variables}}
+void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to variables and functions}}
+  int b __attribute__((nodebug));
 }
 
 void t1() __attribute__((nodebug));