Skip to content

Commit 00c64e7

Browse files
Merge pull request #27345 from adrian-prantl/16042546
Debug Info: Encode let-bindings using DW_TAG_const_type.
2 parents 6f8b2bf + ff22da2 commit 00c64e7

20 files changed

+168
-125
lines changed

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,6 +5064,10 @@ bool VarDecl::isSettable(const DeclContext *UseDC,
50645064
if (!isLet())
50655065
return supportsMutation();
50665066

5067+
// Debugger expression 'let's are initialized through a side-channel.
5068+
if (isDebuggerVar())
5069+
return false;
5070+
50675071
// We have a 'let'; we must be checking settability from a specific
50685072
// DeclContext to go on further.
50695073
if (UseDC == nullptr)

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
168168
void emitVariableDeclaration(IRBuilder &Builder,
169169
ArrayRef<llvm::Value *> Storage,
170170
DebugTypeInfo Ty, const SILDebugScope *DS,
171-
ValueDecl *VarDecl, StringRef Name,
172-
unsigned ArgNo = 0,
171+
ValueDecl *VarDecl, SILDebugVariable VarInfo,
173172
IndirectionKind = DirectValue,
174173
ArtificialKind = RealValue);
175174
void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
@@ -2133,7 +2132,7 @@ void IRGenDebugInfoImpl::emitArtificialFunction(IRBuilder &Builder,
21332132

21342133
void IRGenDebugInfoImpl::emitVariableDeclaration(
21352134
IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo DbgTy,
2136-
const SILDebugScope *DS, ValueDecl *VarDecl, StringRef Name, unsigned ArgNo,
2135+
const SILDebugScope *DS, ValueDecl *VarDecl, SILDebugVariable VarInfo,
21372136
IndirectionKind Indirection, ArtificialKind Artificial) {
21382137
assert(DS && "variable has no scope");
21392138

@@ -2153,19 +2152,21 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
21532152

21542153
// FIXME: this should be the scope of the type's declaration.
21552154
// If this is an argument, attach it to the current function scope.
2156-
if (ArgNo > 0) {
2155+
if (VarInfo.ArgNo > 0) {
21572156
while (isa<llvm::DILexicalBlock>(Scope))
21582157
Scope = cast<llvm::DILexicalBlock>(Scope)->getScope();
21592158
}
21602159
assert(Scope && isa<llvm::DIScope>(Scope) && "variable has no scope");
21612160
llvm::DIFile *Unit = getFile(Scope);
21622161
llvm::DIType *DITy = getOrCreateType(DbgTy);
21632162
assert(DITy && "could not determine debug type of variable");
2163+
if (VarInfo.Constant)
2164+
DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);
21642165

21652166
unsigned Line = Loc.Line;
21662167

21672168
// Self is always an artificial argument, so are variables without location.
2168-
if (!Line || (ArgNo > 0 && Name == IGM.Context.Id_self.str()))
2169+
if (!Line || (VarInfo.ArgNo > 0 && VarInfo.Name == IGM.Context.Id_self.str()))
21692170
Artificial = ArtificialValue;
21702171

21712172
llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
@@ -2176,10 +2177,11 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
21762177
bool Optimized = false;
21772178
// Create the descriptor for the variable.
21782179
llvm::DILocalVariable *Var =
2179-
(ArgNo > 0) ? DBuilder.createParameterVariable(
2180-
Scope, Name, ArgNo, Unit, Line, DITy, Optimized, Flags)
2181-
: DBuilder.createAutoVariable(Scope, Name, Unit, Line, DITy,
2182-
Optimized, Flags);
2180+
(VarInfo.ArgNo > 0)
2181+
? DBuilder.createParameterVariable(Scope, VarInfo.Name, VarInfo.ArgNo,
2182+
Unit, Line, DITy, Optimized, Flags)
2183+
: DBuilder.createAutoVariable(Scope, VarInfo.Name, Unit, Line, DITy,
2184+
Optimized, Flags);
21832185

21842186
// Running variables for the current/previous piece.
21852187
bool IsPiece = Storage.size() > 1;
@@ -2263,16 +2265,22 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
22632265
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
22642266
return;
22652267

2266-
llvm::DIType *Ty = getOrCreateType(DbgTy);
2267-
if (Ty->isArtificial() || Ty == InternalType || !Loc)
2268+
llvm::DIType *DITy = getOrCreateType(DbgTy);
2269+
VarDecl *VD = nullptr;
2270+
if (Loc)
2271+
VD = dyn_cast_or_null<VarDecl>(Loc->getAsASTNode<Decl>());
2272+
if (!VD || VD->isLet())
2273+
DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);
2274+
2275+
if (DITy->isArtificial() || DITy == InternalType || !Loc)
22682276
// FIXME: Really these should be marked as artificial, but LLVM
22692277
// currently has no support for flags to be put on global
22702278
// variables. In the mean time, elide these variables, they
22712279
// would confuse both the user and LLDB.
22722280
return;
22732281

22742282
if (InFixedBuffer)
2275-
Ty = createFixedValueBufferStruct(Ty);
2283+
DITy = createFixedValueBufferStruct(DITy);
22762284

22772285
auto L = getStartLocation(Loc);
22782286
auto File = getOrCreateFile(L.Filename);
@@ -2282,7 +2290,7 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
22822290
if (!Var)
22832291
Expr = DBuilder.createConstantValueExpression(0);
22842292
auto *GV = DBuilder.createGlobalVariableExpression(
2285-
MainModule, Name, LinkageName, File, L.Line, Ty, IsLocalToUnit, Expr);
2293+
MainModule, Name, LinkageName, File, L.Line, DITy, IsLocalToUnit, Expr);
22862294
if (Var)
22872295
Var->addDebugInfo(GV);
22882296
}
@@ -2308,7 +2316,7 @@ void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
23082316
Metadata->getType(), Size(CI.getTargetInfo().getPointerWidth(0)),
23092317
Alignment(CI.getTargetInfo().getPointerAlign(0)));
23102318
emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
2311-
nullptr, OS.str().str(), 0,
2319+
nullptr, {OS.str().str(), 0, false},
23122320
// swift.type is already a pointer type,
23132321
// having a shadow copy doesn't add another
23142322
// layer of indirection.
@@ -2407,11 +2415,10 @@ void IRGenDebugInfo::emitArtificialFunction(IRBuilder &Builder,
24072415

24082416
void IRGenDebugInfo::emitVariableDeclaration(
24092417
IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo Ty,
2410-
const SILDebugScope *DS, ValueDecl *VarDecl, StringRef Name,
2411-
unsigned ArgNo, IndirectionKind Indirection,
2412-
ArtificialKind Artificial) {
2418+
const SILDebugScope *DS, ValueDecl *VarDecl, SILDebugVariable VarInfo,
2419+
IndirectionKind Indirection, ArtificialKind Artificial) {
24132420
static_cast<IRGenDebugInfoImpl *>(this)->emitVariableDeclaration(
2414-
Builder, Storage, Ty, DS, VarDecl, Name, ArgNo, Indirection, Artificial);
2421+
Builder, Storage, Ty, DS, VarDecl, VarInfo, Indirection, Artificial);
24152422
}
24162423

