28
28
using namespace swift ;
29
29
using namespace OptRemark ;
30
30
31
- Argument::Argument (StringRef key, int n) : key(key), val(llvm::itostr(n)) {}
31
+ Argument::Argument (StringRef key, int n)
32
+ : key(ArgumentKeyKind::Default, key), val(llvm::itostr(n)) {}
32
33
33
- Argument::Argument (StringRef key, long n) : key(key), val(llvm::itostr(n)) {}
34
+ Argument::Argument (StringRef key, long n)
35
+ : key(ArgumentKeyKind::Default, key), val(llvm::itostr(n)) {}
34
36
35
37
Argument::Argument (StringRef key, long long n)
36
- : key(key), val(llvm::itostr(n)) {}
38
+ : key(ArgumentKeyKind::Default, key), val(llvm::itostr(n)) {}
37
39
38
40
Argument::Argument (StringRef key, unsigned n)
39
- : key(key), val(llvm::utostr(n)) {}
41
+ : key(ArgumentKeyKind::Default, key), val(llvm::utostr(n)) {}
40
42
41
43
Argument::Argument (StringRef key, unsigned long n)
42
- : key(key), val(llvm::utostr(n)) {}
44
+ : key(ArgumentKeyKind::Default, key), val(llvm::utostr(n)) {}
43
45
44
46
Argument::Argument (StringRef key, unsigned long long n)
45
- : key(key), val(llvm::utostr(n)) {}
47
+ : key(ArgumentKeyKind::Default, key), val(llvm::utostr(n)) {}
46
48
47
- Argument::Argument (StringRef key, SILFunction *f) : key(key) {
49
+ Argument::Argument (ArgumentKey key, SILFunction *f) : key(key) {
48
50
auto options = Demangle::DemangleOptions::SimplifiedUIDemangleOptions ();
49
51
// Enable module names so that we have a way of filtering out
50
52
// stdlib-related remarks.
@@ -58,12 +60,14 @@ Argument::Argument(StringRef key, SILFunction *f) : key(key) {
58
60
loc = f->getLocation ().getSourceLoc ();
59
61
}
60
62
61
- Argument::Argument (StringRef key, SILType ty) : key(key) {
63
+ Argument::Argument (StringRef key, SILType ty)
64
+ : key(ArgumentKeyKind::Default, key) {
62
65
llvm::raw_string_ostream stream (val);
63
66
ty.print (stream);
64
67
}
65
68
66
- Argument::Argument (StringRef key, CanType ty) : key(key) {
69
+ Argument::Argument (StringRef key, CanType ty)
70
+ : key(ArgumentKeyKind::Default, key) {
67
71
llvm::raw_string_ostream stream (val);
68
72
ty.print (stream);
69
73
}
@@ -72,8 +76,15 @@ template <typename DerivedT>
72
76
std::string Remark<DerivedT>::getMsg() const {
73
77
std::string str;
74
78
llvm::raw_string_ostream stream (str);
75
- for (const Argument &arg : args)
79
+ // Go through our args and if we are not emitting for diagnostics *OR* we are
80
+ // emitting for diagnostics and this argument is not intended to be emitted as
81
+ // a diagnostic separate from our main remark, emit the arg value here.
82
+ for (const Argument &arg : args) {
83
+ if (arg.key .kind .isSeparateDiagnostic ())
84
+ continue ;
76
85
stream << arg.val ;
86
+ }
87
+
77
88
return stream.str ();
78
89
}
79
90
@@ -194,9 +205,27 @@ static void emitRemark(SILModule &module, const Remark<RemarkT> &remark,
194
205
return ;
195
206
if (auto *remarkStreamer = module .getSILRemarkStreamer ())
196
207
remarkStreamer->emit (remark);
197
- if (diagEnabled)
198
- module .getASTContext ().Diags .diagnose (remark.getLocation (), id,
199
- remark.getMsg ());
208
+
209
+ // If diagnostics are enabled, first emit the main diagnostic and then loop
210
+ // through our arguments and allow the arguments to add additional diagnostics
211
+ // if they want.
212
+ if (diagEnabled) {
213
+ auto &Diags = module .getASTContext ().Diags ;
214
+ Diags.diagnose (remark.getLocation (), id,
215
+ remark.getMsg ());
216
+ for (auto &arg : remark.getArgs ()) {
217
+ switch (arg.key .kind ) {
218
+ case ArgumentKeyKind::Default:
219
+ continue ;
220
+ case ArgumentKeyKind::Note:
221
+ Diags.diagnose (arg.loc , diag::opt_remark_note,
222
+ arg.key .data );
223
+ continue ;
224
+ }
225
+
226
+ llvm_unreachable (" Unhandled case?!" );
227
+ }
228
+ }
200
229
}
201
230
202
231
void Emitter::emit (const RemarkPassed &remark) {
0 commit comments