diff options
author | Adrian Prantl <aprantl@apple.com> | 2013-05-02 17:30:20 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2013-05-02 17:30:20 +0000 |
commit | fa6b079b1231366696f6a497c6a084c73a35c85d (patch) | |
tree | 302668355094ed5d183c591e7fb9f529f451e715 /lib/CodeGen/CodeGenFunction.cpp | |
parent | d4147c4b2d4eba0327658f36c5a2c63f2d234991 (diff) |
Ensure that the line table for functions with cleanups is sequential.
If there is cleanup code, the cleanup code gets the debug location of
the closing '}'. The subsequent ret IR-instruction does not get a
debug location. The return _expression_ will get the debug location
of the return statement.
If the function contains only a single, simple return statement,
the cleanup code may become the first breakpoint in the function.
In this case we set the debug location for the cleanup code
to the location of the return statement.
rdar://problem/13442648
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180932 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 0daae58bdc..122e95b266 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -44,6 +44,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) DebugInfo(0), DisableDebugInfo(false), CalleeWithThisReturn(0), DidCallStackSave(false), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), + NumStopPoints(0), NumSimpleReturnExprs(0), CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXDefaultInitExprThis(0), CXXStructorImplicitParamDecl(0), CXXStructorImplicitParamValue(0), @@ -187,16 +188,35 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - if (CGDebugInfo *DI = getDebugInfo()) - DI->EmitLocation(Builder, EndLoc); + // If the function contains only a single, simple return statement, + // the cleanup code may become the first breakpoint in the + // function. To be safe set the debug location for it to the + // location of the return statement. Otherwise point it to end of + // the function's lexical scope. + if (CGDebugInfo *DI = getDebugInfo()) { + if (NumSimpleReturnExprs == 1 && NumStopPoints == 1) + DI->EmitLocation(Builder, FirstStopPoint); + else + DI->EmitLocation(Builder, EndLoc); + } // Pop any cleanups that might have been associated with the // parameters. Do this in whatever block we're currently in; it's // important to do this before we enter the return block or return // edges will be *really* confused. - if (EHStack.stable_begin() != PrologueCleanupDepth) + bool EmitRetDbgLoc = true; + if (EHStack.stable_begin() != PrologueCleanupDepth) { PopCleanupBlocks(PrologueCleanupDepth); + // Make sure the line table doesn't jump back into the body for + // the ret after it's been at EndLoc. + EmitRetDbgLoc = false; + + if (CGDebugInfo *DI = getDebugInfo()) + if (NumSimpleReturnExprs == 1 && NumStopPoints == 1) + DI->EmitLocation(Builder, EndLoc); + } + // Emit function epilog (to return). EmitReturnBlock(); @@ -208,7 +228,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { DI->EmitFunctionEnd(Builder); } - EmitFunctionEpilog(*CurFnInfo); + EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc); EmitEndEHSpec(CurCodeDecl); assert(EHStack.empty() && |