@@ -152,16 +152,52 @@ class StoringDiagnosticConsumer : public swift::DiagnosticConsumer {
152
152
// FXIME: This is a heuristic.
153
153
uint16_t len = info.Ranges .size () ? info.Ranges .front ().getByteLength () : 0 ;
154
154
bool in_user_input = false ;
155
- // FIXME: improve this!
156
- if (buffer_name == " <REPL>" || buffer_name == " <EXPR>" ||
157
- buffer_name == " repl.swift" ||
158
- buffer_name.starts_with (" <user expression" ))
159
- in_user_input = true ;
155
+ bool hidden = false ;
156
+ [&]() {
157
+ if (buffer_name == " repl.swift" ) {
158
+ in_user_input = true ;
159
+ return ;
160
+ }
161
+ if (buffer_name != " <REPL>" && buffer_name != " <EXPR>" &&
162
+ !buffer_name.starts_with (" <user expression" ))
163
+ return ;
164
+
165
+ unsigned buffer_id = source_mgr.findBufferContainingLoc (info.Loc );
166
+ llvm::SourceMgr &src_mgr = source_mgr.getLLVMSourceMgr ();
167
+ auto *buffer = src_mgr.getMemoryBuffer (buffer_id);
168
+ if (!buffer)
169
+ return ;
170
+
171
+ // Clang uses the much more elegant #line mechanism to find the
172
+ // user code, but doing this here could interfere with
173
+ // ExprOptions.PoundLineLine mechanism used Swift
174
+ // Playgrounds. So instead we find the markers from both ends.
175
+ StringRef buffer_data = buffer->getBuffer ();
176
+ size_t pos = buffer_data.find (" __LLDB_USER_START__" );
177
+ if (pos == StringRef::npos)
178
+ return ;
179
+ auto start_loc =
180
+ llvm::SMLoc::getFromPointer (buffer->getBufferStart () + pos);
181
+ unsigned start_line = src_mgr.FindLineNumber (start_loc, buffer_id);
182
+
183
+ pos = buffer_data.rfind (" __LLDB_USER_END__" );
184
+ if (pos == StringRef::npos)
185
+ return ;
186
+ auto end_loc =
187
+ llvm::SMLoc::getFromPointer (buffer->getBufferStart () + pos);
188
+ unsigned end_line = src_mgr.FindLineNumber (end_loc, buffer_id);
189
+
190
+ unsigned diag_line =
191
+ source_mgr.getLineAndColumnInBuffer (info.Loc , buffer_id).first ;
192
+
193
+ in_user_input = start_line < diag_line && diag_line < end_line;
194
+ hidden = !in_user_input;
195
+ }();
160
196
DiagnosticDetail::SourceLocation loc = {FileSpec{buffer_name.str ()},
161
197
line_col.first ,
162
198
(uint16_t )line_col.second ,
163
199
len,
164
- !in_user_input ,
200
+ hidden ,
165
201
in_user_input};
166
202
DiagnosticDetail detail = {loc, severity, raw_text, formatted_text};
167
203
RawDiagnostic diagnostic (
0 commit comments