From: Adrian Prantl Date: Fri, 17 Jan 2014 00:15:10 +0000 (+0000) Subject: Debug info: Refactor NoLocation and ArtificialLocation to use a common base X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7095c767d444b4444563213f6882b28014c2e60e;p=clang Debug info: Refactor NoLocation and ArtificialLocation to use a common base class and use it pervasively to restore debug locations. Fixes an interaction between cleanup and EH that caused the location to not be restored properly after emitting a landing pad. rdar://problem/15208190 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199444 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index c4e7880196..4983ce9343 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -860,7 +860,9 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // Emit the EH cleanup if required. if (RequiresEHCleanup) { - if (CGDebugInfo *DI = getDebugInfo()) + CGDebugInfo *DI = getDebugInfo(); + SaveAndRestoreLocation AutoRestoreLocation(*this, Builder); + if (DI) DI->EmitLocation(Builder, CurEHLocation); CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 2977ed2223..3edffa5656 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -53,29 +53,34 @@ CGDebugInfo::~CGDebugInfo() { } -NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B) +SaveAndRestoreLocation::SaveAndRestoreLocation(CodeGenFunction &CGF, CGBuilderTy &B) : DI(CGF.getDebugInfo()), Builder(B) { if (DI) { SavedLoc = DI->getLocation(); DI->CurLoc = SourceLocation(); - Builder.SetCurrentDebugLocation(llvm::DebugLoc()); } } +SaveAndRestoreLocation::~SaveAndRestoreLocation() { + if (DI) + DI->EmitLocation(Builder, SavedLoc); +} + +NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B) + : SaveAndRestoreLocation(CGF, B) { + if (DI) + Builder.SetCurrentDebugLocation(llvm::DebugLoc()); +} + NoLocation::~NoLocation() { - if (DI) { + if (DI) assert(Builder.getCurrentDebugLocation().isUnknown()); - DI->CurLoc = SavedLoc; - } } ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B) - : DI(CGF.getDebugInfo()), Builder(B) { - if (DI) { - SavedLoc = DI->getLocation(); - DI->CurLoc = SourceLocation(); + : SaveAndRestoreLocation(CGF, B) { + if (DI) Builder.SetCurrentDebugLocation(llvm::DebugLoc()); - } } void ArtificialLocation::Emit() { @@ -91,10 +96,8 @@ void ArtificialLocation::Emit() { } ArtificialLocation::~ArtificialLocation() { - if (DI) { + if (DI) assert(Builder.getCurrentDebugLocation().getLine() == 0); - DI->CurLoc = SavedLoc; - } } void CGDebugInfo::setLocation(SourceLocation Loc) { diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 0ca274f568..fce56c0513 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -47,8 +47,8 @@ namespace CodeGen { /// and is responsible for emitting to llvm globals or pass directly to /// the backend. class CGDebugInfo { - friend class NoLocation; friend class ArtificialLocation; + friend class SaveAndRestoreLocation; CodeGenModule &CGM; const CodeGenOptions::DebugInfoKind DebugKind; llvm::DIBuilder DBuilder; @@ -394,16 +394,26 @@ private: } }; -/// NoLocation - An RAII object that temporarily disables debug -/// locations. This is useful for emitting instructions that should be -/// counted towards the function prologue. -class NoLocation { +/// SaveAndRestoreLocation - An RAII object saves the current location +/// and automatically restores it to the original value. +class SaveAndRestoreLocation { +protected: SourceLocation SavedLoc; CGDebugInfo *DI; CGBuilderTy &Builder; +public: + SaveAndRestoreLocation(CodeGenFunction &CGF, CGBuilderTy &B); + /// Autorestore everything back to normal. + ~SaveAndRestoreLocation(); +}; + +/// NoLocation - An RAII object that temporarily disables debug +/// locations. This is useful for emitting instructions that should be +/// counted towards the function prologue. +class NoLocation : public SaveAndRestoreLocation { public: NoLocation(CodeGenFunction &CGF, CGBuilderTy &B); - /// ~NoLocation - Autorestore everything back to normal. + /// Autorestore everything back to normal. ~NoLocation(); }; @@ -418,10 +428,7 @@ public: /// This is necessary because passing an empty SourceLocation to /// CGDebugInfo::setLocation() will result in the last valid location /// being reused. -class ArtificialLocation { - SourceLocation SavedLoc; - CGDebugInfo *DI; - CGBuilderTy &Builder; +class ArtificialLocation : public SaveAndRestoreLocation { public: ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B); @@ -429,7 +436,7 @@ public: /// (= the top of the LexicalBlockStack). void Emit(); - /// ~ArtificialLocation - Autorestore everything back to normal. + /// Autorestore everything back to normal. ~ArtificialLocation(); }; diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 8a43794281..cc03b0a8d5 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -766,11 +766,9 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // Save the current IR generation state. CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP(); - SourceLocation SavedLocation; - if (CGDebugInfo *DI = getDebugInfo()) { - SavedLocation = DI->getLocation(); + SaveAndRestoreLocation AutoRestoreLocation(*this, Builder); + if (CGDebugInfo *DI = getDebugInfo()) DI->EmitLocation(Builder, CurEHLocation); - } const EHPersonality &personality = EHPersonality::get(getLangOpts()); @@ -892,8 +890,6 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { // Restore the old IR generation state. Builder.restoreIP(savedIP); - if (CGDebugInfo *DI = getDebugInfo()) - DI->EmitLocation(Builder, SavedLocation); return lpad; } diff --git a/test/CodeGenCXX/linetable-eh.cpp b/test/CodeGenCXX/linetable-eh.cpp new file mode 100644 index 0000000000..d190c64c01 --- /dev/null +++ b/test/CodeGenCXX/linetable-eh.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-macosx10.9.0 -munwind-tables -std=c++11 -fcxx-exceptions -fexceptions %s -o - | FileCheck %s + +// Test that emitting a landing pad does not affect the line table +// entries for the code that triggered it. + +// CHECK: call void @llvm.dbg.declare +// CHECK: call void @llvm.dbg.declare(metadata !{{{.*}}}, metadata ![[CURRENT_ADDR:.*]]), !dbg ![[DBG1:.*]] +// CHECK: unwind label %{{.*}}, !dbg ![[DBG1]] +// CHECK: store i64 %{{.*}}, i64* %current_address, align 8, !dbg ![[DBG1]] +// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{{{.*}}}, metadata ![[FOUND_IT:.*]]), !dbg ![[DBG2:.*]] +// CHECK: = landingpad +// CHECK-NEXT: cleanup, !dbg ![[DBG3:.*]] +// CHECK-DAG: ![[CURRENT_ADDR]] = {{.*}} [current_address] +// CHECK-DAG: ![[FOUND_IT]] = {{.*}} [found_it] +// CHECK-DAG: ![[DBG1]] = metadata !{i32 256, +// CHECK-DAG: ![[DBG2]] = metadata !{i32 257, +// CHECK-DAG: ![[DBG3]] = metadata !{i32 268, +typedef unsigned long long uint64_t; +template class shared_ptr { +public: + typedef _Tp element_type; + element_type* __ptr_; + ~shared_ptr(); + element_type* operator->() const noexcept {return __ptr_;} +}; +class Context { +public: + uint64_t GetIt(); +}; +class Foo +{ + bool bar(); + virtual shared_ptr GetContext () = 0; +}; +# 253 "Foo.cpp" 3 +bool +Foo::bar () +{ + uint64_t current_address = GetContext()->GetIt(); + bool found_it = false; +# 267 "Foo.cpp" 3 + return found_it; +}