]> granicus.if.org Git - clang/commitdiff
PR14566: Debug Info: avoid top level lexical blocks in functions
authorDavid Blaikie <dblaikie@gmail.com>
Sat, 26 Jan 2013 22:16:26 +0000 (22:16 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Sat, 26 Jan 2013 22:16:26 +0000 (22:16 +0000)
One of the gotchas (see changes to CodeGenFunction) was due to the fix in
r139416 (for PR10829). This only worked previously because the top level
lexical block would set the location to the end of the function, the debug
location would be updated (as per r139416), the location would be set to
the end of the function again (but that would no-op, since it was the same
as the previous location), then the return instruction would be emitted using
the debug location.

Once the top level lexical block was no longer emitted, the end-of-function
location change was causing the debug loc to be updated, regressing that bug.

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

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/2010-02-16-DbgScopes.c
test/CodeGen/2010-03-5-LexicalScope.c
test/CodeGen/debug-info-line.c
test/CodeGen/debug-info-scope.c
test/CodeGenObjC/catch-lexical-block.m

index ec88d8727ce875ced1e0ab9f1971dfc5fd4da1cc..ca810e7cf54aca5ad19f4e628507d6f9ed3d81fc 100644 (file)
@@ -79,7 +79,7 @@ void CGDebugInfo::setLocation(SourceLocation Loc) {
     llvm::MDNode *N = D;
     LexicalBlockStack.pop_back();
     LexicalBlockStack.push_back(N);
-  } else if (Scope.isLexicalBlock()) {
+  } else if (Scope.isLexicalBlock() || Scope.isSubprogram()) {
     llvm::DIDescriptor D
       = DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurLoc));
     llvm::MDNode *N = D;
index ea4c08fac3a34b95f14efdef58e6d5e608b5ee5d..a293f1d2e70046c4a0bbd5021c214d21e46d426b 100644 (file)
@@ -198,6 +198,12 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
   // Keep track of the current cleanup stack depth, including debug scopes.
   LexicalScope Scope(*this, S.getSourceRange());
 
+  return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot);
+}
+
+RValue CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast,
+                                         AggValueSlot AggSlot) {
+
   for (CompoundStmt::const_body_iterator I = S.body_begin(),
        E = S.body_end()-GetLast; I != E; ++I)
     EmitStmt(*I);
index 1fdcc6f9ecda09f05c28599bfc2f855111b3124b..59e38e63d51d0a8d0f71e8a94eec54227349ebbc 100644 (file)
@@ -117,7 +117,7 @@ bool CodeGenFunction::hasAggregateLLVMType(QualType type) {
   llvm_unreachable("unknown type kind!");
 }
 
-void CodeGenFunction::EmitReturnBlock() {
+bool CodeGenFunction::EmitReturnBlock() {
   // For cleanliness, we try to avoid emitting the return block for
   // simple cases.
   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
@@ -132,7 +132,7 @@ void CodeGenFunction::EmitReturnBlock() {
       delete ReturnBlock.getBlock();
     } else
       EmitBlock(ReturnBlock.getBlock());
-    return;
+    return false;
   }
 
   // Otherwise, if the return block is the target of a single direct
@@ -148,7 +148,7 @@ void CodeGenFunction::EmitReturnBlock() {
       Builder.SetInsertPoint(BI->getParent());
       BI->eraseFromParent();
       delete ReturnBlock.getBlock();
-      return;
+      return true;
     }
   }
 
@@ -157,6 +157,7 @@ void CodeGenFunction::EmitReturnBlock() {
   // region.end for now.
 
   EmitBlock(ReturnBlock.getBlock());
+  return false;
 }
 
 static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
@@ -178,14 +179,14 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
     PopCleanupBlocks(PrologueCleanupDepth);
 
   // Emit function epilog (to return).
-  EmitReturnBlock();
+  bool MoveEndLoc = EmitReturnBlock();
 
   if (ShouldInstrumentFunction())
     EmitFunctionInstrumentation("__cyg_profile_func_exit");
 
   // Emit debug descriptor for function end.
   if (CGDebugInfo *DI = getDebugInfo()) {
-    DI->setLocation(EndLoc);
+    if (!MoveEndLoc) DI->setLocation(EndLoc);
     DI->EmitFunctionEnd(Builder);
   }
 
@@ -486,7 +487,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
 void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
   const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
   assert(FD->getBody());
-  EmitStmt(FD->getBody());
+  if (const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody()))
+    EmitCompoundStmtWithoutScope(*S);
+  else
+    EmitStmt(FD->getBody());
 }
 
 /// Tries to mark the given function nounwind based on the