24172424
void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,

lib/IRGen/IRGenDebugInfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_IRGEN_DEBUGINFO_H
1818
#define SWIFT_IRGEN_DEBUGINFO_H
1919

20+
#include <swift/SIL/SILInstruction.h>
2021
#include "DebugTypeInfo.h"
2122
#include "IRGenFunction.h"
2223

@@ -133,8 +134,7 @@ class IRGenDebugInfo {
133134
void emitVariableDeclaration(IRBuilder &Builder,
134135
ArrayRef<llvm::Value *> Storage,
135136
DebugTypeInfo Ty, const SILDebugScope *DS,
136-
ValueDecl *VarDecl, StringRef Name,
137-
unsigned ArgNo = 0,
137+
ValueDecl *VarDecl, SILDebugVariable VarInfo,
138138
IndirectionKind Indirection = DirectValue,
139139
ArtificialKind Artificial = RealValue);
140140

lib/IRGen/IRGenSIL.cpp

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -761,13 +761,14 @@ class IRGenSILFunction :
761761

762762
/// Unconditionally emit a stack shadow copy of an \c llvm::Value.
763763
llvm::Value *emitShadowCopy(llvm::Value *Storage, const SILDebugScope *Scope,
764-
StringRef Name, unsigned ArgNo, Alignment Align) {
764+
SILDebugVariable VarInfo, Alignment Align) {
765765
if (Align.isZero())
766766
Align = IGM.getPointerAlignment();
767767

768-
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, Name}}];
768+
unsigned ArgNo = VarInfo.ArgNo;
769+
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, VarInfo.Name}}];
769770
if (!Alloca.isValid())
770-
Alloca = createAlloca(Storage->getType(), Align, Name+".debug");
771+
Alloca = createAlloca(Storage->getType(), Align, VarInfo.Name + ".debug");
771772
zeroInit(cast<llvm::AllocaInst>(Alloca.getAddress()));
772773

