@@ -59,30 +59,76 @@ static void diagnose(ASTContext &context, SILInstruction *inst, Diag<T...> diag,
59
59
context.Diags .diagnose (loc.getSourceLoc (), diag, std::forward<U>(args)...);
60
60
}
61
61
62
- static StringRef getVariableNameForValue (MarkMustCheckInst *mmci) {
63
- if ( auto *allocInst = dyn_cast<AllocationInst>(mmci-> getOperand ()) ) {
64
- DebugVarCarryingInst debugVar (allocInst);
65
- if ( auto varInfo = debugVar. getVarInfo ()) {
66
- return varInfo-> Name ;
67
- } else {
68
- if ( auto *decl = debugVar.getDecl ()) {
69
- return decl-> getBaseName (). userFacingName ();
70
- }
62
+ static void getVariableNameForValue (MarkMustCheckInst *mmci,
63
+ SmallString< 64 > &resultingString ) {
64
+ // Before we do anything, lets see if we have an exact debug_value on our
65
+ // mmci. In such a case, we can end early and are done.
66
+ if ( auto *use = getSingleDebugUse (mmci)) {
67
+ if ( auto debugVar = DebugVarCarryingInst (use-> getUser ())) {
68
+ assert ( debugVar.getKind () == DebugVarCarryingInst::Kind::DebugValue);
69
+ resultingString += debugVar. getName ();
70
+ return ;
71
71
}
72
72
}
73
73
74
- if (auto *use = getSingleDebugUse (mmci)) {
75
- DebugVarCarryingInst debugVar (use->getUser ());
76
- if (auto varInfo = debugVar.getVarInfo ()) {
77
- return varInfo->Name ;
78
- } else {
79
- if (auto *decl = debugVar.getDecl ()) {
80
- return decl->getBaseName ().userFacingName ();
74
+ // Otherwise, we need to look at our mark_must_check's operand.
75
+ StackList<SILInstruction *> variableNamePath (mmci->getFunction ());
76
+ SILValue value = mmci->getOperand ();
77
+ while (true ) {
78
+ if (auto *allocInst = dyn_cast<AllocationInst>(value)) {
79
+ variableNamePath.push_back (allocInst);
80
+ break ;
81
+ }
82
+
83
+ if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(value)) {
84
+ variableNamePath.push_back (globalAddrInst);
85
+ break ;
86
+ }
87
+
88
+ if (auto *rei = dyn_cast<RefElementAddrInst>(value)) {
89
+ variableNamePath.push_back (rei);
90
+ value = rei->getOperand ();
91
+ continue ;
92
+ }
93
+
94
+ // Single value instructions we should look through.
95
+ if (isa<BeginBorrowInst>(value) || isa<LoadInst>(value) ||
96
+ isa<BeginAccessInst>(value) || isa<MarkMustCheckInst>(value)) {
97
+ value = cast<SingleValueInstruction>(value)->getOperand (0 );
98
+ continue ;
99
+ }
100
+
101
+ // If we do not do an exact match, see if we can find a debug_var inst. If
102
+ // we do, we always break since we have a root value.
103
+ if (auto *use = getSingleDebugUse (value)) {
104
+ if (auto debugVar = DebugVarCarryingInst (use->getUser ())) {
105
+ assert (debugVar.getKind () == DebugVarCarryingInst::Kind::DebugValue);
106
+ variableNamePath.push_back (use->getUser ());
107
+ break ;
81
108
}
82
109
}
110
+
111
+ // If we do not pattern match successfully, just set resulting string to
112
+ // unknown and return early.
113
+ resultingString += " unknown" ;
114
+ return ;
83
115
}
84
116
85
- return " unknown" ;
117
+ // Walk backwards, constructing our string.
118
+ while (true ) {
119
+ auto *next = variableNamePath.pop_back_val ();
120
+
121
+ if (auto i = DebugVarCarryingInst (next)) {
122
+ resultingString += i.getName ();
123
+ } else if (auto i = VarDeclCarryingInst (next)) {
124
+ resultingString += i.getName ();
125
+ }
126
+
127
+ if (variableNamePath.empty ())
128
+ return ;
129
+
130
+ resultingString += ' .' ;
131
+ }
86
132
}
87
133
88
134
// ===----------------------------------------------------------------------===//
@@ -113,7 +159,8 @@ void DiagnosticEmitter::emitCheckerDoesntUnderstandDiagnostic(
113
159
void DiagnosticEmitter::emitObjectGuaranteedDiagnostic (
114
160
MarkMustCheckInst *markedValue) {
115
161
auto &astContext = fn->getASTContext ();
116
- StringRef varName = getVariableNameForValue (markedValue);
162
+ SmallString<64 > varName;
163
+ getVariableNameForValue (markedValue, varName);
117
164
118
165
// See if we have any closure capture uses and emit a better diagnostic.
119
166
if (getCanonicalizer ().hasPartialApplyConsumingUse ()) {
@@ -153,7 +200,8 @@ void DiagnosticEmitter::emitObjectGuaranteedDiagnostic(
153
200
void DiagnosticEmitter::emitObjectOwnedDiagnostic (
154
201
MarkMustCheckInst *markedValue) {
155
202
auto &astContext = fn->getASTContext ();
156
- StringRef varName = getVariableNameForValue (markedValue);
203
+ SmallString<64 > varName;
204
+ getVariableNameForValue (markedValue, varName);
157
205
158
206
// Ok we know that we are going to emit an error. Lets use a little more
159
207
// compile time to emit a nice error.
@@ -323,7 +371,8 @@ void DiagnosticEmitter::emitAddressExclusivityHazardDiagnostic(
323
371
registerDiagnosticEmitted (markedValue);
324
372
325
373
auto &astContext = markedValue->getFunction ()->getASTContext ();
326
- StringRef varName = getVariableNameForValue (markedValue);
374
+ SmallString<64 > varName;
375
+ getVariableNameForValue (markedValue, varName);
327
376
328
377
LLVM_DEBUG (llvm::dbgs () << " Emitting error for exclusivity!\n " );
329
378
LLVM_DEBUG (llvm::dbgs () << " Mark: " << *markedValue);
@@ -345,7 +394,8 @@ void DiagnosticEmitter::emitAddressDiagnostic(MarkMustCheckInst *markedValue,
345
394
registerDiagnosticEmitted (markedValue);
346
395
347
396
auto &astContext = markedValue->getFunction ()->getASTContext ();
348
- StringRef varName = getVariableNameForValue (markedValue);
397
+ SmallString<64 > varName;
398
+ getVariableNameForValue (markedValue, varName);
349
399
350
400
LLVM_DEBUG (llvm::dbgs () << " Emitting error!\n " );
351
401
LLVM_DEBUG (llvm::dbgs () << " Mark: " << *markedValue);
@@ -434,7 +484,8 @@ void DiagnosticEmitter::emitInOutEndOfFunctionDiagnostic(
434
484
" Expected markedValue to be on an inout" );
435
485
436
486
auto &astContext = markedValue->getFunction ()->getASTContext ();
437
- StringRef varName = getVariableNameForValue (markedValue);
487
+ SmallString<64 > varName;
488
+ getVariableNameForValue (markedValue, varName);
438
489
439
490
LLVM_DEBUG (llvm::dbgs () << " Emitting inout error error!\n " );
440
491
LLVM_DEBUG (llvm::dbgs () << " Mark: " << *markedValue);
@@ -468,7 +519,8 @@ void DiagnosticEmitter::emitAddressDiagnosticNoCopy(
468
519
return ;
469
520
470
521
auto &astContext = markedValue->getFunction ()->getASTContext ();
471
- StringRef varName = getVariableNameForValue (markedValue);
522
+ SmallString<64 > varName;
523
+ getVariableNameForValue (markedValue, varName);
472
524
473
525
LLVM_DEBUG (llvm::dbgs () << " Emitting no copy error!\n " );
474
526
LLVM_DEBUG (llvm::dbgs () << " Mark: " << *markedValue);
@@ -491,7 +543,8 @@ void DiagnosticEmitter::emitObjectDestructureNeededWithinBorrowBoundary(
491
543
return ;
492
544
493
545
auto &astContext = markedValue->getFunction ()->getASTContext ();
494
- StringRef varName = getVariableNameForValue (markedValue);
546
+ SmallString<64 > varName;
547
+ getVariableNameForValue (markedValue, varName);
495
548
496
549
LLVM_DEBUG (llvm::dbgs () << " Emitting destructure can't be created error!\n " );
497
550
LLVM_DEBUG (llvm::dbgs () << " Mark: " << *markedValue);
@@ -531,7 +584,8 @@ void DiagnosticEmitter::emitObjectInstConsumesValueTwice(
531
584
<< secondUse->getOperandNumber () << ' \n ' );
532
585
533
586
auto &astContext = markedValue->getModule ().getASTContext ();
534
- StringRef varName = getVariableNameForValue (markedValue);
587
+ SmallString<64 > varName;
588
+ getVariableNameForValue (markedValue, varName);
535
589
diagnose (astContext, markedValue,
536
590
diag::sil_moveonlychecker_owned_value_consumed_more_than_once,
537
591
varName);
@@ -556,7 +610,8 @@ void DiagnosticEmitter::emitObjectInstConsumesAndUsesValue(
556
610
<< nonConsumingUse->getOperandNumber () << ' \n ' );
557
611
558
612
auto &astContext = markedValue->getModule ().getASTContext ();
559
- StringRef varName = getVariableNameForValue (markedValue);
613
+ SmallString<64 > varName;
614
+ getVariableNameForValue (markedValue, varName);
560
615
diagnose (astContext, markedValue,
561
616
diag::sil_moveonlychecker_owned_value_consumed_and_used_at_same_time,
562
617
varName);
0 commit comments