13
13
#ifndef SWIFT_SIL_SILBUILDER_H
14
14
#define SWIFT_SIL_SILBUILDER_H
15
15
16
+ #include " SILDebugVariable.h"
17
+ #include " SILInstruction.h"
16
18
#include " swift/Basic/ProfileCounter.h"
17
19
#include " swift/SIL/SILArgument.h"
18
20
#include " swift/SIL/SILDebugScope.h"
22
24
#include " swift/SIL/SILUndef.h"
23
25
#include " llvm/ADT/PointerUnion.h"
24
26
#include " llvm/ADT/StringExtras.h"
27
+ #include < type_traits>
25
28
26
29
namespace swift {
27
30
@@ -168,27 +171,33 @@ class SILBuilder {
168
171
// / location.
169
172
// /
170
173
// / SILBuilderContext must outlive this SILBuilder instance.
171
- SILBuilder (SILInstruction *I, const SILDebugScope *DS, SILBuilderContext &C)
174
+ SILBuilder (SILInstruction *I, SILBuilderContext &C,
175
+ const SILDebugScope *DS = nullptr )
172
176
: TempContext(C.getModule()), C(C), F(I->getFunction ()) {
173
- assert (DS && " instruction has no debug scope" );
174
- setCurrentDebugScope (DS);
175
177
setInsertionPoint (I);
178
+ if (DS)
179
+ setCurrentDebugScope (DS);
176
180
}
177
181
178
- SILBuilder (SILBasicBlock *BB, const SILDebugScope *DS, SILBuilder &B)
179
- : SILBuilder(BB, DS, B.getBuilderContext()) {}
182
+ SILBuilder (SILBasicBlock *BB, SILBuilder &B,
183
+ const SILDebugScope *DS = nullptr )
184
+ : SILBuilder(BB, B.getBuilderContext(), DS) {}
180
185
181
186
// / Build instructions before the given insertion point, inheriting the debug
182
187
// / location.
183
188
// /
184
189
// / SILBuilderContext must outlive this SILBuilder instance.
185
- SILBuilder (SILBasicBlock *BB, const SILDebugScope *DS, SILBuilderContext &C)
190
+ SILBuilder (SILBasicBlock *BB, SILBuilderContext &C,
191
+ const SILDebugScope *DS = nullptr )
186
192
: TempContext(C.getModule()), C(C), F(BB->getParent ()) {
187
193
assert (DS && " block has no debug scope" );
188
- setCurrentDebugScope (DS);
189
194
setInsertionPoint (BB);
195
+ if (DS)
196
+ setCurrentDebugScope (DS);
190
197
}
191
198
199
+ virtual ~SILBuilder () {}
200
+
192
201
// Allow a pass to override the current SIL module conventions. This should
193
202
// only be done by a pass responsible for lowering SIL to a new stage
194
203
// (e.g. AddressLowering).
@@ -238,7 +247,8 @@ class SILBuilder {
238
247
}
239
248
240
249
// / Convenience function for building a SILDebugLocation.
241
- SILDebugLocation getSILDebugLocation (SILLocation Loc) {
250
+ virtual SILDebugLocation
251
+ getSILDebugLocation (SILLocation Loc, bool ForMetaInstruction = false ) {
242
252
// FIXME: Audit all uses and enable this assertion.
243
253
// assert(getCurrentDebugScope() && "no debug scope");
244
254
auto Scope = getCurrentDebugScope ();
@@ -248,6 +258,17 @@ class SILBuilder {
248
258
return SILDebugLocation (overriddenLoc, Scope);
249
259
}
250
260
261
+ // / When the frontend generates synthesized conformances it generates a
262
+ // / fully-typechecked AST without source locations. This means that the
263
+ // / ASTScope-based mechanism to generate SILDebugScopes doesn't work, which
264
+ // / means we can't disambiguate local variables in different lexical
265
+ // / scopes. To avoid a verification error later in the pipeline, drop all
266
+ // / variables without a proper source location.
267
+ bool shouldDropVariable (SILDebugVariable Var, SILLocation Loc) {
268
+ return !Var.ArgNo && Loc.isSynthesizedAST ();
269
+ }
270
+
271
+
251
272
// / If we have a SILFunction, return SILFunction::hasOwnership(). If we have a
252
273
// / SILGlobalVariable, just return false.
253
274
bool hasOwnership () const {
@@ -369,7 +390,7 @@ class SILBuilder {
369
390
SILBasicBlock *createFallthroughBlock (SILLocation loc,
370
391
SILBasicBlock *targetBB) {
371
392
auto *newBB = F->createBasicBlock ();
372
- SILBuilder (newBB, this ->getCurrentDebugScope (), this ->getBuilderContext ())
393
+ SILBuilder (newBB, this ->getBuilderContext (), this ->getCurrentDebugScope ())
373
394
.createBranch (loc, targetBB);
374
395
return newBB;
375
396
}
@@ -382,6 +403,8 @@ class SILBuilder {
382
403
Optional<SILDebugVariable>
383
404
substituteAnonymousArgs (llvm::SmallString<4 > Name,
384
405
Optional<SILDebugVariable> Var, SILLocation Loc) {
406
+ if (Var && shouldDropVariable (*Var, Loc))
407
+ return {};
385
408
if (!Var || !Var->ArgNo || !Var->Name .empty ())
386
409
return Var;
387
410
@@ -397,14 +420,21 @@ class SILBuilder {
397
420
AllocStackInst *createAllocStack (SILLocation Loc, SILType elementType,
398
421
Optional<SILDebugVariable> Var = None,
399
422
bool hasDynamicLifetime = false ,
400
- bool isLexical = false ,
401
- bool wasMoved = false ) {
423
+ bool isLexical = false , bool wasMoved = false
424
+ #ifndef NDEBUG
425
+ ,
426
+ bool skipVarDeclAssert = false
427
+ #endif
428
+ ) {
402
429
llvm::SmallString<4 > Name;
403
430
Loc.markAsPrologue ();
404
- assert ((!dyn_cast_or_null<VarDecl>(Loc.getAsASTNode <Decl>()) || Var) &&
405
- " location is a VarDecl, but SILDebugVariable is empty" );
431
+ #ifndef NDEBUG
432
+ if (dyn_cast_or_null<VarDecl>(Loc.getAsASTNode <Decl>()))
433
+ assert ((skipVarDeclAssert || Loc.isSynthesizedAST () || Var) &&
434
+ " location is a VarDecl, but SILDebugVariable is empty" );
435
+ #endif
406
436
return insert (AllocStackInst::create (
407
- getSILDebugLocation (Loc), elementType, getFunction (),
437
+ getSILDebugLocation (Loc, true ), elementType, getFunction (),
408
438
substituteAnonymousArgs (Name, Var, Loc), hasDynamicLifetime, isLexical,
409
439
wasMoved));
410
440
}
@@ -455,15 +485,20 @@ class SILBuilder {
455
485
Optional<SILDebugVariable> Var = None,
456
486
bool hasDynamicLifetime = false ,
457
487
bool reflection = false ,
458
- bool usesMoveableValueDebugInfo = false ) {
488
+ bool usesMoveableValueDebugInfo = false
489
+ #ifndef NDEBUG
490
+ , bool skipVarDeclAssert = false
491
+ #endif
492
+ ) {
459
493
llvm::SmallString<4 > Name;
460
494
Loc.markAsPrologue ();
461
- assert ((!dyn_cast_or_null<VarDecl>(Loc.getAsASTNode <Decl>()) || Var) &&
495
+ assert ((skipVarDeclAssert ||
496
+ !dyn_cast_or_null<VarDecl>(Loc.getAsASTNode <Decl>()) || Var) &&
462
497
" location is a VarDecl, but SILDebugVariable is empty" );
463
- return insert (AllocBoxInst::create (getSILDebugLocation (Loc), BoxType, *F,
464
- substituteAnonymousArgs (Name, Var, Loc) ,
465
- hasDynamicLifetime, reflection,
466
- usesMoveableValueDebugInfo));
498
+ return insert (AllocBoxInst::create (
499
+ getSILDebugLocation (Loc, true ), BoxType, *F ,
500
+ substituteAnonymousArgs (Name, Var, Loc), hasDynamicLifetime, reflection,
501
+ usesMoveableValueDebugInfo));
467
502
}
468
503
469
504
AllocExistentialBoxInst *
@@ -2918,7 +2953,21 @@ class SILBuilder {
2918
2953
class SILBuilderWithScope : public SILBuilder {
2919
2954
void inheritScopeFrom (SILInstruction *I) {
2920
2955
assert (I->getDebugScope () && " instruction has no debug scope" );
2921
- setCurrentDebugScope (I->getDebugScope ());
2956
+ SILBasicBlock::iterator II (*I);
2957
+ auto End = I->getParent ()->end ();
2958
+ const SILDebugScope *DS = II->getDebugScope ();
2959
+ assert (DS);
2960
+ // Skip over meta instructions, since debug_values may originate from outer
2961
+ // scopes. Don't do any of this after inlining.
2962
+ while (!DS->InlinedCallSite && II != End && II->isMetaInstruction ())
2963
+ ++II;
2964
+ if (II != End) {
2965
+ auto nextScope = II->getDebugScope ();
2966
+ if (!nextScope->InlinedCallSite )
2967
+ DS = nextScope;
2968
+ }
2969
+ assert (DS);
2970
+ setCurrentDebugScope (DS);
2922
2971
}
2923
2972
2924
2973
public:
@@ -2927,29 +2976,33 @@ class SILBuilderWithScope : public SILBuilder {
2927
2976
// /
2928
2977
// / Clients should prefer this constructor.
2929
2978
SILBuilderWithScope (SILInstruction *I, SILBuilderContext &C)
2930
- : SILBuilder(I, I->getDebugScope (), C)
2931
- {}
2979
+ : SILBuilder(I, C) {
2980
+ inheritScopeFrom (I);
2981
+ }
2932
2982
2933
2983
// / Build instructions before the given insertion point, inheriting the debug
2934
2984
// / location and using the context from the passed in builder.
2935
2985
// /
2936
2986
// / Clients should prefer this constructor.
2937
2987
SILBuilderWithScope (SILInstruction *I, SILBuilder &B)
2938
- : SILBuilder(I, I->getDebugScope (), B.getBuilderContext()) {}
2988
+ : SILBuilder(I, B.getBuilderContext()) {
2989
+ inheritScopeFrom (I);
2990
+ }
2939
2991
2940
2992
explicit SILBuilderWithScope (
2941
2993
SILInstruction *I,
2942
2994
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr )
2943
2995
: SILBuilder(I, InsertedInstrs) {
2944
- assert (I->getDebugScope () && " instruction has no debug scope" );
2945
- setCurrentDebugScope (I->getDebugScope ());
2996
+ inheritScopeFrom (I);
2946
2997
}
2947
2998
2948
2999
explicit SILBuilderWithScope (SILBasicBlock::iterator I)
2949
3000
: SILBuilderWithScope(&*I) {}
2950
3001
2951
3002
explicit SILBuilderWithScope (SILBasicBlock::iterator I, SILBuilder &B)
2952
- : SILBuilder(&*I, &*I->getDebugScope (), B.getBuilderContext()) {}
3003
+ : SILBuilder(&*I, B.getBuilderContext()) {
3004
+ inheritScopeFrom (&*I);
3005
+ }
2953
3006
2954
3007
explicit SILBuilderWithScope (SILInstruction *I,
2955
3008
SILInstruction *InheritScopeFrom)
@@ -2971,12 +3024,13 @@ class SILBuilderWithScope : public SILBuilder {
2971
3024
2972
3025
explicit SILBuilderWithScope (SILBasicBlock *BB, SILBuilder &B,
2973
3026
SILInstruction *InheritScopeFrom)
2974
- : SILBuilder(BB, InheritScopeFrom->getDebugScope (),
2975
- B.getBuilderContext()) {}
3027
+ : SILBuilder(BB, B.getBuilderContext()) {
3028
+ inheritScopeFrom (InheritScopeFrom);
3029
+ }
2976
3030
2977
3031
explicit SILBuilderWithScope (SILBasicBlock *BB, SILBuilderContext &C,
2978
3032
const SILDebugScope *debugScope)
2979
- : SILBuilder(BB, debugScope, C ) {}
3033
+ : SILBuilder(BB, C, debugScope ) {}
2980
3034
2981
3035
// / Creates a new SILBuilder with an insertion point at the
2982
3036
// / beginning of BB and the debug scope from the first
0 commit comments