From b9a23c91559a86dcdf7c6b9eba3e9fcbb383be6e Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 2 Jan 2015 22:07:26 +0000 Subject: [PATCH] DebugInfo: Provide a less subtle way to set the debug location of simple ret instructions un-XFAILing the test XFAIL'd in r225086 after it regressed in r225083. llvm-svn: 225090 --- clang/lib/CodeGen/CGDebugInfo.cpp | 9 +++++++++ clang/lib/CodeGen/CGDebugInfo.h | 1 + clang/lib/CodeGen/CodeGenFunction.cpp | 23 ++++++++++++----------- clang/lib/CodeGen/CodeGenFunction.h | 2 +- clang/test/CodeGen/debug-info-line3.c | 5 ----- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9f993b8..6a911c5 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -75,6 +75,15 @@ ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, } } +ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc) + : CGF(CGF) { + if (CGF.getDebugInfo()) { + OriginalLocation = CGF.Builder.getCurrentDebugLocation(); + if (!Loc.isUnknown()) + CGF.Builder.SetCurrentDebugLocation(Loc); + } +} + ApplyDebugLocation::~ApplyDebugLocation() { // Query CGF so the location isn't overwritten when location updates are // temporarily disabled (for C++ default function arguments) diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 4c73743..8422a1f 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -454,6 +454,7 @@ public: ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation = SourceLocation(), bool ForceColumnInfo = false); + ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc); ~ApplyDebugLocation(); }; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4e97f9b..826171a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -158,7 +158,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { } } -void CodeGenFunction::EmitReturnBlock() { +llvm::DebugLoc CodeGenFunction::EmitReturnBlock() { // For cleanliness, we try to avoid emitting the return block for // simple cases. llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); @@ -173,7 +173,7 @@ void CodeGenFunction::EmitReturnBlock() { delete ReturnBlock.getBlock(); } else EmitBlock(ReturnBlock.getBlock()); - return; + return llvm::DebugLoc(); } // Otherwise, if the return block is the target of a single direct @@ -184,15 +184,13 @@ void CodeGenFunction::EmitReturnBlock() { dyn_cast(*ReturnBlock.getBlock()->user_begin()); if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock.getBlock()) { - // Reset insertion point, including debug location, and delete the - // branch. This is really subtle and only works because the next change - // in location will hit the caching in CGDebugInfo::EmitLocation and not - // override this. - Builder.SetCurrentDebugLocation(BI->getDebugLoc()); + // Record/return the DebugLoc of the simple 'return' expression to be used + // later by the actual 'ret' instruction. + llvm::DebugLoc Loc = BI->getDebugLoc(); Builder.SetInsertPoint(BI->getParent()); BI->eraseFromParent(); delete ReturnBlock.getBlock(); - return; + return Loc; } } @@ -201,6 +199,7 @@ void CodeGenFunction::EmitReturnBlock() { // region.end for now. EmitBlock(ReturnBlock.getBlock()); + return llvm::DebugLoc(); } static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { @@ -254,16 +253,18 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { } // Emit function epilog (to return). - EmitReturnBlock(); + llvm::DebugLoc Loc = EmitReturnBlock(); if (ShouldInstrumentFunction()) EmitFunctionInstrumentation("__cyg_profile_func_exit"); // Emit debug descriptor for function end. - if (CGDebugInfo *DI = getDebugInfo()) { + if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder); - } + // Reset the debug location to that of the simple 'return' expression, if any + // rather than that of the end of the function's scope '}'. + ApplyDebugLocation AL(*this, Loc); EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc); EmitEndEHSpec(CurCodeDecl); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8302b7a..3691469 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1262,7 +1262,7 @@ public: /// EmitReturnBlock - Emit the unified return block, trying to avoid its /// emission when possible. - void EmitReturnBlock(); + llvm::DebugLoc EmitReturnBlock(); /// FinishFunction - Complete IR generation of the current function. It is /// legal to call this function even if there is no current insertion point. diff --git a/clang/test/CodeGen/debug-info-line3.c b/clang/test/CodeGen/debug-info-line3.c index 13941c0..a2bb5c8 100644 --- a/clang/test/CodeGen/debug-info-line3.c +++ b/clang/test/CodeGen/debug-info-line3.c @@ -1,10 +1,5 @@ // RUN: %clang_cc1 -g -S -emit-llvm %s -o - | FileCheck %s -// Temporarily XFAIL while investigating regression. (other improvements seem -// more important to keep rather than reverting them in favor of preserving -// this) -// XFAIL: * - void func(char c, char* d) { *d = c + 1; -- 2.7.4