Replace llvm::DIBuilder::DisableDebugLocations() with two RAII interfaces

inspired by CodegenFunction::LexicalScope.
- NoLocation temporarily turns off debug locations altogether.
  This is useful for emitting instructions that should be
  counted towards the function prologue.
- BuiltinLocation temporarily switches to an artificial debug location
  that has a valid scope, but no line information. This is useful when
  emitting compiler-generated helper functions that have no source
  location associated with them.

llvm-svn: 186552
This commit is contained in:
Adrian Prantl 2013-07-18 00:28:02 +00:00
parent 02c0caa198
commit 2e0637ff63
3 changed files with 75 additions and 3 deletions

View File

@ -1164,9 +1164,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
Alloca->setAlignment(Align);
// Set the DebugLocation to empty, so the store is recognized as a
// frame setup instruction by llvm::DwarfDebug::beginFunction().
Builder.DisableDebugLocations();
NoLocation NL(*this, Builder);
Builder.CreateAlignedStore(BlockPointer, Alloca, Align);
Builder.EnableDebugLocations();
BlockPointerDbgLoc = Alloca;
}

View File

@ -51,6 +51,44 @@ CGDebugInfo::~CGDebugInfo() {
"Region stack mismatch, stack not empty!");
}
NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
: DI(CGF.getDebugInfo()), Builder(B) {
if (DI) {
SavedLoc = DI->getLocation();
DI->CurLoc = SourceLocation();
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
}
}
NoLocation::~NoLocation() {
if (DI) {
assert(Builder.getCurrentDebugLocation().isUnknown());
DI->CurLoc = SavedLoc;
}
}
BuiltinLocation::BuiltinLocation(CodeGenFunction &CGF, CGBuilderTy &B)
: DI(CGF.getDebugInfo()), Builder(B) {
if (DI) {
SavedLoc = DI->getLocation();
// Sync the Builder.
DI->EmitLocation(Builder, SavedLoc);
DI->CurLoc = SourceLocation();
// Construct a location that has a valid scope, but no line info.
llvm::MDNode *Scope = DI->LexicalBlockStack.empty() ?
DI->TheCU : DI->LexicalBlockStack.back();
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(0, 0, Scope));
}
}
BuiltinLocation::~BuiltinLocation() {
if (DI) {
assert(Builder.getCurrentDebugLocation().getLine() == 0);
DI->CurLoc = SavedLoc;
}
}
void CGDebugInfo::setLocation(SourceLocation Loc) {
// If the new location isn't valid return.
if (Loc.isInvalid()) return;
@ -2449,7 +2487,6 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
/// previous location will be reused.
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
bool ForceColumnInfo) {
// Update our current location
setLocation(Loc);

View File

@ -47,6 +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 BuiltinLocation;
CodeGenModule &CGM;
const CodeGenOptions::DebugInfoKind DebugKind;
llvm::DIBuilder DBuilder;
@ -387,6 +389,40 @@ private:
/// \param Force Assume DebugColumnInfo option is true.
unsigned getColumnNumber(SourceLocation Loc, bool Force=false);
};
/// 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 {
SourceLocation SavedLoc;
CGDebugInfo *DI;
CGBuilderTy &Builder;
public:
NoLocation(CodeGenFunction &CGF, CGBuilderTy &B);
/// ~NoLocation - Autorestore everything back to normal.
~NoLocation();
};
/// BuiltinLocation - An RAII object that temporarily switches to an
/// artificial debug location that has a valid scope, but no line
/// information. This is useful when emitting compiler-generated
/// helper functions that have no source location associated with
/// them.
///
/// This is necessary because pasing an empty SourceLocation to
/// CGDebugInfo::setLocation() will result in the last valid location
/// being reused.
class BuiltinLocation {
SourceLocation SavedLoc;
CGDebugInfo *DI;
CGBuilderTy &Builder;
public:
BuiltinLocation(CodeGenFunction &CGF, CGBuilderTy &B);
/// ~BuildinLocation - Autorestore everything back to normal.
~BuiltinLocation();
};
} // namespace CodeGen
} // namespace clang