Skip to content

Commit

Permalink
[DebugInfo] Enable debug information for C99 VLA types
Browse files Browse the repository at this point in the history
Summary:
This patch enables debugging of C99 VLA types by generating more precise
LLVM Debug metadata, using the extended DISubrange 'count' field that
takes a DIVariable.
    
This should implement:
  Bug 30553: Debug info generated for arrays is not what GDB expects (not as good as GCC's)
https://bugs.llvm.org/show_bug.cgi?id=30553

Reviewers: echristo, aprantl, dexonsmith, clayborg, pcc, kristof.beyls, dblaikie

Reviewed By: aprantl

Subscribers: jholewinski, schweitz, davide, fhahn, JDevlieghere, cfe-commits

Differential Revision: https://reviews.llvm.org/D41698

llvm-svn: 323952
  • Loading branch information
sdesmalen-arm committed Feb 1, 2018
1 parent e11f054 commit 17c4633
Show file tree
Hide file tree
Showing 23 changed files with 207 additions and 75 deletions.
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGBlocks.cpp
Expand Up @@ -1479,8 +1479,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
if (capture.isConstant()) {
auto addr = LocalDeclMap.find(variable)->second;
DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
Builder);
(void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
Builder);
continue;
}

Expand Down
41 changes: 25 additions & 16 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Expand Up @@ -2292,12 +2292,14 @@ llvm::DIType *CGDebugInfo::CreateType(const VectorType *Ty,
llvm::DIFile *Unit) {
llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit);
int64_t Count = Ty->getNumElements();
if (Count == 0)
// If number of elements are not known then this is an unbounded array.
// Use Count == -1 to express such arrays.
Count = -1;

llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(0, Count);
llvm::Metadata *Subscript;
QualType QTy(Ty, 0);
auto SizeExpr = SizeExprCache.find(QTy);
if (SizeExpr != SizeExprCache.end())
Subscript = DBuilder.getOrCreateSubrange(0, SizeExpr->getSecond());
else
Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

uint64_t Size = CGM.getContext().getTypeSize(Ty);
Expand Down Expand Up @@ -2354,8 +2356,12 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) {
}
}

// FIXME: Verify this is right for VLAs.
Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
auto SizeNode = SizeExprCache.find(EltTy);
if (SizeNode != SizeExprCache.end())
Subscripts.push_back(
DBuilder.getOrCreateSubrange(0, SizeNode->getSecond()));
else
Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));
EltTy = Ty->getElementType();
}

Expand Down Expand Up @@ -3473,13 +3479,14 @@ llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
nullptr, Elements);
}

void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
llvm::Optional<unsigned> ArgNo,
CGBuilderTy &Builder) {
llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
llvm::Value *Storage,
llvm::Optional<unsigned> ArgNo,
CGBuilderTy &Builder) {
assert(DebugKind >= codegenoptions::LimitedDebugInfo);
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
if (VD->hasAttr<NoDebugAttr>())
return;
return nullptr;

bool Unwritten =
VD->isImplicit() || (isa<Decl>(VD->getDeclContext()) &&
Expand All @@ -3497,7 +3504,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
// If there is no debug info for this type then do not emit debug info
// for this variable.
if (!Ty)
return;
return nullptr;

// Get location information.
unsigned Line = 0;
Expand Down Expand Up @@ -3593,13 +3600,15 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
Builder.GetInsertBlock());

return D;
}

void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
llvm::Value *Storage,
CGBuilderTy &Builder) {
llvm::DILocalVariable *
CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage,
CGBuilderTy &Builder) {
assert(DebugKind >= codegenoptions::LimitedDebugInfo);
EmitDeclare(VD, Storage, llvm::None, Builder);
return EmitDeclare(VD, Storage, llvm::None, Builder);
}

llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,
Expand Down
24 changes: 20 additions & 4 deletions clang/lib/CodeGen/CGDebugInfo.h
Expand Up @@ -81,6 +81,10 @@ class CGDebugInfo {

llvm::SmallDenseMap<llvm::StringRef, llvm::StringRef> DebugPrefixMap;

/// Cache that maps VLA types to size expressions for that type,
/// represented by instantiated Metadata nodes.
llvm::SmallDenseMap<QualType, llvm::Metadata *> SizeExprCache;

struct ObjCInterfaceCacheEntry {
const ObjCInterfaceType *Type;
llvm::DIType *Decl;
Expand Down Expand Up @@ -309,6 +313,11 @@ class CGDebugInfo {

void finalize();

/// Register VLA size expression debug node with the qualified type.
void registerVLASizeExpression(QualType Ty, llvm::Metadata *SizeExpr) {
SizeExprCache[Ty] = SizeExpr;
}

/// Module debugging: Support for building PCMs.
/// @{
/// Set the main CU's DwoId field to \p Signature.
Expand Down Expand Up @@ -379,8 +388,11 @@ class CGDebugInfo {

/// Emit call to \c llvm.dbg.declare for an automatic variable
/// declaration.
void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
CGBuilderTy &Builder);
/// Returns a pointer to the DILocalVariable associated with the
/// llvm.dbg.declare, or nullptr otherwise.
llvm::DILocalVariable *EmitDeclareOfAutoVariable(const VarDecl *Decl,
llvm::Value *AI,
CGBuilderTy &Builder);

/// Emit call to \c llvm.dbg.declare for an imported variable
/// declaration in a block.
Expand Down Expand Up @@ -451,10 +463,14 @@ class CGDebugInfo {
llvm::DIMacroFile *CreateTempMacroFile(llvm::DIMacroFile *Parent,
SourceLocation LineLoc,
SourceLocation FileLoc);

private:
/// Emit call to llvm.dbg.declare for a variable declaration.
void EmitDeclare(const VarDecl *decl, llvm::Value *AI,
llvm::Optional<unsigned> ArgNo, CGBuilderTy &Builder);
/// Returns a pointer to the DILocalVariable associated with the
/// llvm.dbg.declare, or nullptr otherwise.
llvm::DILocalVariable *EmitDeclare(const VarDecl *decl, llvm::Value *AI,
llvm::Optional<unsigned> ArgNo,
CGBuilderTy &Builder);

/// Build up structure info for the byref. See \a BuildByRefType.
llvm::DIType *EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
Expand Down
82 changes: 68 additions & 14 deletions clang/lib/CodeGen/CGDecl.cpp
Expand Up @@ -955,6 +955,58 @@ void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
C->setDoesNotThrow();
}

void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo) {
// For each dimension stores its QualType and corresponding
// size-expression Value.
SmallVector<CodeGenFunction::VlaSizePair, 4> Dimensions;

// Break down the array into individual dimensions.
QualType Type1D = D.getType();
while (getContext().getAsVariableArrayType(Type1D)) {
auto VlaSize = getVLAElements1D(Type1D);
if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
Dimensions.emplace_back(C, Type1D.getUnqualifiedType());
else {
auto SizeExprAddr =
CreateDefaultAlignTempAlloca(VlaSize.NumElts->getType(), "vla_expr");
Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);
Dimensions.emplace_back(SizeExprAddr.getPointer(),
Type1D.getUnqualifiedType());
}
Type1D = VlaSize.Type;
}

if (!EmitDebugInfo)
return;

// Register each dimension's size-expression with a DILocalVariable,
// so that it can be used by CGDebugInfo when instantiating a DISubrange
// to describe this array.
for (auto &VlaSize : Dimensions) {
llvm::Metadata *MD;
if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
MD = llvm::ConstantAsMetadata::get(C);
else {
// Create an artificial VarDecl to generate debug info for.
IdentifierInfo &NameIdent = getContext().Idents.getOwn(
cast<llvm::AllocaInst>(VlaSize.NumElts)->getName());
auto VlaExprTy = VlaSize.NumElts->getType()->getPointerElementType();
auto QT = getContext().getIntTypeForBitwidth(
VlaExprTy->getScalarSizeInBits(), false);
auto *ArtificialDecl = VarDecl::Create(
getContext(), const_cast<DeclContext *>(D.getDeclContext()),
D.getLocation(), D.getLocation(), &NameIdent, QT,
getContext().CreateTypeSourceInfo(QT), SC_Auto);

MD = DI->EmitDeclareOfAutoVariable(ArtificialDecl, VlaSize.NumElts,
Builder);
}
assert(MD && "No Size expression debug node created");
DI->registerVLASizeExpression(VlaSize.Type, MD);
}
}

/// EmitAutoVarAlloca - Emit the alloca and debug information for a
/// local variable. Does not emit initialization or destruction.
CodeGenFunction::AutoVarEmission
Expand All @@ -975,6 +1027,10 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
if (Ty->isVariablyModifiedType())
EmitVariablyModifiedType(Ty);

auto *DI = getDebugInfo();
bool EmitDebugInfo = DI && CGM.getCodeGenOpts().getDebugInfo() >=
codegenoptions::LimitedDebugInfo;

Address address = Address::invalid();
if (Ty->isConstantSizeType()) {
bool NRVO = getLangOpts().ElideConstructors &&
Expand Down Expand Up @@ -1108,28 +1164,26 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
pushStackRestore(NormalCleanup, Stack);
}

llvm::Value *elementCount;
QualType elementType;
std::tie(elementCount, elementType) = getVLASize(Ty);

llvm::Type *llvmTy = ConvertTypeForMem(elementType);
auto VlaSize = getVLASize(Ty);
llvm::Type *llvmTy = ConvertTypeForMem(VlaSize.Type);

// Allocate memory for the array.
address = CreateTempAlloca(llvmTy, alignment, "vla", elementCount);
address = CreateTempAlloca(llvmTy, alignment, "vla", VlaSize.NumElts);

// If we have debug info enabled, properly describe the VLA dimensions for
// this type by registering the vla size expression for each of the
// dimensions.
EmitAndRegisterVariableArrayDimensions(DI, D, EmitDebugInfo);
}

setAddrOfLocalVar(&D, address);
emission.Addr = address;