773774
ArtificialLocation AutoRestore(Scope, IGM.DebugInfo.get(), Builder);
@@ -781,7 +782,7 @@ class IRGenSILFunction :
781782
/// shadow copies, we lose the precise lifetime.
782783
llvm::Value *emitShadowCopyIfNeeded(llvm::Value *Storage,
783784
const SILDebugScope *Scope,
784-
StringRef Name, unsigned ArgNo,
785+
SILDebugVariable VarInfo,
785786
bool IsAnonymous,
786787
Alignment Align = Alignment(0)) {
787788
// Never emit shadow copies when optimizing, or if already on the stack.
@@ -792,7 +793,7 @@ class IRGenSILFunction :
792793
return Storage;
793794

794795
// Always emit shadow copies for function arguments.
795-
if (ArgNo == 0)
796+
if (VarInfo.ArgNo == 0)
796797
// Otherwise only if debug value range extension is not feasible.
797798
if (!needsShadowCopy(Storage)) {
798799
// Mark for debug value range extension unless this is a constant, or
@@ -809,22 +810,22 @@ class IRGenSILFunction :
809810

810811
return Storage;
811812
}
812-
return emitShadowCopy(Storage, Scope, Name, ArgNo, Align);
813+
return emitShadowCopy(Storage, Scope, VarInfo, Align);
813814
}
814815

815816
/// Like \c emitShadowCopyIfNeeded() but takes an \c Address instead of an
816817
/// \c llvm::Value.
817818
llvm::Value *emitShadowCopyIfNeeded(Address Storage,
818819
const SILDebugScope *Scope,
819-
StringRef Name, unsigned ArgNo,
820+
SILDebugVariable VarInfo,
820821
bool IsAnonymous) {
821-
return emitShadowCopyIfNeeded(Storage.getAddress(), Scope, Name, ArgNo,
822+
return emitShadowCopyIfNeeded(Storage.getAddress(), Scope, VarInfo,
822823
IsAnonymous, Storage.getAlignment());
823824
}
824825

825826
/// Like \c emitShadowCopyIfNeeded() but takes an exploded value.
826827
void emitShadowCopyIfNeeded(SILValue &SILVal, const SILDebugScope *Scope,
827-
StringRef Name, unsigned ArgNo, bool IsAnonymous,
828+
SILDebugVariable VarInfo, bool IsAnonymous,
828829
llvm::SmallVectorImpl<llvm::Value *> &copy) {
829830
Explosion e = getLoweredExplosion(SILVal);
830831

@@ -840,13 +841,13 @@ class IRGenSILFunction :
840841
auto vals = e.claimAll();
841842
for (auto val : vals)
842843
copy.push_back(
843-
emitShadowCopyIfNeeded(val, Scope, Name, ArgNo, IsAnonymous));
844+
emitShadowCopyIfNeeded(val, Scope, VarInfo, IsAnonymous));
844845
return;
845846
}
846847

847848
SILType Type = SILVal->getType();
848849
auto &LTI = cast<LoadableTypeInfo>(IGM.getTypeInfo(Type));
849-
auto Alloca = LTI.allocateStack(*this, Type, Name+".debug");
850+
auto Alloca = LTI.allocateStack(*this, Type, VarInfo.Name + ".debug");
850851
zeroInit(cast<llvm::AllocaInst>(Alloca.getAddress().getAddress()));
851852
ArtificialLocation AutoRestore(Scope, IGM.DebugInfo.get(), Builder);
852853
LTI.initialize(*this, e, Alloca.getAddress(), false /* isOutlined */);
@@ -867,22 +868,18 @@ class IRGenSILFunction :
867868

