Use the debugger hook, `reportToDebugger`, for all calls to _swift_stdlib_reportFatalError[InFile].  Only do this when a hidden frontend flag, `-report-errors-to-debugger`, is used. (#10617) (#10703)

diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 5a64126..ef88835 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -185,6 +185,9 @@
     /// accesses.
     bool DisableTsanInoutInstrumentation = false;
 
+    /// \brief Staging flag for reporting runtime issues to the debugger.
+    bool ReportErrorsToDebugger = false;
+
     /// \brief Staging flag for class resilience, which we do not want to enable
     /// fully until more code is in place, to allow the standard library to be
     /// tested with value type resilience only.
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 62926fe..4bc4968 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -294,6 +294,9 @@
   "disable-tsan-inout-instrumentation">,
   HelpText<"Disable treatment of inout parameters as Thread Sanitizer accesses">;
 
+def report_errors_to_debugger : Flag<["-"], "report-errors-to-debugger">,
+  HelpText<"Invoke the debugger hook on fatalError calls">;
+
 def enable_infer_import_as_member :
   Flag<["-"], "enable-infer-import-as-member">,
   HelpText<"Infer when a global could be imported as a member">;
diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h
index 7512d1a..3e67edb 100644
--- a/include/swift/Runtime/Debug.h
+++ b/include/swift/Runtime/Debug.h
@@ -210,6 +210,9 @@
 void reportToDebugger(uintptr_t flags, const char *message,
                       RuntimeErrorDetails *details = nullptr);
 
+SWIFT_RUNTIME_EXPORT
+bool _swift_reportFatalErrorsToDebugger;
+
 // namespace swift
 }
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 6966f96..1763da2 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -964,6 +964,9 @@
   Opts.DisableTsanInoutInstrumentation |=
       Args.hasArg(OPT_disable_tsan_inout_instrumentation);
 
+  Opts.ReportErrorsToDebugger |=
+      Args.hasArg(OPT_report_errors_to_debugger);
+
   if (FrontendOpts.InputKind == InputFileKind::IFK_SIL)
     Opts.DisableAvailabilityChecking = true;
   
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index a073dce..b3c22cd 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -44,6 +44,7 @@
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MD5.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
 
 #include "GenEnum.h"
 #include "GenType.h"
@@ -1042,6 +1043,31 @@
   }
 }
 
+void IRGenModule::emitEnableReportErrorsToDebugger() {
+  if (!Context.LangOpts.ReportErrorsToDebugger)
+    return;
+
+  if (!getSwiftModule()->hasEntryPoint())
+    return;
+
+  llvm::Function *NewFn = llvm::Function::Create(
+      llvm::FunctionType::get(VoidTy, false), llvm::GlobalValue::PrivateLinkage,
+      "_swift_enable_report_errors_to_debugger");
+  IRGenFunction NewIGF(*this, NewFn);
+  NewFn->setAttributes(constructInitialAttributes());
+  Module.getFunctionList().push_back(NewFn);
+  NewFn->setCallingConv(DefaultCC);
+
+  llvm::Value *addr =
+      Module.getOrInsertGlobal("_swift_reportFatalErrorsToDebugger", Int1Ty);
+  llvm::Value *one = llvm::ConstantInt::get(Int1Ty, 1);
+
+  NewIGF.Builder.CreateStore(one, addr, Alignment(1));
+  NewIGF.Builder.CreateRetVoid();
+
+  llvm::appendToGlobalCtors(Module, NewFn, 0, nullptr);
+}
+
 void IRGenModule::cleanupClangCodeGenMetadata() {
   // Remove llvm.ident that ClangCodeGen might have left in the module.
   auto *LLVMIdent = Module.getNamedMetadata("llvm.ident");
@@ -1110,6 +1136,7 @@
     return false;
 
   emitAutolinkInfo();
+  emitEnableReportErrorsToDebugger();
   emitGlobalLists();
   if (DebugInfo)
     DebugInfo->finalize();
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index d8bd0d8..34e154a 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -792,6 +792,7 @@
 
   void emitGlobalLists();
   void emitAutolinkInfo();
+  void emitEnableReportErrorsToDebugger();
   void cleanupClangCodeGenMetadata();
 
 //--- Remote reflection metadata --------------------------------------------
diff --git a/stdlib/public/stubs/Assert.cpp b/stdlib/public/stubs/Assert.cpp
index 69fa5ca..39c9b74 100644
--- a/stdlib/public/stubs/Assert.cpp
+++ b/stdlib/public/stubs/Assert.cpp
@@ -21,6 +21,8 @@
 
 using namespace swift;
 
+bool swift::_swift_reportFatalErrorsToDebugger = false;
+
 static int swift_asprintf(char **strp, const char *fmt, ...) {
   va_list args;
   va_start(args, fmt);
@@ -49,6 +51,24 @@
   return result;
 }
 
+static void logPrefixAndMessageToDebugger(
+    const unsigned char *prefix, int prefixLength,
+    const unsigned char *message, int messageLength
+) {
+  if (!_swift_reportFatalErrorsToDebugger)
+    return;
+
+  char *debuggerMessage;
+  if (messageLength) {
+    swift_asprintf(&debuggerMessage, "%.*s: %.*s", prefixLength, prefix,
+        messageLength, message);
+  } else {
+    swift_asprintf(&debuggerMessage, "%.*s", prefixLength, prefix);
+  }
+  reportToDebugger(RuntimeErrorFlagFatal, debuggerMessage);
+  free(debuggerMessage);
+}
+
 void swift::_swift_stdlib_reportFatalErrorInFile(
     const unsigned char *prefix, int prefixLength,
     const unsigned char *message, int messageLength,
@@ -56,6 +76,8 @@
     uint32_t line,
     uint32_t flags
 ) {
+  logPrefixAndMessageToDebugger(prefix, prefixLength, message, messageLength);
+
   char *log;
   swift_asprintf(
       &log, "%.*s: %.*s%sfile %.*s, line %" PRIu32 "\n",
@@ -74,6 +96,8 @@
     const unsigned char *message, int messageLength,
     uint32_t flags
 ) {
+  logPrefixAndMessageToDebugger(prefix, prefixLength, message, messageLength);
+
   char *log;
   swift_asprintf(
       &log, "%.*s: %.*s\n",