Improve debugging information for BlockDeclRefExpr. WIP. Given this

scheme, we can switch the previous scheme over to using this code
path.  There's a bit of simplifications yet to do as well.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83138 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mike Stump 2009-09-30 02:43:10 +00:00
Родитель 432887fadd
Коммит b1a6e68796
3 изменённых файлов: 246 добавлений и 0 удалений

Просмотреть файл

@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/DeclObjC.h"
@ -661,9 +662,40 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
StartFunction(BD, ResultType, Fn, Args,
BExpr->getBody()->getLocEnd());
// Save a spot to insert the debug information for all the BlockDeclRefDecls.
llvm::BasicBlock *entry = Builder.GetInsertBlock();
llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
CurFuncDecl = OuterFuncDecl;
CurCodeDecl = BD;
EmitStmt(BExpr->getBody());
if (CGDebugInfo *DI = getDebugInfo()) {
llvm::BasicBlock *end = Builder.GetInsertBlock();
llvm::BasicBlock::iterator end_ptr = Builder.GetInsertPoint();
// Emit debug information for all the BlockDeclRefDecls.
// First, go back to the entry...
Builder.SetInsertPoint(entry, entry_ptr);
// And then insert the debug information..
for (unsigned i=0; i < BlockDeclRefDecls.size(); ++i) {
const Expr *E = BlockDeclRefDecls[i];
const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
if (BDRE) {
const ValueDecl *D = BDRE->getDecl();
DI->setLocation(D->getLocation());
DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
LocalDeclMap[getBlockStructDecl()],
Builder, this);
}
}
// Then go back to the end, and we're done.
Builder.SetInsertPoint(end, end_ptr);
}
FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
// The runtime needs a minimum alignment of a void *.

Просмотреть файл

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
@ -1076,12 +1077,213 @@ void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag,
DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
}
/// EmitDeclare - Emit local variable declaration debug info.
void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
llvm::Value *Storage, CGBuilderTy &Builder,
CodeGenFunction *CGF) {
const ValueDecl *Decl = BDRE->getDecl();
assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
// Do not emit variable debug information while generating optimized code.
// The llvm optimizer and code generator are not yet ready to support
// optimized code debugging.
const CompileOptions &CO = M->getCompileOpts();
if (CO.OptimizationLevel)
return;
uint64_t XOffset = 0;
llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
QualType Type = Decl->getType();
llvm::DIType Ty = getOrCreateType(Type, Unit);
if (Decl->hasAttr<BlocksAttr>()) {
llvm::DICompileUnit DefUnit;
unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
llvm::DIType FieldTy;
QualType FType;
uint64_t FieldSize, FieldOffset;
unsigned FieldAlign;
llvm::DIArray Elements;
llvm::DIType EltTy;
// Build up structure for the byref. See BuildByRefType.
FieldOffset = 0;
FType = M->getContext().getPointerType(M->getContext().VoidTy);
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__isa", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
FType = M->getContext().getPointerType(M->getContext().VoidTy);
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__forwarding", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__flags", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__size", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
bool HasCopyAndDispose = M->BlockRequiresCopying(Type);
if (HasCopyAndDispose) {
FType = M->getContext().getPointerType(M->getContext().VoidTy);
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__copy_helper", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
FType = M->getContext().getPointerType(M->getContext().VoidTy);
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
"__destroy_helper", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
}
unsigned Align = M->getContext().getDeclAlignInBytes(Decl);
if (Align > M->getContext().Target.getPointerAlign(0) / 8) {
unsigned AlignedOffsetInBytes
= llvm::RoundUpToAlignment(FieldOffset/8, Align);
unsigned NumPaddingBytes
= AlignedOffsetInBytes - FieldOffset/8;
if (NumPaddingBytes > 0) {
llvm::APInt pad(32, NumPaddingBytes);
FType = M->getContext().getConstantArrayType(M->getContext().CharTy,
pad, ArrayType::Normal, 0);
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = M->getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
Unit, "", DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
}
}
FType = Type;
FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
FieldSize = M->getContext().getTypeSize(FType);
FieldAlign = Align*8;
std::string Name = Decl->getNameAsString();
XOffset = FieldOffset;
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
Name, DefUnit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
FieldOffset += FieldSize;
Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
Ty = DebugFactory.CreateCompositeType(Tag, Unit, "",
llvm::DICompileUnit(),
0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
}
// Get location information.
SourceManager &SM = M->getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(Decl->getLocation());
unsigned Line = 0;
if (!PLoc.isInvalid())
Line = PLoc.getLine();
else
Unit = llvm::DICompileUnit();
uint64_t offset = CGF->BlockDecls[Decl];
llvm::SmallVector<llvm::Value *, 9> addr;
llvm::LLVMContext &VMContext = M->getLLVMContext();
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpDeref));
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpPlus));
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
offset));
if (BDRE->isByRef()) {
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpDeref));
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpPlus));
offset = CGF->LLVMPointerWidth/8; // offset of __forwarding field
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
offset));
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpDeref));
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
llvm::DIFactory::OpPlus));
offset = XOffset/8; // offset of x field
addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
offset));
}
// Create the descriptor for the variable.
llvm::DIVariable D =
DebugFactory.CreateComplexVariable(Tag, RegionStack.back(),
Decl->getNameAsString(), Unit, Line, Ty,
addr);
// Insert an llvm.dbg.declare into the current block.
DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
}
void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *Decl,
llvm::Value *Storage,
CGBuilderTy &Builder) {
EmitDeclare(Decl, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder);
}
void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
const BlockDeclRefExpr *BDRE, llvm::Value *Storage, CGBuilderTy &Builder,
CodeGenFunction *CGF) {
EmitDeclare(BDRE, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder, CGF);
}
/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
/// variable declaration.
void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,

Просмотреть файл

@ -15,6 +15,7 @@
#define CLANG_CODEGEN_CGDEBUGINFO_H
#include "clang/AST/Type.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Analysis/DebugInfo.h"
@ -33,6 +34,7 @@ namespace clang {
namespace CodeGen {
class CodeGenModule;
class CodeGenFunction;
/// CGDebugInfo - This class gathers all debug information during compilation
/// and is responsible for emitting to llvm globals or pass directly to
@ -102,6 +104,13 @@ public:
void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
CGBuilderTy &Builder);
/// EmitDeclareOfBlockDeclRefVariable - Emit call to llvm.dbg.declare for an
/// imported variable declaration in a block.
void EmitDeclareOfBlockDeclRefVariable(const BlockDeclRefExpr *BDRE,
llvm::Value *AI,
CGBuilderTy &Builder,
CodeGenFunction *CGF);
/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
/// variable declaration.
void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
@ -118,6 +127,9 @@ private:
void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
CGBuilderTy &Builder);
/// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
void EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, llvm::Value *AI,
CGBuilderTy &Builder, CodeGenFunction *CGF);
/// getOrCreateCompileUnit - Get the compile unit from the cache or create a
/// new one if necessary.