868869
/// Emit debug info for a function argument or a local variable.
869870
template <typename StorageType>
870-
void emitDebugVariableDeclaration(StorageType Storage,
871-
DebugTypeInfo Ty,
872-
SILType SILTy,
873-
const SILDebugScope *DS,
874-
VarDecl *VarDecl,
875-
StringRef Name,
876-
unsigned ArgNo = 0,
871+
void emitDebugVariableDeclaration(StorageType Storage, DebugTypeInfo Ty,
872+
SILType SILTy, const SILDebugScope *DS,
873+
VarDecl *VarDecl, SILDebugVariable VarInfo,
877874
IndirectionKind Indirection = DirectValue) {
878875
assert(IGM.DebugInfo && "debug info not enabled");
879-
if (ArgNo) {
876+
if (VarInfo.ArgNo) {
880877
PrologueLocation AutoRestore(IGM.DebugInfo.get(), Builder);
881878
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarDecl,
882-
Name, ArgNo, Indirection);
879+
VarInfo, Indirection);
883880
} else
884881
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarDecl,
885-
Name, 0, Indirection);
882+
VarInfo, Indirection);
886883
}
887884

888885
void emitFailBB() {
@@ -3649,17 +3646,16 @@ void IRGenSILFunction::emitErrorResultVar(SILResultInfo ErrorInfo,
36493646
auto ErrorResultSlot = getErrorResultSlot(IGM.silConv.getSILType(ErrorInfo));
36503647
auto Var = DbgValue->getVarInfo();
36513648
assert(Var && "error result without debug info");
3652-
auto Storage =
3653-
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), getDebugScope(),
3654-
Var->Name, Var->ArgNo, false);
3649+
auto Storage = emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(),
3650+
getDebugScope(), *Var, false);
36553651
if (!IGM.DebugInfo)
36563652
return;
36573653
auto DbgTy = DebugTypeInfo::getErrorResult(
36583654
ErrorInfo.getType(), ErrorResultSlot->getType(), IGM.getPointerSize(),
36593655
IGM.getPointerAlignment());
3660-
IGM.DebugInfo->emitVariableDeclaration(
3661-
Builder, Storage, DbgTy, getDebugScope(), nullptr, Var->Name, Var->ArgNo,
3662-
IndirectValue, ArtificialValue);
3656+
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, DbgTy,
3657+
getDebugScope(), nullptr, *Var,
3658+
IndirectValue, ArtificialValue);
36633659
}
36643660

36653661
void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
@@ -3680,30 +3676,30 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
36803676
}
36813677

36823678
bool IsAnonymous = false;
3683-
StringRef Name = getVarName(i, IsAnonymous);
3679+
VarInfo->Name = getVarName(i, IsAnonymous);
36843680
DebugTypeInfo DbgTy;
36853681
SILType SILTy = SILVal->getType();
36863682
auto RealTy = SILVal->getType().getASTType();
36873683
if (VarDecl *Decl = i->getDecl()) {
36883684
DbgTy = DebugTypeInfo::getLocalVariable(
36893685
Decl, RealTy, getTypeInfo(SILVal->getType()));
36903686
} else if (i->getFunction()->isBare() &&
3691-
!SILTy.hasArchetype() && !Name.empty()) {
3687+
!SILTy.hasArchetype() && !VarInfo->Name.empty()) {
36923688
// Preliminary support for .sil debug information.
36933689
DbgTy = DebugTypeInfo::getFromTypeInfo(RealTy, getTypeInfo(SILTy));
36943690
} else
36953691
return;
36963692

36973693
// Put the value into a stack slot at -Onone.
36983694
llvm::SmallVector<llvm::Value *, 8> Copy;
3699-
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), Name, VarInfo->ArgNo,
3700-
IsAnonymous, Copy);
3695+
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), *VarInfo, IsAnonymous,
3696+
Copy);
37013697
bindArchetypes(DbgTy.getType());
37023698
if (!IGM.DebugInfo)
37033699
return;
37043700

