aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-01-26 22:16:26 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-01-26 22:16:26 +0000
commita6504853d297c30cfa271f4710af5a3d5db59449 (patch)
tree113c931f80320603886620025086cace8a4e6d4f
parent8c718e7d87018919b5b84b0d545fe477b2d532d1 (diff)
PR14566: Debug Info: avoid top level lexical blocks in functions
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
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp6
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp16
-rw-r--r--lib/CodeGen/CodeGenFunction.h5
-rw-r--r--test/CodeGen/2010-02-16-DbgScopes.c1
-rw-r--r--test/CodeGen/2010-03-5-LexicalScope.c1
-rw-r--r--test/CodeGen/debug-info-line.c6
-rw-r--r--test/CodeGen/debug-info-scope.c4
-rw-r--r--test/CodeGenObjC/catch-lexical-block.m3
9 files changed, 27 insertions, 17 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index ec88d8727c..ca810e7cf5 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -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;
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index ea4c08fac3..a293f1d2e7 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -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);
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 1fdcc6f9ec..59e38e63d5 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -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
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index bfcc77a3fd..6f06b3bc26 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -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.
diff --git a/test/CodeGen/2010-02-16-DbgScopes.c b/test/CodeGen/2010-02-16-DbgScopes.c
index 58bda9a2d7..36484a4c63 100644
--- a/test/CodeGen/2010-02-16-DbgScopes.c
+++ b/test/CodeGen/2010-02-16-DbgScopes.c
@@ -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();
diff --git a/test/CodeGen/2010-03-5-LexicalScope.c b/test/CodeGen/2010-03-5-LexicalScope.c
index 511372d158..e0e41dd237 100644
--- a/test/CodeGen/2010-03-5-LexicalScope.c
+++ b/test/CodeGen/2010-03-5-LexicalScope.c
@@ -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;
diff --git a/test/CodeGen/debug-info-line.c b/test/CodeGen/debug-info-line.c
index 9e6e9714aa..8f869d04f0 100644
--- a/test/CodeGen/debug-info-line.c
+++ b/test/CodeGen/debug-info-line.c
@@ -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;
@@ -16,7 +15,6 @@ int foo() {
}
// CHECK: DW_TAG_lexical_block
-// CHECK: DW_TAG_lexical_block
// CHECK: !"m.h"
// CHECK: DW_TAG_lexical_block
// CHECK: !"m.c"
diff --git a/test/CodeGen/debug-info-scope.c b/test/CodeGen/debug-info-scope.c
index 6051e6ed0f..9decaeafd5 100644
--- a/test/CodeGen/debug-info-scope.c
+++ b/test/CodeGen/debug-info-scope.c
@@ -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;
diff --git a/test/CodeGenObjC/catch-lexical-block.m b/test/CodeGenObjC/catch-lexical-block.m
index f4a6a22218..618d3a2232 100644
--- a/test/CodeGenObjC/catch-lexical-block.m
+++ b/test/CodeGenObjC/catch-lexical-block.m
@@ -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