]> granicus.if.org Git - clang/commitdiff
* Attempt to un-break gdb buildbot by emitting a lexical block end only
authorAdrian Prantl <aprantl@apple.com>
Mon, 1 Apr 2013 19:02:06 +0000 (19:02 +0000)
committerAdrian Prantl <aprantl@apple.com>
Mon, 1 Apr 2013 19:02:06 +0000 (19:02 +0000)
  when we actually end a lexical block.
* Added new test for line table / block cleanup.
* Follow-up to r177819 / rdar://problem/13115369

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

lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/cp-blocks-linetables.cpp [new file with mode: 0644]

index e40a731825beb167a0d2a8502a96811b00625d7c..f76022fb97d8f4d56726b3fe60d91d428d71ed72 100644 (file)
@@ -881,6 +881,9 @@ public:
     /// \brief Exit this cleanup scope, emitting any accumulated
     /// cleanups.
     ~LexicalScope() {
+      if (CGDebugInfo *DI = CGF.getDebugInfo())
+        DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
+
       // If we should perform a cleanup, force them now.  Note that
       // this ends the cleanup scope before rescoping any labels.
       if (PerformCleanup) ForceCleanup();
@@ -889,15 +892,9 @@ public:
     /// \brief Force the emission of cleanups now, instead of waiting
     /// until this object is destroyed.
     void ForceCleanup() {
+      CGF.CurLexicalScope = ParentScope;
       RunCleanupsScope::ForceCleanup();
-      endLexicalScope();
-    }
 
-  private:
-    void endLexicalScope() {
-      CGF.CurLexicalScope = ParentScope;
-      if (CGDebugInfo *DI = CGF.getDebugInfo())
-        DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
       if (!Labels.empty())
         rescopeLabels();
     }
diff --git a/test/CodeGenCXX/cp-blocks-linetables.cpp b/test/CodeGenCXX/cp-blocks-linetables.cpp
new file mode 100644 (file)
index 0000000..d5dd46c
--- /dev/null
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s
+// Ensure that we generate a line table entry for the block cleanup.
+// CHECK: define {{.*}} @__main_block_invoke
+// CHECK: _NSConcreteStackBlock
+// CHECK: = bitcast {{.*}}, !dbg ![[L1:[0-9]+]]
+// CHECK-NOT:  call {{.*}} @_Block_object_dispose{{.*}}, !dbg ![[L1]]
+// CHECK: ret
+
+void * _NSConcreteStackBlock;
+#ifdef __cplusplus
+extern "C" void exit(int);
+#else
+extern void exit(int);
+#endif
+
+enum numbers {
+  zero, one, two, three, four
+};
+
+typedef enum numbers (^myblock)(enum numbers);
+
+
+double test(myblock I) {
+  return I(three);
+}
+
+int main() {
+  __block enum numbers x = one;
+  __block enum numbers y = two;
+
+  /* Breakpoint for first Block function.  */
+  myblock CL = ^(enum numbers z)
+    { enum numbers savex = x;
+      { __block enum numbers x = savex;
+       y = z;
+       if (y != three)
+         exit (6);
+       test (
+             /* Breakpoint for second Block function.  */
+             ^ (enum numbers z) {
+               if (y != three) {
+                 exit(1);
+               }
+               if (x != one)
+                 exit(2);
+               x = z;
+               if (x != three)
+                 exit(3);
+               if (y != three)
+                 exit(4);
+               return (enum numbers) four;
+             });}
+      return x;
+    };
+
+  enum numbers res = (enum numbers)test(CL);
+
+  if (res != one)
+    exit (5);
+  return 0;
+}