37053701
emitDebugVariableDeclaration(Copy, DbgTy, SILTy, i->getDebugScope(),
3706-
i->getDecl(), Name, VarInfo->ArgNo);
3702+
i->getDecl(), *VarInfo);
37073703
}
37083704

37093705
void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
@@ -3722,7 +3718,7 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
37223718
assert(VarInfo && "debug_value_addr without debug info");
37233719
bool IsAnonymous = false;
37243720
bool IsLoadablyByAddress = isa<AllocStackInst>(SILVal);
3725-
StringRef Name = getVarName(i, IsAnonymous);
3721+
VarInfo->Name = getVarName(i, IsAnonymous);
37263722
auto Addr = getLoweredAddress(SILVal).getAddress();
37273723
SILType SILTy = SILVal->getType();
37283724
auto RealType = SILTy.getASTType();
@@ -3736,9 +3732,8 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
37363732
// Put the value's address into a stack slot at -Onone and emit a debug
37373733
// intrinsic.
37383734
emitDebugVariableDeclaration(
3739-
emitShadowCopyIfNeeded(Addr, i->getDebugScope(), Name, VarInfo->ArgNo,
3740-
IsAnonymous),
3741-
DbgTy, SILType(), i->getDebugScope(), Decl, Name, VarInfo->ArgNo,
3735+
emitShadowCopyIfNeeded(Addr, i->getDebugScope(), *VarInfo, IsAnonymous),
3736+
DbgTy, SILType(), i->getDebugScope(), Decl, *VarInfo,
37423737
(IsLoadablyByAddress) ? DirectValue : IndirectValue);
37433738
}
37443739

@@ -4000,7 +3995,7 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
40003995
return;
40013996

40023997
bool IsAnonymous = false;
4003-
StringRef Name = getVarName(i, IsAnonymous);
3998+
VarInfo->Name = getVarName(i, IsAnonymous);
40043999

40054000
// At this point addr must be an alloca or an undef.
40064001
assert(isa<llvm::AllocaInst>(addr) || isa<llvm::UndefValue>(addr) ||
@@ -4011,8 +4006,7 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
40114006
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(addr))
40124007
if (!Alloca->isStaticAlloca()) {
40134008
// Store the address of the dynamic alloca on the stack.
4014-
addr = emitShadowCopy(addr, DS, Name, VarInfo->ArgNo,
4015-
IGM.getPointerAlignment());
4009+
addr = emitShadowCopy(addr, DS, *VarInfo, IGM.getPointerAlignment());
40164010
Indirection = IndirectValue;
40174011
}
40184012

@@ -4031,8 +4025,8 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
40314025

40324026
bindArchetypes(DbgTy.getType());
40334027
if (IGM.DebugInfo)
4034-
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, Name,
4035-
VarInfo->ArgNo, Indirection);
4028+
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, *VarInfo,
4029+
Indirection);
40364030
}
40374031

40384032
void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
@@ -4232,16 +4226,18 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
42324226
auto RealType = SILTy.getASTType();
42334227
auto DbgTy = DebugTypeInfo::getLocalVariable(Decl, RealType, type);
42344228

4229+
auto VarInfo = i->getVarInfo();
4230+
assert(VarInfo && "debug_value without debug info");
4231+
42354232
auto Storage = emitShadowCopyIfNeeded(
4236-
boxWithAddr.getAddress(), i->getDebugScope(), Name, 0, IsAnonymous);
4233+
boxWithAddr.getAddress(), i->getDebugScope(), *VarInfo, IsAnonymous);
42374234

42384235
if (!IGM.DebugInfo)
42394236
return;
42404237

4241-
IGM.DebugInfo->emitVariableDeclaration(
4242-
Builder,
4243-
Storage,
4244-
DbgTy, i->getDebugScope(), Decl, Name, 0, IndirectValue);
4238+
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, DbgTy,
4239+
i->getDebugScope(), Decl, *VarInfo,
4240+
IndirectValue);
42454241
}
42464242

42474243
void IRGenSILFunction::visitProjectBoxInst(swift::ProjectBoxInst *i) {

0 commit comments

Comments
 (0)