index bfcc77a3fdb56473e050d8bbacdad54a616cb334..6f06b3bc261e9aeae22d7b5a656ea64e2e738bdd 100644 (file)
@@ -1411,7 +1411,7 @@ public:
 
   /// EmitReturnBlock - Emit the unified return block, trying to avoid its
   /// emission when possible.
-  void EmitReturnBlock();
+  bool EmitReturnBlock();
 
   /// FinishFunction - Complete IR generation of the current function. It is
   /// legal to call this function even if there is no current insertion point.
@@ -2013,6 +2013,9 @@ public:
 
   RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
                           AggValueSlot AVS = AggValueSlot::ignored());
+  RValue EmitCompoundStmtWithoutScope(const CompoundStmt &S,
+                                      bool GetLast = false, AggValueSlot AVS =
+                                          AggValueSlot::ignored());
 
   /// EmitLabel - Emit the block for the given label. It is legal to call this
   /// function even if there is no current insertion point.
index 58bda9a2d7cf81a7c004611b8a606e697cd072e0..36484a4c6372fd0ce94409768f4a7d1f73527ebc 100644 (file)
@@ -4,7 +4,6 @@
 // CHECK: DW_TAG_lexical_block
 // CHECK: DW_TAG_lexical_block
 // CHECK: DW_TAG_lexical_block
-// CHECK: DW_TAG_lexical_block
 
 extern int bar();
 extern void foobar();
index 511372d1583bba110e6f9c87c91494b163776bc7..e0e41dd2379bb5af08f5f97a3ce61f43f508467f 100644 (file)
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm -O0 -g %s -o - | FileCheck %s
 // CHECK: DW_TAG_lexical_block
 // CHECK: DW_TAG_lexical_block
-// CHECK: DW_TAG_lexical_block
 int foo(int i) {
        if (i) {
                int j = 2;
index 9e6e9714aa4742b459fcb281fe713d3062d1f82a..8f869d04f0526552f6967f312d0cb3cc19b9ea22 100644 (file)
@@ -1,9 +1,8 @@
 // RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s
 
 // Radar 8396182
-// There is only one lexical block, but we need a DILexicalBlock and two
-// DILexicalBlockFile to correctly represent file info. This means we have
-// two lexical blocks shown as the latter is also tagged as a lexical block.
+// There are no lexical blocks, but we need two DILexicalBlockFiles to
+// correctly represent file info.
 
 int foo() {
   int i = 1;
@@ -15,7 +14,6 @@ int foo() {
   return i + j;
 }
 
-// CHECK: DW_TAG_lexical_block
 // CHECK: DW_TAG_lexical_block
 // CHECK: !"m.h"
 // CHECK: DW_TAG_lexical_block
index 6051e6ed0fe11b03cd9005d328652caf952149fd..9decaeafd50ead8ebe005ba5112e7bc9f5fe00ca 100644 (file)
@@ -4,10 +4,12 @@
 int main() {
        int j = 0;
        int k = 0;
-// CHECK: DW_TAG_auto_variable
+// CHECK: DW_TAG_auto_variable ] [i]
 // CHECK-NEXT: DW_TAG_lexical_block
        for (int i = 0; i < 10; i++)
                j++;
+// CHECK: DW_TAG_auto_variable ] [i]
+// CHECK-NEXT: DW_TAG_lexical_block
        for (int i = 0; i < 10; i++)
                k++;
        return 0;
index f4a6a222182e60cb634e290c592c226fe61198cc..618d3a2232297fb89ae5aabbacfe22901bf6393c 100644 (file)
@@ -7,10 +7,9 @@ void f0() {
   }
 }
 
-// We should have 4 lexical blocks here at the moment, including one
+// We should have 3 lexical blocks here at the moment, including one
 // for the catch block.
 // CHECK: lexical_block
 // CHECK: lexical_block
-// CHECK: lexical_block
 // CHECK: auto_variable
 // CHECK: lexical_block