// Emit debug info for local var declaration.
if (HaveInsertPoint())
if (CGDebugInfo *DI = getDebugInfo()) {
if (CGM.getCodeGenOpts().getDebugInfo() >=
codegenoptions::LimitedDebugInfo) {
DI->setLocation(D.getLocation());
DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
}
}
if (EmitDebugInfo && HaveInsertPoint()) {
DI->setLocation(D.getLocation());
(void)DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
}

if (D.hasAttr<AnnotateAttr>())
EmitVarAnnotations(&D, address.getPointer());
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CGExpr.cpp
Expand Up @@ -873,7 +873,7 @@ static llvm::Value *getArrayIndexingBound(
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
return CGF.Builder.getInt(CAT->getSize());
else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
return CGF.getVLASize(VAT).first;
return CGF.getVLASize(VAT).NumElts;
// Ignore pass_object_size here. It's not applicable on decayed pointers.
}
}
Expand Down Expand Up @@ -3313,7 +3313,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
auto *Idx = EmitIdxAfterBase(/*Promote*/true);

// The element count here is the total number of non-VLA elements.
llvm::Value *numElements = getVLASize(vla).first;
llvm::Value *numElements = getVLASize(vla).NumElts;

// Effectively, the multiply by the VLA size is part of the GEP.
// GEP indexes are signed, and scaling an index isn't permitted to
Expand Down Expand Up @@ -3547,7 +3547,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo,
BaseTy, VLA->getElementType(), IsLowerBound);
// The element count here is the total number of non-VLA elements.
llvm::Value *NumElements = getVLASize(VLA).first;
llvm::Value *NumElements = getVLASize(VLA).NumElts;

// Effectively, the multiply by the VLA size is part of the GEP.
// GEP indexes are signed, and scaling an index isn't permitted to
Expand Down
22 changes: 9 additions & 13 deletions clang/lib/CodeGen/CGExprScalar.cpp
Expand Up @@ -1973,7 +1973,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
// VLA types don't have constant size.
if (const VariableArrayType *vla
= CGF.getContext().getAsVariableArrayType(type)) {
llvm::Value *numElts = CGF.getVLASize(vla).first;
llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, numElts, "vla.inc");
Expand Down Expand Up @@ -2271,16 +2271,13 @@ ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
CGF.EmitIgnoredExpr(E->getArgumentExpr());
}

QualType eltType;
llvm::Value *numElts;
std::tie(numElts, eltType) = CGF.getVLASize(VAT);

llvm::Value *size = numElts;
auto VlaSize = CGF.getVLASize(VAT);
llvm::Value *size = VlaSize.NumElts;

// Scale the number of non-VLA elements by the non-VLA element size.
CharUnits eltSize = CGF.getContext().getTypeSizeInChars(eltType);
CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
if (!eltSize.isOne())
size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), numElts);
size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);

return size;
}
Expand Down Expand Up @@ -2767,7 +2764,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
if (const VariableArrayType *vla
= CGF.getContext().getAsVariableArrayType(elementType)) {
// The element count here is the total number of non-VLA elements.
llvm::Value *numElements = CGF.getVLASize(vla).first;
llvm::Value *numElements = CGF.getVLASize(vla).NumElts;

// Effectively, the multiply by the VLA size is part of the GEP.
// GEP indexes are signed, and scaling an index isn't permitted to
Expand Down Expand Up @@ -2962,10 +2959,9 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
// For a variable-length array, this is going to be non-constant.
if (const VariableArrayType *vla
= CGF.getContext().getAsVariableArrayType(elementType)) {
llvm::Value *numElements;
std::tie(numElements, elementType) = CGF.getVLASize(vla);

divisor = numElements;
auto VlaSize = CGF.getVLASize(vla);
elementType = VlaSize.Type;
divisor = VlaSize.NumElts;

// Scale the number of non-VLA elements by the non-VLA element size.
CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGOpenMPRuntime.cpp
Expand Up @@ -5154,7 +5154,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
llvm::Value *Size = CGF.Builder.CreateIntCast(
CGF.getVLASize(
CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
.first,
.NumElts,
CGF.SizeTy, /*isSigned=*/false);
CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
Elem);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
Expand Up @@ -2232,7 +2232,7 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
llvm::Value *Size = CGF.Builder.CreateIntCast(
CGF.getVLASize(
CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
.first,
.NumElts,
CGF.SizeTy, /*isSigned=*/false);
CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
Elem);
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Expand Up @@ -237,9 +237,10 @@ llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
if (SizeInChars.isZero()) {
// getTypeSizeInChars() returns 0 for a VLA.
while (auto *VAT = C.getAsVariableArrayType(Ty)) {
llvm::Value *ArraySize;
std::tie(ArraySize, Ty) = getVLASize(VAT);
Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize;
auto VlaSize = getVLASize(VAT);
Ty = VlaSize.Type;
Size = Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts)
: VlaSize.NumElts;
}
SizeInChars = C.getTypeSizeInChars(Ty);
if (SizeInChars.isZero())
Expand Down

0 comments on commit 17c4633

Please sign in to comment.