@@ -152,16 +152,52 @@ class StoringDiagnosticConsumer : public swift::DiagnosticConsumer {
152152 // FXIME: This is a heuristic.
153153 uint16_t len = info.Ranges .size () ? info.Ranges .front ().getByteLength () : 0 ;
154154 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+ }();
160196 DiagnosticDetail::SourceLocation loc = {FileSpec{buffer_name.str ()},
161197 line_col.first ,
162198 (uint16_t )line_col.second ,
163199 len,
164- !in_user_input ,
200+ hidden ,
165201 in_user_input};
166202 DiagnosticDetail detail = {loc, severity, raw_text, formatted_text};
167203 RawDiagnostic diagnostic (
0 commit comments