[clang] [clang-tools-extra] Remove delayed typo expressions (PR #143423)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 10 05:56:04 PDT 2025


https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/143423

>From fd7cd1dfd8f98f4f9e68ec7b21a8954c72088e10 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Fri, 30 May 2025 12:24:35 -0400
Subject: [PATCH 01/11] Disable delayed typo correction by default

---
 clang/include/clang/Basic/LangOptions.def     |  6 ++
 clang/include/clang/Driver/Options.td         |  3 +
 clang/lib/Parse/ParseOpenMP.cpp               |  8 ++-
 clang/lib/Sema/SemaLookup.cpp                 |  3 +
 clang/test/AST/ast-dump-recovery.c            |  2 +-
 clang/test/AST/ast-dump-recovery.cpp          |  4 +-
 clang/test/AST/ast-dump-recovery.m            |  2 +-
 .../test/CXX/class.access/class.friend/p1.cpp | 16 ++---
 clang/test/CXX/class.access/p6.cpp            |  4 +-
 .../basic.namespace/namespace.def/p8.cpp      |  8 +--
 clang/test/CXX/drs/cwg14xx.cpp                |  6 +-
 clang/test/CXX/drs/cwg1xx.cpp                 |  7 +-
 clang/test/CXX/drs/cwg26xx.cpp                |  1 -
 clang/test/CXX/drs/cwg2xx.cpp                 |  3 +-
 .../test/CXX/module/basic/basic.link/p2.cppm  |  2 +-
 clang/test/CXX/module/module.interface/p2.cpp | 12 ++--
 .../temp.class/temp.mem.enum/p1.cpp           |  6 +-
 clang/test/FixIt/fixit-unicode.c              |  4 +-
 clang/test/FixIt/fixit.c                      |  4 +-
 clang/test/FixIt/typo-location-bugs.cpp       |  4 +-
 clang/test/FixIt/typo.cpp                     |  4 +-
 clang/test/Index/complete-switch.c            |  2 +-
 clang/test/Index/fix-its.c                    |  2 +-
 clang/test/Lexer/raw-string-ext.c             | 10 +--
 clang/test/Misc/serialized-diags.m            |  2 +-
 clang/test/Modules/auto-module-import.m       |  9 ++-
 .../crash-typo-correction-visibility.cpp      |  4 +-
 clang/test/Modules/cxx-templates.cpp          |  2 +-
 clang/test/Modules/diagnose-missing-import.m  |  2 +-
 clang/test/Modules/normal-module-map.cpp      |  7 +-
 clang/test/Modules/subframeworks.m            |  3 +-
 clang/test/Modules/submodule-visibility.cpp   |  7 +-
 clang/test/Modules/submodules-merge-defs.cpp  |  7 +-
 clang/test/Modules/suggest-include.cpp        |  2 +-
 .../OpenMP/begin_declare_variant_messages.c   |  2 +-
 .../OpenMP/declare_reduction_messages.cpp     |  2 +-
 clang/test/OpenMP/declare_variant_messages.c  |  6 +-
 .../test/OpenMP/declare_variant_messages.cpp  |  4 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 .../distribute_simd_linear_messages.cpp       |  6 +-
 clang/test/OpenMP/for_linear_messages.cpp     |  4 +-
 .../test/OpenMP/for_simd_linear_messages.cpp  |  4 +-
 .../masked_taskloop_simd_linear_messages.cpp  |  4 +-
 .../master_taskloop_simd_linear_messages.cpp  |  4 +-
 .../OpenMP/parallel_for_linear_messages.cpp   |  4 +-
 .../parallel_for_simd_linear_messages.cpp     |  4 +-
 ...l_masked_taskloop_simd_linear_messages.cpp |  4 +-
 ...l_master_taskloop_simd_linear_messages.cpp |  4 +-
 clang/test/OpenMP/simd_linear_messages.cpp    |  4 +-
 clang/test/OpenMP/target_map_messages.cpp     |  8 +--
 .../target_parallel_for_linear_messages.cpp   |  4 +-
 ...rget_parallel_for_simd_linear_messages.cpp |  4 +-
 .../OpenMP/target_simd_linear_messages.cpp    |  4 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 ..._teams_distribute_simd_linear_messages.cpp |  4 +-
 clang/test/OpenMP/target_update_messages.cpp  | 15 ++--
 .../OpenMP/taskloop_simd_linear_messages.cpp  |  4 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 .../teams_distribute_simd_linear_messages.cpp |  4 +-
 clang/test/PCH/race-condition.cpp             |  6 +-
 clang/test/Parser/cxx-invalid-for-range.cpp   |  4 +-
 clang/test/Parser/cxx1z-fold-expressions.cpp  |  6 +-
 clang/test/Parser/cxx2c-pack-indexing.cpp     |  3 +-
 clang/test/Parser/objc-foreach-syntax.m       |  3 +-
 clang/test/Parser/opencl-atomics-cl20.cl      | 18 ++---
 clang/test/Parser/recovery.c                  | 12 ++--
 clang/test/Parser/switch-recovery.cpp         |  4 +-
 clang/test/Parser/switch-typo-correction.cpp  |  2 +-
 .../ParserOpenACC/parse-cache-construct.cpp   | 10 +--
 clang/test/ParserOpenACC/parse-clauses.c      | 24 ++-----
 clang/test/ParserOpenACC/parse-constructs.cpp | 12 ++--
 clang/test/ParserOpenACC/parse-sub-array.cpp  |  5 +-
 clang/test/ParserOpenACC/parse-wait-clause.c  |  5 +-
 .../test/ParserOpenACC/parse-wait-construct.c |  9 +--
 clang/test/Sema/PR28181.c                     |  8 +--
 clang/test/Sema/builtin-unary-fp.c            |  1 -
 .../c23-delayed-typo-correction-crashes.c     | 18 +++++
 .../Sema/delayed-typo-correction-crashes.c    | 30 ++++++++
 clang/test/Sema/invalid-member.cpp            |  6 +-
 clang/test/Sema/typo-correction-ambiguity.c   |  2 +-
 clang/test/Sema/typo-correction-ambiguity.cpp |  2 +-
 clang/test/Sema/typo-correction-no-hang.c     |  2 +-
 clang/test/Sema/typo-correction-no-hang.cpp   |  2 +-
 clang/test/Sema/typo-correction-recursive.cpp |  2 +-
 clang/test/Sema/typo-correction.c             |  2 +-
 clang/test/Sema/var-redecl.c                  |  5 +-
 clang/test/SemaCXX/arrow-operator.cpp         | 11 ++-
 .../SemaCXX/constant-expression-cxx11.cpp     |  7 +-
 clang/test/SemaCXX/coroutines.cpp             | 20 ++----
 .../cxx-delayed-typo-correction-crashes.cpp   | 66 +++++++++++++++++
 clang/test/SemaCXX/cxx11-crashes.cpp          |  2 +-
 clang/test/SemaCXX/cxx1y-init-captures.cpp    | 70 +++++++++----------
 .../cxx20-delayed-typo-correction-crashes.cpp | 19 +++++
 .../SemaCXX/cxx2a-adl-only-template-id.cpp    |  8 +--
 clang/test/SemaCXX/destructor.cpp             | 23 +++---
 clang/test/SemaCXX/invalid-if-constexpr.cpp   | 10 +--
 clang/test/SemaCXX/lambda-expressions.cpp     |  5 +-
 clang/test/SemaCXX/member-expr.cpp            |  8 +--
 ...g-namespace-qualifier-typo-corrections.cpp |  2 +-
 clang/test/SemaCXX/nested-name-spec.cpp       | 14 ++--
 .../test/SemaCXX/pr13394-crash-on-invalid.cpp |  5 +-
 clang/test/SemaCXX/qualified-id-lookup.cpp    | 16 ++---
 clang/test/SemaCXX/return.cpp                 |  6 +-
 clang/test/SemaCXX/typo-correction-blocks.c   |  2 +-
 clang/test/SemaCXX/typo-correction-crash.cpp  |  2 +-
 clang/test/SemaCXX/typo-correction-cxx11.cpp  |  2 +-
 .../test/SemaCXX/typo-correction-delayed.cpp  |  6 +-
 clang/test/SemaCXX/typo-correction.cpp        |  4 +-
 clang/test/SemaCXX/virtuals.cpp               |  4 +-
 clang/test/SemaObjC/call-super-2.m            |  4 +-
 clang/test/SemaObjC/default-synthesize-2.m    |  2 +-
 .../SemaObjC/error-outof-scope-property-use.m |  7 +-
 clang/test/SemaObjC/objc-array-literal.m      |  6 +-
 clang/test/SemaObjC/objc-dictionary-literal.m |  6 +-
 clang/test/SemaObjC/super.m                   |  2 +-
 clang/test/SemaObjC/synth-provisional-ivars.m |  2 +-
 clang/test/SemaObjC/typo-correction-arc.m     |  2 +-
 .../test/SemaObjC/typo-correction-subscript.m |  2 +-
 clang/test/SemaObjC/typo-correction.m         |  2 +-
 .../SemaObjC/undef-arg-super-method-call.m    |  8 +--
 clang/test/SemaObjCXX/typo-correction.mm      |  2 +-
 .../compute-construct-num_gangs-clause.cpp    |  6 +-
 clang/test/SemaOpenCL/atomic-ops.cl           |  1 -
 .../test/SemaOpenCL/clang-builtin-version.cl  |  8 +--
 .../SemaTemplate/concepts-recovery-expr.cpp   |  2 +-
 clang/test/SemaTemplate/concepts.cpp          |  6 +-
 .../SemaTemplate/dependent-typos-recovery.cpp |  2 +-
 clang/test/SemaTemplate/typo-variadic.cpp     |  2 +-
 128 files changed, 476 insertions(+), 394 deletions(-)
 create mode 100644 clang/test/Sema/c23-delayed-typo-correction-crashes.c
 create mode 100644 clang/test/Sema/delayed-typo-correction-crashes.c
 create mode 100644 clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
 create mode 100644 clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp

diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 789761c1f3647..77e7c485e0a80 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -534,6 +534,12 @@ LANGOPT(BoundsSafety, 1, 0, "Bounds safety extension for C")
 
 LANGOPT(PreserveVec3Type, 1, 0, "Preserve 3-component vector type")
 
+COMPATIBLE_LANGOPT(DelayedTypoCorrection, 1, 0, "True if we want to allow "
+                   "delayed typo correction. This can improve typo correction "
+                   "behavior in C++, particularly around template "
+                   "instantiations, but comes at the expense of potentially "
+                   "crashing Clang.")
+
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index b66cc15e87b9f..63f428f6d0b2e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2025,6 +2025,9 @@ def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">,
   Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   HelpText<"Put crash-report files in <dir>">, MetaVarName<"<dir>">;
+def fdelayed_typo_correction : Flag<["-"], "fdelayed-typo-correction">, Group<f_clang_Group>,
+  HelpText<"Enable delayed typo correction">, Visibility<[CC1Option]>,
+  MarshallingInfoFlag<LangOpts<"DelayedTypoCorrection">>;
 def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
 defm cxx_exceptions: BoolFOption<"cxx-exceptions",
   LangOpts<"CXXExceptions">, DefaultFalse,
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index e41e5ba8596b9..1e39d89a0c211 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -4884,6 +4884,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     SourceLocation ELoc = ConsumeToken();
 
     if (getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
+      bool Malformed = false;
       while (Tok.isNot(tok::r_paren)) {
         if (Tok.is(tok::identifier)) {
           // identifier could be a linear kind (val, uval, ref) or step
@@ -4920,6 +4921,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
             ModifierFound = true;
           } else {
             StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+            if (!StepFound) {
+              Malformed = true;
+              SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+                        StopBeforeMatch);
+            }
           }
         } else {
           // parse an integer expression as step size
@@ -4931,7 +4937,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
         if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
           break;
       }
-      if (!StepFound && !ModifierFound)
+      if (!Malformed && !StepFound && !ModifierFound)
         Diag(ELoc, diag::err_expected_expression);
     } else {
       // for OMPC_aligned and OMPC_linear (with OpenMP <= 5.1)
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index eef134b158438..269ec888f299d 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -5437,6 +5437,9 @@ TypoExpr *Sema::CorrectTypoDelayed(
     TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode,
     DeclContext *MemberContext, bool EnteringContext,
     const ObjCObjectPointerType *OPT) {
+  if (!LangOpts.DelayedTypoCorrection)
+    return nullptr;
+
   auto Consumer = makeTypoCorrectionConsumer(
       TypoName, LookupKind, S, SS, CCC, MemberContext, EnteringContext, OPT,
       Mode == CorrectTypoKind::ErrorRecovery);
diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c
index 68d3f182dd9f6..ac3e69b9c8f99 100644
--- a/clang/test/AST/ast-dump-recovery.c
+++ b/clang/test/AST/ast-dump-recovery.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -fdelayed-typo-correction -ast-dump %s | FileCheck -strict-whitespace %s
 
 int some_func(int);
 
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index b8195950f2fa1..bd3057caa740a 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -1,5 +1,5 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -fdelayed-typo-correction -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -fdelayed-typo-correction -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
 
 int some_func(int *);
 
diff --git a/clang/test/AST/ast-dump-recovery.m b/clang/test/AST/ast-dump-recovery.m
index 37fa8045c0b94..3c5ab125317b1 100644
--- a/clang/test/AST/ast-dump-recovery.m
+++ b/clang/test/AST/ast-dump-recovery.m
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fdelayed-typo-correction -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
 
 @interface Foo
 - (void)method:(int)n;
diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp
index 4b18036365c1c..01d9405dcdb73 100644
--- a/clang/test/CXX/class.access/class.friend/p1.cpp
+++ b/clang/test/CXX/class.access/class.friend/p1.cpp
@@ -11,7 +11,7 @@
 //   friends members of the befriending class.
 
 struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
-S* g() { return 0; } // expected-note 2 {{'g' declared here}}
+S* g() { return 0; }
 
 struct X {
   friend struct S;
@@ -22,7 +22,7 @@ void test1() {
   S s;
   g()->f();
   S::f();
-  X::g(); // expected-error{{no member named 'g' in 'X'; did you mean simply 'g'?}}
+  X::g(); // expected-error{{no member named 'g' in 'X'}}
   X::S x_s; // expected-error{{no type named 'S' in 'X'; did you mean simply 'S'?}}
   X x;
   x.g(); // expected-error{{no member named 'g' in 'X'}}
@@ -40,22 +40,22 @@ namespace N {
   };
 
   struct S2 { static void f2(); }; // expected-note 2 {{'S2' declared here}}
-  S2* g2() { return 0; } // expected-note 2 {{'g2' declared here}}
+  S2* g2() { return 0; }
 
   void test() {
     g()->f();
     S s;
     S::f();
-    X::g(); // expected-error{{no member named 'g' in 'N::X'; did you mean simply 'g'?}}
+    X::g(); // expected-error{{no member named 'g' in 'N::X'}}
     X::S x_s; // expected-error{{no type named 'S' in 'N::X'; did you mean simply 'S'?}}
     X x;
     x.g(); // expected-error{{no member named 'g' in 'N::X'}}
 
     g2();
     S2 s2;
-    ::g2(); // expected-error{{no member named 'g2' in the global namespace; did you mean simply 'g2'?}}
+    ::g2(); // expected-error{{no member named 'g2' in the global namespace}}
     ::S2 g_s2; // expected-error{{no type named 'S2' in the global namespace; did you mean simply 'S2'?}}
-    X::g2(); // expected-error{{no member named 'g2' in 'N::X'; did you mean simply 'g2'?}}
+    X::g2(); // expected-error{{no member named 'g2' in 'N::X'}}
     X::S2 x_s2; // expected-error{{no type named 'S2' in 'N::X'; did you mean simply 'S2'?}}
     x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}
   }
@@ -139,7 +139,7 @@ namespace test2 {
   struct ilist_walker {
     static X *getPrev(X *N) { return N->getPrev(); }
     static X *getNext(X *N) { return N->getNext(); }
-  };  
+  };
 
   struct ilist_walker_bad {
     static X *getPrev(X *N) { return N->getPrev(); } // \
@@ -147,7 +147,7 @@ namespace test2 {
 
     static X *getNext(X *N) { return N->getNext(); } // \
     // expected-error {{'getNext' is a private member of 'test2::ilist_node'}}
-  };  
+  };
 }
 
 namespace test3 {
diff --git a/clang/test/CXX/class.access/p6.cpp b/clang/test/CXX/class.access/p6.cpp
index 15f2644f6ac1d..face8ef177589 100644
--- a/clang/test/CXX/class.access/p6.cpp
+++ b/clang/test/CXX/class.access/p6.cpp
@@ -92,7 +92,7 @@ namespace test3 {
 
   template <class T> class Outer::A<T, typename T::nature> {
   public:
-    static void foo(); // expected-note {{'Outer::A<test3::B, test3::Green>::foo' declared here}}
+    static void foo();
   };
 
   class B {
@@ -102,7 +102,7 @@ namespace test3 {
 
   void test() {
     Outer::A<B, Green>::foo();
-    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<test3::B, test3::Green>::foo'?}}
+    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'}}
   }
 }
 
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
index 3b2c48920b37b..03eb9aebd7402 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
@@ -3,7 +3,7 @@
 // Fun things you can do with inline namespaces:
 
 inline namespace X {
-  void f1(); // expected-note {{'f1' declared here}}
+  void f1();
 
   inline namespace Y {
     void f2();
@@ -21,7 +21,7 @@ void foo1() {
   f1();
   ::f1();
   X::f1();
-  Y::f1(); // expected-error {{no member named 'f1' in namespace 'Y'; did you mean simply 'f1'?}}
+  Y::f1(); // expected-error {{no member named 'f1' in namespace 'Y'}}
 
   f2();
   ::f2();
@@ -90,7 +90,7 @@ namespace redecl { inline namespace n1 {
   {
   public:
       typedef Tp& reference;
-  
+
       void allocate(allocator<void>::const_pointer = 0);
   };
 
@@ -99,7 +99,7 @@ namespace redecl { inline namespace n1 {
 // Normal redeclarations (not for explicit instantiations or
 // specializations) are distinct in an inline namespace vs. not in an
 // inline namespace.
-namespace redecl2 { 
+namespace redecl2 {
   inline namespace n1 {
     void f(int) { }
     struct X1 { };
diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp
index 17d5c2fc2e210..12de8722a8e1b 100644
--- a/clang/test/CXX/drs/cwg14xx.cpp
+++ b/clang/test/CXX/drs/cwg14xx.cpp
@@ -21,23 +21,19 @@ namespace cwg1413 { // cwg1413: 12
       // expected-error at -1 {{use of undeclared identifier 'var1'}}
 
       // ok, variable declaration
-      Check<true ? 0 : a>::type *var2; // #cwg1413-var2
+      Check<true ? 0 : a>::type *var2;
       Check<true ? 0 : b>::type *var3;
       // expected-error at -1 {{use of undeclared identifier 'var3'}}
-      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
       Check<true ? 0 : ((void)c, 0)>::type *var4;
       // expected-error at -1 {{use of undeclared identifier 'var4'}}
-      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
 
       // value-dependent because of the implied type-dependent 'this->', not because of 'd'
       Check<true ? 0 : (d(), 0)>::type *var5;
       // expected-error at -1 {{use of undeclared identifier 'var5'}}
-      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
 
       // value-dependent because of the value-dependent '&' operator, not because of 'A::d'
       Check<true ? 0 : (&A::d(), 0)>::type *var5;
       // expected-error at -1 {{use of undeclared identifier 'var5'}}
-      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
     }
   };
 } // namespace cwg1413
diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index 8b84de0ab5a9a..4051a0996c076 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -634,7 +634,7 @@ namespace example3 {
 struct Base {
 private:
   static const int i = 10; // #cwg138-ex3-Base-i
-  
+
 public:
   struct Data;
   // Elaborated type specifier is not the sole constituent of declaration,
@@ -648,7 +648,7 @@ struct Base {
   };
 };
 struct Data {
-  void f() {  
+  void f() {
     int i2 = Base::i;
     // expected-error at -1 {{'i' is a private member of 'cwg138::example3::Base'}}
     //   expected-note@#cwg138-ex3-Base-i {{declared private here}}
@@ -702,8 +702,7 @@ namespace cwg141 { // cwg141: 3.1
     // cxx98-error@#cwg141-a {{lookup of 'S' in member access expression is ambiguous; using member of 'struct A'}}
     //   cxx98-note@#cwg141-A-S {{lookup in the object type 'struct A' refers here}}
     //   cxx98-note@#cwg141-S {{lookup from the current scope refers here}}
-    // expected-error@#cwg141-a {{no member named 'n' in 'cwg141::A::S<int>'; did you mean '::cwg141::S<int>::n'?}}
-    //   expected-note@#cwg141-S {{'::cwg141::S<int>::n' declared here}}
+    // expected-error@#cwg141-a {{no member named 'n' in 'cwg141::A::S<int>'}}
     // FIXME: we issue a useful diagnostic first, then some bogus ones.
     b.f<int>();
     // expected-error at -1 {{no member named 'f' in 'cwg141::B'}}
diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp
index 3eb70583b6026..656888672106b 100644
--- a/clang/test/CXX/drs/cwg26xx.cpp
+++ b/clang/test/CXX/drs/cwg26xx.cpp
@@ -220,7 +220,6 @@ int x = cwg2640_a\N{abc});
 int y = cwg2640_a\N{LOTUS});
 // expected-error at -1 {{character <U+1FAB7> not allowed in an identifier}}
 // expected-error at -2 {{use of undeclared identifier 'cwg2640_a🪷'}}
-// expected-error at -3 {{extraneous ')' before ';'}}
 } // namespace cwg2640
 
 // cwg2642: na
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index a53a8d1ed64a8..f664b4bee284d 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -588,8 +588,7 @@ namespace cwg231 { // cwg231: 2.7
     }
     void f() { using namespace inner; }
     int j = i;
-    // expected-error at -1 {{use of undeclared identifier 'i'; did you mean 'inner::i'?}}
-    //   expected-note@#cwg231-i {{'inner::i' declared here}}
+    // expected-error at -1 {{use of undeclared identifier 'i'}}
   }
 } // namespace cwg231
 
diff --git a/clang/test/CXX/module/basic/basic.link/p2.cppm b/clang/test/CXX/module/basic/basic.link/p2.cppm
index d7d2b5992a235..c70abdc461502 100644
--- a/clang/test/CXX/module/basic/basic.link/p2.cppm
+++ b/clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -51,7 +51,7 @@ void use_from_module_impl() {
   (void)external_linkage_var;
   (void)module_linkage_var;
 
-  (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} //expected-error{{}}
+  (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}}
   (void)internal_linkage_var; // expected-error {{use of undeclared identifier 'internal_linkage_var'}}
 }
 
diff --git a/clang/test/CXX/module/module.interface/p2.cpp b/clang/test/CXX/module/module.interface/p2.cpp
index 4f06b9f386869..36c2b9baf5e10 100644
--- a/clang/test/CXX/module/module.interface/p2.cpp
+++ b/clang/test/CXX/module/module.interface/p2.cpp
@@ -72,18 +72,15 @@ import "header.h";
 
 void use() {
   // namespace A is implicitly exported by the export of A::g.
-  A::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
-          // expected-note@* {{declaration here is not visible}}
+  A::f(); // expected-error {{no member named 'f' in namespace 'A'}}
   A::g();
-  A::h();                   // expected-error {{declaration of 'h' must be imported from module 'p2' before it is required}}
-                            // expected-note@* {{declaration here is not visible}}
+  A::h();                   // expected-error {{no member named 'h' in namespace 'A'}}
   using namespace A::inner; // expected-error {{declaration of 'inner' must be imported from module 'p2' before it is required}}
 
   // namespace B and B::inner are explicitly exported
   using namespace B;
   using namespace B::inner;
-  B::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
-          // expected-note@* {{declaration here is not visible}}
+  B::f(); // expected-error {{no member named 'f' in namespace 'B'}}
   f();    // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
           // expected-note@* {{declaration here is not visible}}
 
@@ -91,8 +88,7 @@ void use() {
   using namespace C; // expected-error {{declaration of 'C' must be imported from module 'p2' before it is required}}
 
   // namespace D is exported, but D::f is not
-  D::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
-          // expected-note@* {{declaration here is not visible}}
+  D::f(); // expected-error {{no member named 'f' in namespace 'D'}}
 }
 
 int use_header() { return foo + bar::baz(); }
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
index e5807993a7a18..2da1592c57b84 100644
--- a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
@@ -12,7 +12,7 @@ A<int> a;
 A<int>::E a0 = A<int>().v;
 int n = A<int>::E::e1; // expected-error {{implicit instantiation of undefined member}}
 
-template<typename T> enum A<T>::E : T { e1, e2 }; // expected-note 2 {{declared here}}
+template<typename T> enum A<T>::E : T { e1, e2 };
 
 // FIXME: Now that A<T>::E is defined, we are supposed to inject its enumerators
 // into the already-instantiated class A<T>. This seems like a really bad idea,
@@ -20,7 +20,7 @@ template<typename T> enum A<T>::E : T { e1, e2 }; // expected-note 2 {{declared
 //
 // Either do as the standard says, or only include enumerators lexically defined
 // within the class in its scope.
-A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'; did you mean simply 'e1'?}}
+A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'}}
 
 A<char>::E a2 = A<char>::e2;
 
@@ -94,7 +94,7 @@ D<int>::E d1 = D<int>::E::e1; // expected-error {{incomplete type 'D<int>::E'}}
 template<> enum class D<int>::E { e2 };
 D<int>::E d2 = D<int>::E::e2;
 D<char>::E d3 = D<char>::E::e1; // expected-note {{first required here}}
-D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'; did you mean simply 'e2'?}}
+D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'}}
 template<> enum class D<char>::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}}
 
 template<> enum class D<short>::E;
diff --git a/clang/test/FixIt/fixit-unicode.c b/clang/test/FixIt/fixit-unicode.c
index 87819cdfbea17..ef75e5408c573 100644
--- a/clang/test/FixIt/fixit-unicode.c
+++ b/clang/test/FixIt/fixit-unicode.c
@@ -2,8 +2,8 @@
 // There's a set of additional checks for systems with proper support of UTF-8
 // on the standard output in fixit-unicode-with-utf8-output.c.
 
-// RUN: not %clang_cc1 -fsyntax-only -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck -strict-whitespace %s
-// RUN: not %clang_cc1 -fsyntax-only -fno-diagnostics-show-line-numbers -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -check-prefix=CHECK-MACHINE %s
+// RUN: not %clang_cc1 -fsyntax-only -fdelayed-typo-correction -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -fsyntax-only -fdelayed-typo-correction -fno-diagnostics-show-line-numbers -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -check-prefix=CHECK-MACHINE %s
 
 struct Foo {
   int bar;
diff --git a/clang/test/FixIt/fixit.c b/clang/test/FixIt/fixit.c
index 0e86d454a0e10..34c1129c7c0d4 100644
--- a/clang/test/FixIt/fixit.c
+++ b/clang/test/FixIt/fixit.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -verify -x c %s
+// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -fdelayed-typo-correction -verify -x c %s
 // RUN: cp %s %t
-// RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
+// RUN: not %clang_cc1 -pedantic -Wunused-label -fdelayed-typo-correction -fixit -x c %t
 // RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -Werror -x c %t
 // RUN: grep -v CHECK %t | FileCheck %t
 
diff --git a/clang/test/FixIt/typo-location-bugs.cpp b/clang/test/FixIt/typo-location-bugs.cpp
index fb60fd6d02093..c4f978fae2c41 100644
--- a/clang/test/FixIt/typo-location-bugs.cpp
+++ b/clang/test/FixIt/typo-location-bugs.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 // RUN: cp %s %t
-// RUN: not %clang_cc1 -fixit -x c++ %t
+// RUN: not %clang_cc1 -fdelayed-typo-correction -fixit -x c++ %t
 // RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
 
 namespace dcl_fct_default_p10 {
diff --git a/clang/test/FixIt/typo.cpp b/clang/test/FixIt/typo.cpp
index e489fbbcaa1df..6ba2aed6baae8 100644
--- a/clang/test/FixIt/typo.cpp
+++ b/clang/test/FixIt/typo.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 // RUN: cp %s %t
-// RUN: not %clang_cc1 -fixit -x c++ %t
+// RUN: not %clang_cc1 -fixit -fdelayed-typo-correction -x c++ %t
 // RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
 // RUN: grep test_string %t
 
diff --git a/clang/test/Index/complete-switch.c b/clang/test/Index/complete-switch.c
index 4a78854595543..d588993504eaf 100644
--- a/clang/test/Index/complete-switch.c
+++ b/clang/test/Index/complete-switch.c
@@ -6,5 +6,5 @@ void f() {
   }
 }
 
-// RUN: not %clang_cc1 -fsyntax-only -fno-recovery-ast -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty
+// RUN: not %clang_cc1 -fsyntax-only -fno-recovery-ast -fdelayed-typo-correction -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty
 // CHECK-NOT: COMPLETION: foo
diff --git a/clang/test/Index/fix-its.c b/clang/test/Index/fix-its.c
index 1e710c28afcca..be4ac4a4827b0 100644
--- a/clang/test/Index/fix-its.c
+++ b/clang/test/Index/fix-its.c
@@ -1,4 +1,4 @@
-// RUN: c-index-test -test-load-source all -fspell-checking %s 2> %t  
+// RUN: c-index-test -test-load-source all -fspell-checking -Xclang -fdelayed-typo-correction %s 2> %t
 // RUN: FileCheck %s < %t
 struct X {
   int wibble;
diff --git a/clang/test/Lexer/raw-string-ext.c b/clang/test/Lexer/raw-string-ext.c
index de318b616df70..8ed96e5c19f0d 100644
--- a/clang/test/Lexer/raw-string-ext.c
+++ b/clang/test/Lexer/raw-string-ext.c
@@ -27,13 +27,13 @@
 // no-warning@* {{ignoring '-fno-raw-string-literals'}}
 
 void f() {
-  (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 'R'}} cxx-unsupported-error {{expected ';' after expression}}
-  (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 'LR'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 'R'}}
+  (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 'LR'}}
 
 #ifdef UNICODE
-  (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 'uR'}} cxx-unsupported-error {{expected ';' after expression}}
-  (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 'u8R'}} cxx-unsupported-error {{expected ';' after expression}}
-  (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 'UR'}} cxx-unsupported-error {{expected ';' after expression}}
+  (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 'uR'}}
+  (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 'u8R'}}
+  (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 'UR'}}
 #endif
 }
 
diff --git a/clang/test/Misc/serialized-diags.m b/clang/test/Misc/serialized-diags.m
index 71c983b883853..1d66958ea8e0e 100644
--- a/clang/test/Misc/serialized-diags.m
+++ b/clang/test/Misc/serialized-diags.m
@@ -11,7 +11,7 @@ - (void) test2 {}
 @end
 
 // RUN: rm -f %t
-// RUN: not %clang -Wall -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1
+// RUN: not %clang -Wall -Xclang -fdelayed-typo-correction -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1
 // RUN: c-index-test -read-diagnostics %t.diag > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
diff --git a/clang/test/Modules/auto-module-import.m b/clang/test/Modules/auto-module-import.m
index cfbb28fa20e66..dd1a367f7b2e7 100644
--- a/clang/test/Modules/auto-module-import.m
+++ b/clang/test/Modules/auto-module-import.m
@@ -28,8 +28,7 @@
 
 void testSubframeworkOther(void) {
 #ifdef ERRORS
-  double *sfo1 = sub_framework_other; // expected-error{{declaration of 'sub_framework_other' must be imported from module 'DependsOnModule.SubFramework.Other'}}
-  // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h:15 {{not visible}}
+  double *sfo1 = sub_framework_other; // expected-error{{use of undeclared identifier 'sub_framework_other'}}
 #endif
 }
 
@@ -47,7 +46,8 @@ void testSubframeworkOther(void) {
 #endif
 
 void testSubframeworkOtherAgain(void) {
-  double *sfo1 = sub_framework_other;
+  // FIXME: this diagnostic should be triggered consistently.
+  double *sfo1 = sub_framework_other; // expected-error 0+{{use of undeclared identifier 'sub_framework_other'}}
 }
 
 void testModuleSubFramework(void) {
@@ -72,8 +72,7 @@ void testModuleSubFrameworkAgain(void) {
 #include <NoUmbrella/A_Private.h> // expected-remark{{treating #include as an import of module 'NoUmbrella.Private.A_Private'}}
 int getNoUmbrellaAPrivate(void) { return no_umbrella_A_private; }
 
-int getNoUmbrellaBPrivateFail(void) { return no_umbrella_B_private; } // expected-error{{declaration of 'no_umbrella_B_private' must be imported from module 'NoUmbrella.Private.B_Private'}}
-// expected-note at Inputs/NoUmbrella.framework/PrivateHeaders/B_Private.h:1 {{not visible}}
+int getNoUmbrellaBPrivateFail(void) { return no_umbrella_B_private; } // expected-error{{use of undeclared identifier 'no_umbrella_B_private'}}
 
 // Test inclusion of headers that are under an umbrella directory but
 // not actually part of the module.
diff --git a/clang/test/Modules/crash-typo-correction-visibility.cpp b/clang/test/Modules/crash-typo-correction-visibility.cpp
index 9f0ed3b7b1320..d52bd4443c242 100644
--- a/clang/test/Modules/crash-typo-correction-visibility.cpp
+++ b/clang/test/Modules/crash-typo-correction-visibility.cpp
@@ -1,6 +1,6 @@
 // RUN: mkdir -p %t
-// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
-// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/module.pcm %s -verify
+// RUN: %clang_cc1 -x c++ -std=c++11 -fdelayed-typo-correction -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
+// RUN: %clang_cc1 -x c++ -std=c++11 -fdelayed-typo-correction -fmodules -fmodule-file=%t/module.pcm %s -verify
 
 struct S {
   int member; // expected-note {{declared here}}
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index f587af4beb7ce..d7938f51985cc 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -200,7 +200,7 @@ namespace hidden_specializations {
     // For enums, uses that would trigger instantiations of definitions are not
     // allowed.
     cls<void>::nested_enum e; // ok
-    (void)cls<void>::nested_enum::e; // expected-error 1+{{definition of 'nested_enum' must be imported}} expected-error 1+{{declaration of 'e'}}
+    (void)cls<void>::nested_enum::e; // expected-error 1+{{definition of 'nested_enum' must be imported}} expected-error 1+{{no member named 'e' in 'hidden_specializations::cls<void>::nested_enum'}}
 
     // For variable template specializations, no uses are allowed because
     // specializations can change the type.
diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m
index 8fb8e6b25f68a..12fa632618034 100644
--- a/clang/test/Modules/diagnose-missing-import.m
+++ b/clang/test/Modules/diagnose-missing-import.m
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/diagnose-missing-import \
-// RUN:   -Werror=implicit-function-declaration -fsyntax-only \
+// RUN:   -Werror=implicit-function-declaration -fsyntax-only -fdelayed-typo-correction \
 // RUN:   -fimplicit-module-maps -verify %s
 @import NCI;
 
diff --git a/clang/test/Modules/normal-module-map.cpp b/clang/test/Modules/normal-module-map.cpp
index 1f4e3e57d20e8..9b249786dbbc0 100644
--- a/clang/test/Modules/normal-module-map.cpp
+++ b/clang/test/Modules/normal-module-map.cpp
@@ -2,8 +2,8 @@
 // RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/normal-module-map %s -verify
 #include "Umbrella/umbrella_sub.h"
 
-int getUmbrella(void) { 
-  return umbrella + umbrella_sub; 
+int getUmbrella(void) {
+  return umbrella + umbrella_sub;
 }
 
 @import Umbrella2;
@@ -24,8 +24,7 @@ int testNestedUmbrellaA(void) {
 
 int testNestedUmbrellaBFail(void) {
   return nested_umbrella_b;
-  // expected-error at -1{{declaration of 'nested_umbrella_b' must be imported from module 'nested_umbrella.b' before it is required}}
-  // expected-note at Inputs/normal-module-map/nested_umbrella/b.h:1{{here}}
+  // expected-error at -1{{use of undeclared identifier 'nested_umbrella_b'}}
 }
 
 @import nested_umbrella.b;
diff --git a/clang/test/Modules/subframeworks.m b/clang/test/Modules/subframeworks.m
index cf94c5e3549f6..cd6e1a40c9ee4 100644
--- a/clang/test/Modules/subframeworks.m
+++ b/clang/test/Modules/subframeworks.m
@@ -5,8 +5,7 @@
 @import DependsOnModule;
 
 void testSubFramework(void) {
-  float *sf1 = sub_framework; // expected-error{{declaration of 'sub_framework' must be imported from module 'DependsOnModule.SubFramework' before it is required}}
-  // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h:2 {{here}}
+  float *sf1 = sub_framework; // expected-error{{use of undeclared identifier 'sub_framework'}}
 }
 
 @import DependsOnModule.SubFramework;
diff --git a/clang/test/Modules/submodule-visibility.cpp b/clang/test/Modules/submodule-visibility.cpp
index 6a1a816ed67e5..dad19ae50a780 100644
--- a/clang/test/Modules/submodule-visibility.cpp
+++ b/clang/test/Modules/submodule-visibility.cpp
@@ -28,8 +28,7 @@
 // The use of -fmodule-name=x causes us to textually include the above headers.
 // The submodule visibility rules are still applied in this case.
 //
-// expected-error at b.h:1 {{missing '#include "a.h"'; 'n' must be declared}}
-// expected-note at a.h:1 {{here}}
+// expected-error at b.h:1 {{use of undeclared identifier 'n'}}
 #endif
 
 int k = n + m; // OK, a and b are visible here.
@@ -45,8 +44,8 @@ int k = n + m; // OK, a and b are visible here.
 // Ensure we don't compute the linkage of this struct before we find it has a
 // typedef name for linkage purposes.
 typedef struct {
-  int p;                 
-  void (*f)(int p);                                                                       
+  int p;
+  void (*f)(int p);
 } name_for_linkage;
 
 void g() { b_template<int>(); }
diff --git a/clang/test/Modules/submodules-merge-defs.cpp b/clang/test/Modules/submodules-merge-defs.cpp
index 0a54699a96723..c4a51ebfe4584 100644
--- a/clang/test/Modules/submodules-merge-defs.cpp
+++ b/clang/test/Modules/submodules-merge-defs.cpp
@@ -48,10 +48,11 @@ int pre_fg = F<int>().g<int>(); // expected-error +{{must be declared}}
 // expected-note at defs.h:34 +{{here}}
 
 G::A pre_ga // expected-error +{{must be declared}}
-  = G::a; // expected-error +{{must be declared}}
+  = G::a; // expected-error +{{no member named 'a' in namespace 'G'}}
 // expected-note at defs.h:50 +{{here}}
-decltype(G::h) pre_gh = G::h; // expected-error +{{must be declared}} expected-error +{{must be defined}}
-// expected-note at defs.h:51 +{{here}}
+decltype(G::h) pre_gh = G::h; // expected-error +{{no member named 'h' in namespace 'G'}}
+// FIXME: some of the RUN lines emit this note, textual ones do not.
+// expected-note at defs.h:51 0+{{here}}
 
 int pre_h = H(); // expected-error +{{must be declared}}
 // expected-note at defs.h:56 +{{here}}
diff --git a/clang/test/Modules/suggest-include.cpp b/clang/test/Modules/suggest-include.cpp
index 1e53ef05d5f83..ac59ca00ec566 100644
--- a/clang/test/Modules/suggest-include.cpp
+++ b/clang/test/Modules/suggest-include.cpp
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs/suggest-include %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -fdelayed-typo-correction -I%S/Inputs/suggest-include %s -verify
 
 #include "empty.h" // import the module file
 
diff --git a/clang/test/OpenMP/begin_declare_variant_messages.c b/clang/test/OpenMP/begin_declare_variant_messages.c
index d8d8f4211678f..8878188e7ceb2 100644
--- a/clang/test/OpenMP/begin_declare_variant_messages.c
+++ b/clang/test/OpenMP/begin_declare_variant_messages.c
@@ -83,7 +83,7 @@ const int var;
 #pragma omp end declare variant
 #pragma omp begin declare variant match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}}
 #pragma omp end declare variant
-#pragma omp begin declare variant match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<recovery-expr>()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
+#pragma omp begin declare variant match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp end declare variant
 #pragma omp begin declare variant match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp end declare variant
diff --git a/clang/test/OpenMP/declare_reduction_messages.cpp b/clang/test/OpenMP/declare_reduction_messages.cpp
index 752cc4fb05a12..f91d952dfa14f 100644
--- a/clang/test/OpenMP/declare_reduction_messages.cpp
+++ b/clang/test/OpenMP/declare_reduction_messages.cpp
@@ -69,7 +69,7 @@ class Class2 : public Class1<T> {
 #pragma omp declare reduction(fun77 : long : omp_out += omp_in) initializer(omp_priv Class2 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv 23)                 // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare reduction(fun88 : long : omp_out += omp_in) initializer(omp_priv 23))               // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
-#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23)               // expected-error {{use of undeclared identifier 'omp_priv'; did you mean 'omp_in'?}} expected-note {{'omp_in' declared here}}
+#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23)               // expected-error {{use of undeclared identifier 'omp_priv'}}
 #pragma omp declare reduction(fun10 : long : omp_out += omp_in) initializer(omp_priv = 23)
 
 template <typename T>
diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c
index 32e365cc415bd..d1e36e5d1e7e9 100644
--- a/clang/test/OpenMP/declare_variant_messages.c
+++ b/clang/test/OpenMP/declare_variant_messages.c
@@ -11,7 +11,7 @@ int foo(void);
 #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
 #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}}
-#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}}
 #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foo) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
@@ -42,7 +42,7 @@ int foo(void);
 #pragma omp declare variant(foo) match(device={kind(}) // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind()}) // expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}}
 #pragma omp declare variant(foo) match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}}
-#pragma omp declare variant(foo) match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<recovery-expr>()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
+#pragma omp declare variant(foo) match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind(score(foo()) ibm)}) // expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('foo()'); score ignored}} expected-warning {{'ibm' is not a valid context property for the context selector 'kind' and the context set 'device'; property ignored}} expected-note {{try 'match(implementation={vendor(ibm)})'}} expected-note {{the ignored property spans until here}}
 #pragma omp declare variant(foo) match(device={kind(score(5): host), kind(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'kind' was used already in the same 'omp declare variant' directive; selector ignored}} expected-note {{the previous context selector 'kind' used here}} expected-note {{the ignored selector spans until here}}
@@ -56,7 +56,7 @@ int foo(void);
 #pragma omp declare variant(foo) match(target_device={device_num}) // expected-warning {{the context selector 'device_num' in context set 'target_device' requires a context property defined in parentheses; selector ignored}} expected-note {{the ignored selector spans until here}}
 #pragma omp declare variant(foo) match(target_device={device_num()}) // expected-error {{expected expression}}
 #pragma omp declare variant(foo) match(target_device={device_num(-1)}) // expected-error {{argument to 'device_num' clause must be a non-negative integer value}}
-#pragma omp declare variant(foo) match(target_device={device_num(abc)}) // expected-error {{expected expression}} expected-error {{use of undeclared identifier 'abc'}}
+#pragma omp declare variant(foo) match(target_device={device_num(abc)}) // expected-error {{use of undeclared identifier 'abc'}}
 int bar(void);
 
 
diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp
index 8eb37bc64cbc1..06da8a8e5b058 100644
--- a/clang/test/OpenMP/declare_variant_messages.cpp
+++ b/clang/test/OpenMP/declare_variant_messages.cpp
@@ -16,7 +16,7 @@ T foofoo();
 #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
 #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}}
-#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}}
 #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo <int>) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo <int>) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
@@ -57,7 +57,7 @@ int bar();
 #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
 #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foofoo <T> // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}}
-#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}}
 #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo <T>) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index 08d745f3b1a07..a8efe0f414333 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -46,7 +46,7 @@ void test_linear_colons()
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/distribute_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
index 64bcdb4812979..daf15ffd935a3 100644
--- a/clang/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -40,13 +40,13 @@ void test_linear_colons()
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/for_linear_messages.cpp b/clang/test/OpenMP/for_linear_messages.cpp
index 2e10230630adb..84c2c1e6baf77 100644
--- a/clang/test/OpenMP/for_linear_messages.cpp
+++ b/clang/test/OpenMP/for_linear_messages.cpp
@@ -20,7 +20,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -37,7 +37,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp for linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp for linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/for_simd_linear_messages.cpp b/clang/test/OpenMP/for_simd_linear_messages.cpp
index 30c6f7274b5da..787c499db34d6 100644
--- a/clang/test/OpenMP/for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -35,7 +35,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp for simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp for simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
index f67af47fc1dfb..064ce1ec0a3fd 100644
--- a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp masked taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp masked taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
index 555c81c34c703..18fbaa682b205 100644
--- a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp master taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp master taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_for_linear_messages.cpp b/clang/test/OpenMP/parallel_for_linear_messages.cpp
index ba80c8e1ce689..c36ac5dffe22d 100644
--- a/clang/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_linear_messages.cpp
@@ -18,7 +18,7 @@ int x;
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -36,7 +36,7 @@ void test_linear_colons() {
 #pragma omp parallel for linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'}}
 #pragma omp parallel for linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
index 7d540bcac8640..b7a68eac91732 100644
--- a/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -17,7 +17,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -34,7 +34,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel for simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp parallel for simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
index a3befd481aa90..f76d31c6a0d74 100644
--- a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel masked taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp parallel masked taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
index b406f36df167b..6c5a1f76b7619 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel master taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp parallel master taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/simd_linear_messages.cpp b/clang/test/OpenMP/simd_linear_messages.cpp
index 3ce4de697de0c..3055999994020 100644
--- a/clang/test/OpenMP/simd_linear_messages.cpp
+++ b/clang/test/OpenMP/simd_linear_messages.cpp
@@ -17,7 +17,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -34,7 +34,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp
index 911031d5412a9..91006860ee2b8 100644
--- a/clang/test/OpenMP/target_map_messages.cpp
+++ b/clang/test/OpenMP/target_map_messages.cpp
@@ -136,7 +136,7 @@ struct SA {
     {}
     #pragma omp target map(self, tofrom: c[:],f)   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
     {}
-    #pragma omp target map(self, tofrom: c,f[:])   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} 
+    #pragma omp target map(self, tofrom: c,f[:])   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
     {}
     #pragma omp target map(close, tofrom: c,f)
     {}
@@ -997,10 +997,8 @@ int main(int argc, char **argv) {
   #pragma omp target map(iterator(it=0:10), tofrom:a[it])
   {}
 
-  // ompx-error at +8 {{use of undeclared identifier 'itt'; did you mean 'it'?}}
-  // ompx-note at +7 {{'it' declared here}}
-  // omp-error at +6 {{use of undeclared identifier 'itt'; did you mean 'it'?}}
-  // omp-note at +5 {{'it' declared here}}
+  // ompx-error at +6 {{use of undeclared identifier 'itt'}}
+  // omp-error at +5 {{use of undeclared identifier 'itt'}}
   // ge51-ompx-error at +4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}}
   // lt51-ompx-error at +3 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}}
   // ge51-omp-error at +2 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present'}}
diff --git a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
index 62aed5780c0cc..acedc3e1d57a4 100644
--- a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -27,7 +27,7 @@ int x;
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -45,7 +45,7 @@ void test_linear_colons() {
 #pragma omp target parallel for linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'}}
 #pragma omp target parallel for linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
index e4e3f9c94febe..1936d8188acbf 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -29,7 +29,7 @@ int x;
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -47,7 +47,7 @@ void test_linear_colons() {
 #pragma omp target parallel for simd linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'}}
 #pragma omp target parallel for simd linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_simd_linear_messages.cpp b/clang/test/OpenMP/target_simd_linear_messages.cpp
index c31ba0dec8c3c..a337052a0d1e7 100644
--- a/clang/test/OpenMP/target_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_simd_linear_messages.cpp
@@ -28,7 +28,7 @@ int x;
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -46,7 +46,7 @@ void test_linear_colons() {
 #pragma omp target simd linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'}}
 #pragma omp target simd linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index a77c1ac6201b8..250dec62f3a93 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -26,7 +26,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -48,7 +48,7 @@ void test_linear_colons()
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index dfa0f2a1e38e4..f071dd4c1ceec 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -26,7 +26,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -48,7 +48,7 @@ void test_linear_colons()
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/target_update_messages.cpp b/clang/test/OpenMP/target_update_messages.cpp
index 83191059202ca..000cc80e513e6 100644
--- a/clang/test/OpenMP/target_update_messages.cpp
+++ b/clang/test/OpenMP/target_update_messages.cpp
@@ -113,9 +113,11 @@ int main(int argc, char **argv) {
   // Check parsing with two modifiers.
   // lt51-warning at +1 {{missing ':' after ) - ignoring}}
   #pragma omp target update to(mapper(id), present: s)
-  // lt51-error at +3 {{use of undeclared identifier 'present'}}
-  // lt51-error at +2 {{use of undeclared identifier 'id'}}
-  // lt51-error at +1 {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+  // lt51-error at +5 {{use of undeclared identifier 'present'}}
+  // lt51-error at +4 {{use of undeclared identifier 'id'}}
+  // lt51-error at +3 {{expected ',' or ')' in 'to' clause}}
+  // lt51-error at +2 {{expected ')'}}
+  // lt51-note at +1 {{to match this '('}}
   #pragma omp target update to(present, mapper(id): s)
   // lt51-warning at +1 {{missing ':' after ) - ignoring}}
   #pragma omp target update to(mapper(id) present: s)
@@ -141,10 +143,9 @@ int main(int argc, char **argv) {
   #pragma omp target update to(present,,: s)
   // lt51-warning at +1 {{missing ':' after ) - ignoring}}
   #pragma omp target update to(mapper(id), present,: s)
-  // lt51-error at +4 {{use of undeclared identifier 'present'}}
-  // lt51-error at +3 {{use of undeclared identifier 'id'}}
-  // lt51-error at +2 {{expected expression}}
-  // lt51-error at +1 {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+  // lt51-error at +3 {{use of undeclared identifier 'present'}}
+  // lt51-error at +2 {{use of undeclared identifier 'id'}}
+  // lt51-error at +1 {{expected expression}}
   #pragma omp target update to(present, mapper(id),: s)
 
   #pragma omp target update from(m) allocate(m) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target update'}}
diff --git a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
index 3741f4e8286bd..927f13510626d 100644
--- a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'}}
   #pragma omp taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index 193f53e52bbf1..299a3a7fa508d 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -43,7 +43,7 @@ void test_linear_colons()
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
-#pragma omp teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index 129d88f5b3bcc..885df92b59d16 100644
--- a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib; // expected-note {{'B::ib' declared here}}
+  static int ib;
   static int bfoo() { return 8; }
 };
 
@@ -43,7 +43,7 @@ void test_linear_colons()
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
-#pragma omp teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/PCH/race-condition.cpp b/clang/test/PCH/race-condition.cpp
index 752b0cc3ff628..4f1fa14b93475 100644
--- a/clang/test/PCH/race-condition.cpp
+++ b/clang/test/PCH/race-condition.cpp
@@ -31,11 +31,7 @@ constexpr enable_if_t<meta<F>::value == 2, void> midpoint(F) {}
 
 #else
 
-// expected-error at 27{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'F'}}
-// expected-error at 24{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'U'}}
-// expected-note at 21{{but in '' found 1st parameter with type 'T'}}
 int x = N::something;
-// expected-error at 37{{no member named 'something' in namespace 'N'}}
-// expected-note at 21{{but in '' found 1st parameter with type 'T'}}
+// expected-error at -1{{no member named 'something' in namespace 'N'}}
 
 #endif
diff --git a/clang/test/Parser/cxx-invalid-for-range.cpp b/clang/test/Parser/cxx-invalid-for-range.cpp
index 557c1da209a9a..009b10fc69f25 100644
--- a/clang/test/Parser/cxx-invalid-for-range.cpp
+++ b/clang/test/Parser/cxx-invalid-for-range.cpp
@@ -3,12 +3,12 @@
 // From PR23057 comment #18 (https://llvm.org/bugs/show_bug.cgi?id=23057#c18).
 
 namespace N {
-  int X[10]; // expected-note{{declared here}}}}
+  int X[10];
 }
 
 void f1() {
   for (auto operator new : X); // expected-error{{'operator new' cannot be the name of a variable or data member}}
-                               // expected-error at -1{{use of undeclared identifier 'X'; did you mean 'N::X'?}}
+                               // expected-error at -1{{use of undeclared identifier 'X'}}
 }
 
 void f2() {
diff --git a/clang/test/Parser/cxx1z-fold-expressions.cpp b/clang/test/Parser/cxx1z-fold-expressions.cpp
index 4a329646b799f..d798a9cbb99b7 100644
--- a/clang/test/Parser/cxx1z-fold-expressions.cpp
+++ b/clang/test/Parser/cxx1z-fold-expressions.cpp
@@ -37,14 +37,14 @@ template<int ...N> int bad12() { return (... N); } // expected-error {{expected
 
 template<typename ...T> void as_operand_of_cast(int a, T ...t) {
   return
-    (int)(a + ... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
+    (int)(a + ... + undeclared_junk) + // expected-error {{undeclared}}
     (int)(t + ... + undeclared_junk) + // expected-error {{undeclared}}
-    (int)(... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
+    (int)(... + undeclared_junk) + // expected-error {{undeclared}}
     (int)(undeclared_junk + ...) + // expected-error {{undeclared}}
     (int)(a + ...) + // expected-error {{does not contain any unexpanded}}
     (int)(a, ...) + // expected-error {{does not contain any unexpanded}}
     (int)(..., a) + // expected-error {{does not contain any unexpanded}}
-    (int)(a, ..., undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
+    (int)(a, ..., undeclared_junk) + // expected-error {{undeclared}}
     (int)(t, ...) +
     (int)(..., t) +
     (int)(t, ..., a);
diff --git a/clang/test/Parser/cxx2c-pack-indexing.cpp b/clang/test/Parser/cxx2c-pack-indexing.cpp
index 72e286322fa97..79069a86ea706 100644
--- a/clang/test/Parser/cxx2c-pack-indexing.cpp
+++ b/clang/test/Parser/cxx2c-pack-indexing.cpp
@@ -69,7 +69,8 @@ template <typename... T>
 requires( ); // expected-error {{expected expression}}
 struct SS {
     void f( ) {
-        (*p).~T...[](); // expected-error {{use of undeclared identifier 'p'}}
+        (*p).~T...[](); // expected-error {{use of undeclared identifier 'p'}} \
+                           expected-error {{undeclared identifier 'T' in destructor name}}
     }
 };
 }
diff --git a/clang/test/Parser/objc-foreach-syntax.m b/clang/test/Parser/objc-foreach-syntax.m
index 2158d8062f6cd..1ff84f393b9f4 100644
--- a/clang/test/Parser/objc-foreach-syntax.m
+++ b/clang/test/Parser/objc-foreach-syntax.m
@@ -21,6 +21,5 @@ - (void)compilerTestAgainst {
 
 
 static int test7(id keys) {
-  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}} \
-                           // expected-error {{expected ';' in 'for' statement specifier}}
+  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}}
 }
diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl
index 2648142f28e7c..2cd2c6ca133e1 100644
--- a/clang/test/Parser/opencl-atomics-cl20.cl
+++ b/clang/test/Parser/opencl-atomics-cl20.cl
@@ -39,23 +39,17 @@ void atomic_types_test(void) {
 // expected-error at -11 {{use of undeclared identifier 'atomic_ulong'}}
 // expected-error at -11 {{use of undeclared identifier 'atomic_double'}}
 #if defined(LANG_VER_OK)
-// expected-error at -15 {{expected ';' after expression}}
-// expected-error at -16 {{use of undeclared identifier 'l'}}
-// expected-error at -16 {{expected ';' after expression}}
-// expected-error at -17 {{use of undeclared identifier 'ul'}}
 #endif
 #if !defined(LANG_VER_OK) || defined(__SPIR64__)
-// expected-error at -18 {{use of undeclared identifier 'atomic_size_t'}}
-// expected-error at -16 {{use of undeclared identifier 'atomic_ptrdiff_t'}}
+// expected-error at -14 {{use of undeclared identifier 'atomic_size_t'}}
+// expected-error at -12 {{use of undeclared identifier 'atomic_ptrdiff_t'}}
 #if !defined(LANG_VER_OK)
-// expected-error at -20 {{use of undeclared identifier 'atomic_intptr_t'}}
-// expected-error at -20 {{use of undeclared identifier 'atomic_uintptr_t'}}
+// expected-error at -16 {{use of undeclared identifier 'atomic_intptr_t'}}
+// expected-error at -16 {{use of undeclared identifier 'atomic_uintptr_t'}}
 #else
-// expected-error at -24 {{expected ';' after expression}}
-// expected-error at -25 {{use of undeclared identifier 's'}}
-// expected-error at -25 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}}
+// expected-error at -19 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}}
 // expected-note@* {{'atomic_int' declared here}}
-// expected-error at -26 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}}
+// expected-error at -20 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}}
 // expected-note@* {{'atomic_uint' declared here}}
 #endif
 #endif
diff --git a/clang/test/Parser/recovery.c b/clang/test/Parser/recovery.c
index 6fdbedffd236a..a84fe0e6ac525 100644
--- a/clang/test/Parser/recovery.c
+++ b/clang/test/Parser/recovery.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -fblocks %s
 
 // PR2241
-float test2241[2] = { 
+float test2241[2] = {
   1e,            // expected-error {{exponent}}
   1ee0           // expected-error {{exponent}}
 };
@@ -11,7 +11,7 @@ float test2241[2] = {
 static void f (char * (*g) (char **, int), char **p, ...) {
   char *s;
   va_list v;                              // expected-error {{identifier}}
-  s = g (p, __builtin_va_arg(v, int));    // expected-error {{identifier}}
+  s = g (p, __builtin_va_arg(v, int));    // expected-error {{identifier}} expected-error {{extraneous ')' before ';'}}
 }
 
 
@@ -21,17 +21,17 @@ static void f (char * (*g) (char **, int), char **p, ...) {
 
 void test(int a) {
   struct { int i; } x;
-  
+
   if (x.hello)   // expected-error {{no member named 'hello'}}
     test(0);
   else
     ;
-  
+
   if (x.hello == 0)   // expected-error {{no member named 'hello'}}
     test(0);
   else
     ;
-  
+
   if ((x.hello == 0))   // expected-error {{no member named 'hello'}}
     test(0);
   else
@@ -60,7 +60,7 @@ struct S A = {
 &BADIDENT, 0     /* expected-error {{use of undeclared identifier}} */
 };
 
-void test6248081(void) { 
+void test6248081(void) {
   [10]  // expected-error {{expected expression}}
 }
 
diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp
index baf703cd03aed..db8d3c457b62b 100644
--- a/clang/test/Parser/switch-recovery.cpp
+++ b/clang/test/Parser/switch-recovery.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 struct A {};
 struct B {
@@ -7,7 +7,7 @@ struct B {
     default:
       return;
     }
-    
+
     switch (b) {
     case 17 // expected-error{{expected ':' after 'case'}}
       break;
diff --git a/clang/test/Parser/switch-typo-correction.cpp b/clang/test/Parser/switch-typo-correction.cpp
index ebf1c18f2b86a..a923c35002c61 100644
--- a/clang/test/Parser/switch-typo-correction.cpp
+++ b/clang/test/Parser/switch-typo-correction.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 namespace c { double xxx; } // expected-note{{'c::xxx' declared here}}
 namespace d { float xxx; }
diff --git a/clang/test/ParserOpenACC/parse-cache-construct.cpp b/clang/test/ParserOpenACC/parse-cache-construct.cpp
index a5a1e58028c33..1c7f5a852e266 100644
--- a/clang/test/ParserOpenACC/parse-cache-construct.cpp
+++ b/clang/test/ParserOpenACC/parse-cache-construct.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 %s -verify -fopenacc
 
 namespace NS {
-  static char* NSArray;// expected-note{{declared here}}
-  static int NSInt;// expected-note 2{{declared here}}
+  static char* NSArray;
+  static int NSInt;
 }
 char *getArrayPtr();
 template<typename T, int I>
@@ -21,17 +21,17 @@ void func() {
   }
 
   for (int i = 0; i < 10; ++i) {
-    // expected-error at +1{{use of undeclared identifier 'NSArray'; did you mean 'NS::NSArray'}}
+    // expected-error at +1{{use of undeclared identifier 'NSArray'}}
     #pragma acc cache(NSArray[NS::NSInt : NS::NSInt])
   }
 
   for (int i = 0; i < 10; ++i) {
-    // expected-error at +1{{use of undeclared identifier 'NSInt'; did you mean 'NS::NSInt'}}
+    // expected-error at +1{{use of undeclared identifier 'NSInt'}}
     #pragma acc cache(NS::NSArray[NSInt : NS::NSInt])
   }
 
   for (int i = 0; i < 10; ++i) {
-    // expected-error at +1{{use of undeclared identifier 'NSInt'; did you mean 'NS::NSInt'}}
+    // expected-error at +1{{use of undeclared identifier 'NSInt'}}
     #pragma acc cache(NS::NSArray[NS::NSInt : NSInt])
   }
 }
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 6d771e858d243..a9ad7ab176cbc 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -347,9 +347,7 @@ void SelfUpdate() {
 #pragma acc update host(s) self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +3{{use of undeclared identifier 'zero'}}
-  // expected-error at +2{{expected ','}}
-  // expected-error at +1{{expected expression}}
+  // expected-error at +1{{use of undeclared identifier 'zero'}}
 #pragma acc update self(zero : s.array[s.value : 5], s.value), if_present
   for(int i = 0; i < 5;++i) {}
 
@@ -453,8 +451,6 @@ void VarListClauses() {
 #pragma acc parallel copy(always, alwaysin, always: HasMem.MemArr[3:]) self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +3{{use of undeclared identifier 'always'}}
-  // expected-error at +2{{use of undeclared identifier 'alwaysin'}}
   // expected-error at +1{{use of undeclared identifier 'always'}}
 #pragma acc parallel copy(always, alwaysin, always, HasMem.MemArr[3:]) self
   for(int i = 0; i < 5;++i) {}
@@ -591,8 +587,7 @@ void VarListClauses() {
 #pragma acc serial copyout(zero : s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'zero'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'zero'}}
 #pragma acc serial copyout(zero s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
@@ -608,8 +603,7 @@ void VarListClauses() {
 #pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'invalid'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'invalid'}}
 #pragma acc serial copyout(invalid s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
@@ -657,8 +651,7 @@ void VarListClauses() {
 #pragma acc serial create(zero : s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'zero'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'zero'}}
 #pragma acc serial create(zero s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
@@ -674,8 +667,7 @@ void VarListClauses() {
 #pragma acc serial create(invalid:s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'invalid'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'invalid'}}
 #pragma acc serial create(invalid s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
@@ -700,8 +692,7 @@ void VarListClauses() {
 #pragma acc serial copyin(readonly : s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'readonly'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'readonly'}}
 #pragma acc serial copyin(readonly s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
@@ -717,8 +708,7 @@ void VarListClauses() {
 #pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
-  // expected-error at +2{{use of undeclared identifier 'invalid'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'invalid'}}
 #pragma acc serial copyin(invalid s.array[s.value : 5], s.value), self
   for(int i = 0; i < 5;++i) {}
 
diff --git a/clang/test/ParserOpenACC/parse-constructs.cpp b/clang/test/ParserOpenACC/parse-constructs.cpp
index 814f6a1fd09f2..ead3077f178bb 100644
--- a/clang/test/ParserOpenACC/parse-constructs.cpp
+++ b/clang/test/ParserOpenACC/parse-constructs.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 %s -verify -fopenacc
 
 namespace NS {
-  void foo(); // expected-note{{declared here}}
+  void foo();
 
   template<typename T>
-  void templ(); // expected-note 2{{declared here}}
+  void templ();
 
   class C { // #CDef
     void private_mem_func(); // #PrivateMemFunc
@@ -13,18 +13,16 @@ namespace NS {
   };
 }
 
-// expected-error at +1{{use of undeclared identifier 'foo'; did you mean 'NS::foo'?}}
+// expected-error at +1{{use of undeclared identifier 'foo'}}
 #pragma acc routine(foo) seq
 #pragma acc routine(NS::foo) seq
 
-// expected-error at +2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}}
-// expected-error at +1{{OpenACC routine name 'NS::templ' names a set of overloads}}
+// expected-error at +1{{use of undeclared identifier 'templ'}}
 #pragma acc routine(templ) seq
 // expected-error at +1{{OpenACC routine name 'NS::templ' names a set of overloads}}
 #pragma acc routine(NS::templ) seq
 
-// expected-error at +2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}}
-// expected-error at +1{{OpenACC routine name 'NS::templ' names a set of overloads}}
+// expected-error at +1{{use of undeclared identifier 'templ'}}
 #pragma acc routine(templ<int>) seq
 // expected-error at +1{{OpenACC routine name 'NS::templ<int>' names a set of overloads}}
 #pragma acc routine(NS::templ<int>) seq
diff --git a/clang/test/ParserOpenACC/parse-sub-array.cpp b/clang/test/ParserOpenACC/parse-sub-array.cpp
index c0d3f89159e89..f4777820867c3 100644
--- a/clang/test/ParserOpenACC/parse-sub-array.cpp
+++ b/clang/test/ParserOpenACC/parse-sub-array.cpp
@@ -35,7 +35,7 @@ void Func(int i, int j) {
   while (true);
 }
 
-template<typename T, unsigned I, auto &IPtr>// #IPTR
+template<typename T, unsigned I, auto &IPtr>
 void TemplFunc() {
   T array[I];
   T array2[2*I];
@@ -73,8 +73,7 @@ void TemplFunc() {
   // expected-note at +1{{to match this '['}}
 #pragma acc parallel private(array[:I:])
   while (true);
-  // expected-error at +2{{no member named 'IPtr' in the global namespace}}
-  // expected-note@#IPTR{{'IPtr' declared here}}
+  // expected-error at +1{{no member named 'IPtr' in the global namespace}}
 #pragma acc parallel private(array[::IPtr])
   while (true);
   // expected-error at +2{{expected ']'}}
diff --git a/clang/test/ParserOpenACC/parse-wait-clause.c b/clang/test/ParserOpenACC/parse-wait-clause.c
index 16e31a67c094f..5c006b4379a27 100644
--- a/clang/test/ParserOpenACC/parse-wait-clause.c
+++ b/clang/test/ParserOpenACC/parse-wait-clause.c
@@ -85,19 +85,16 @@ void func() {
   #pragma acc parallel wait (devnum: i + j:queues:) clause-list
     {}
 
-  // expected-error at +4{{use of undeclared identifier 'devnum'}}
-  // expected-error at +3{{expected ','}}
+  // expected-error at +3{{use of undeclared identifier 'devnum'}}
   // expected-error at +2{{expected ')'}}
   // expected-note at +1{{to match this '('}}
   #pragma acc parallel wait (queues:devnum: i + j
     {}
 
-  // expected-error at +2{{expected ','}}
   // expected-error at +1{{use of undeclared identifier 'devnum'}}
   #pragma acc parallel wait (queues:devnum: i + j)
     {}
 
-  // expected-error at +3{{expected ','}}
   // expected-error at +2{{use of undeclared identifier 'devnum'}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
   #pragma acc parallel wait (queues:devnum: i + j) clause-list
diff --git a/clang/test/ParserOpenACC/parse-wait-construct.c b/clang/test/ParserOpenACC/parse-wait-construct.c
index 491c3bee4ac5a..27a3a02dc2637 100644
--- a/clang/test/ParserOpenACC/parse-wait-construct.c
+++ b/clang/test/ParserOpenACC/parse-wait-construct.c
@@ -68,18 +68,15 @@ void func() {
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
   #pragma acc wait (devnum: i + j:queues:) clause-list
 
-  // expected-error at +4{{use of undeclared identifier 'devnum'}}
-  // expected-error at +3{{expected ','}}
+  // expected-error at +3{{use of undeclared identifier 'devnum'}}
   // expected-error at +2{{expected ')'}}
   // expected-note at +1{{to match this '('}}
   #pragma acc wait (queues:devnum: i + j
 
-  // expected-error at +2{{use of undeclared identifier 'devnum'}}
-  // expected-error at +1{{expected ','}}
+  // expected-error at +1{{use of undeclared identifier 'devnum'}}
   #pragma acc wait (queues:devnum: i + j)
 
-  // expected-error at +3{{use of undeclared identifier 'devnum'}}
-  // expected-error at +2{{expected ','}}
+  // expected-error at +2{{use of undeclared identifier 'devnum'}}
   // expected-error at +1{{invalid OpenACC clause 'clause'}}
   #pragma acc wait (queues:devnum: i + j) clause-list
 
diff --git a/clang/test/Sema/PR28181.c b/clang/test/Sema/PR28181.c
index 8d0a4ad33562a..7e9d5cc91038d 100644
--- a/clang/test/Sema/PR28181.c
+++ b/clang/test/Sema/PR28181.c
@@ -5,9 +5,9 @@ struct spinlock_t {
 } audit_skb_queue;
 
 void fn1(void) {
-  audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
-}                           // expected-error at -1 {{assigning to 'struct spinlock_t' from incompatible type '<overloaded function type>'}}
+  audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'}}
+}
 
 void fn2(void) {
-  audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
-}                           // expected-error at -1 {{reference to overloaded function could not be resolved; did you mean to call it?}}
+  audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'}}
+}
diff --git a/clang/test/Sema/builtin-unary-fp.c b/clang/test/Sema/builtin-unary-fp.c
index fb8e341156a59..9bfcb30b9eba3 100644
--- a/clang/test/Sema/builtin-unary-fp.c
+++ b/clang/test/Sema/builtin-unary-fp.c
@@ -17,5 +17,4 @@ void a(void) {
 
   check(__builtin_fpclassify(0,0,0,0,0, (invalid))); // expected-error{{use of undeclared identifier 'invalid'}}
   check(__builtin_fpclassify(0,0,0,0,0, (inf))); // expected-error{{use of undeclared identifier 'inf'}}
-                                                // expected-error at -1{{reference to overloaded function could not be resolved}}
 }
diff --git a/clang/test/Sema/c23-delayed-typo-correction-crashes.c b/clang/test/Sema/c23-delayed-typo-correction-crashes.c
new file mode 100644
index 0000000000000..6afd3fd32c366
--- /dev/null
+++ b/clang/test/Sema/c23-delayed-typo-correction-crashes.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s
+
+void GH139913(...);
+void GH139913_test() {
+  GH139913(CONCAT(foo, )); // expected-error {{use of undeclared identifier 'CONCAT'}} \
+                              expected-error {{use of undeclared identifier 'foo'}} \
+                              expected-error {{expected expression}}
+}
+
+struct GH137867 {
+ char value;
+};
+void GH137867_test() {
+  _Atomic(struct GH137867) t;
+  while (!atomic_load(&t.value)->value) // expected-error {{use of undeclared identifier 'atomic_load'}} \
+                                           expected-error {{accessing a member of an atomic structure or union is undefined behavior}}
+    ;
+}
diff --git a/clang/test/Sema/delayed-typo-correction-crashes.c b/clang/test/Sema/delayed-typo-correction-crashes.c
new file mode 100644
index 0000000000000..ec75109f8f550
--- /dev/null
+++ b/clang/test/Sema/delayed-typo-correction-crashes.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -ffixed-point -verify %s
+
+void GH137860_test(void) {
+  struct S {
+    char h;
+  };
+  _Atomic struct S s = { .h = UINT8_MIN }; // expected-error {{use of undeclared identifier 'UINT8_MIN'}}
+  __c11_atomic_fetch_add(&s.h, UINT8_MIN); // expected-error {{use of undeclared identifier 'UINT8_MIN'}} \
+                                              expected-error {{accessing a member of an atomic structure or union is undefined behavior}}
+}
+
+int (^GH69470) (int i, int j) = ^(int i, int j)
+{ return i / j; }/ j; // expected-error {{use of undeclared identifier 'j'}}
+
+void GH51210(void) {
+  _Complex int a_1;
+   0.5r / a_2; // expected-error {{use of undeclared identifier 'a_2'}}
+}
+
+void GH69874(void) {
+  *a = (a_struct){0}; // expected-error {{use of undeclared identifier 'a'}} \
+                         expected-error {{use of undeclared identifier 'a_struct'}}
+}
+
+__attribute__((address_space(1))) typedef int *GH140584;
+void topo_print() {
+  GH140584 b1 = topo_parent; // expected-error {{use of undeclared identifier 'topo_parent'}}
+  GH140584 b2;
+  b2 = topo_parent;          // expected-error {{use of undeclared identifier 'topo_parent'}}
+}
diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp
index 57ee187ccf4d5..0e3fec1b18eec 100644
--- a/clang/test/Sema/invalid-member.cpp
+++ b/clang/test/Sema/invalid-member.cpp
@@ -20,10 +20,12 @@ class Z {
 // Should be able to evaluate sizeof without crashing.
 static_assert(sizeof(Z) == 1, "No valid members");
 
-constexpr int N = undef; // expected-error {{use of undeclared identifier}}
+constexpr int N = undef; // expected-error {{use of undeclared identifier}} \
+                            expected-note {{declared here}}
 template<int a>
 class ABC {};
 class T {
-  ABC<N> abc;
+  ABC<N> abc; // expected-error {{non-type template argument is not a constant expression}} \
+                 expected-note {{initializer of 'N' is unknown}}
 };
 static_assert(sizeof(T) == 1, "No valid members");
diff --git a/clang/test/Sema/typo-correction-ambiguity.c b/clang/test/Sema/typo-correction-ambiguity.c
index 0fc18137710d4..1086fed76e222 100644
--- a/clang/test/Sema/typo-correction-ambiguity.c
+++ b/clang/test/Sema/typo-correction-ambiguity.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // Check the following typo correction behavior in C:
 // - no typos are diagnosed when a call expression has ambiguous (multiple) corrections
diff --git a/clang/test/Sema/typo-correction-ambiguity.cpp b/clang/test/Sema/typo-correction-ambiguity.cpp
index 9dcff3d68c823..1cf30c2c80738 100644
--- a/clang/test/Sema/typo-correction-ambiguity.cpp
+++ b/clang/test/Sema/typo-correction-ambiguity.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // Check the following typo correction behavior in namespaces:
 // - no typos are diagnosed when an expression has ambiguous (multiple) corrections
diff --git a/clang/test/Sema/typo-correction-no-hang.c b/clang/test/Sema/typo-correction-no-hang.c
index e6041704ff324..25ca89ca07b1a 100644
--- a/clang/test/Sema/typo-correction-no-hang.c
+++ b/clang/test/Sema/typo-correction-no-hang.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // PR50797
 struct a {
diff --git a/clang/test/Sema/typo-correction-no-hang.cpp b/clang/test/Sema/typo-correction-no-hang.cpp
index 3c591645be25c..04b002f1c39de 100644
--- a/clang/test/Sema/typo-correction-no-hang.cpp
+++ b/clang/test/Sema/typo-correction-no-hang.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // From `test/Sema/typo-correction.c` but for C++ since the behavior varies
 // between the two languages.
diff --git a/clang/test/Sema/typo-correction-recursive.cpp b/clang/test/Sema/typo-correction-recursive.cpp
index b39beb5493f65..b4282f8a84c5e 100644
--- a/clang/test/Sema/typo-correction-recursive.cpp
+++ b/clang/test/Sema/typo-correction-recursive.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // Check the following typo correction behavior:
 // - multiple typos in a single member call chain are all diagnosed
diff --git a/clang/test/Sema/typo-correction.c b/clang/test/Sema/typo-correction.c
index 4157207a9ac42..5244f3f548406 100644
--- a/clang/test/Sema/typo-correction.c
+++ b/clang/test/Sema/typo-correction.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 //
 // This file contains typo correction tests which hit different code paths in C
 // than in C++ and may exhibit different behavior as a result.
diff --git a/clang/test/Sema/var-redecl.c b/clang/test/Sema/var-redecl.c
index 30f1fb229d8c8..2616002ccf390 100644
--- a/clang/test/Sema/var-redecl.c
+++ b/clang/test/Sema/var-redecl.c
@@ -50,11 +50,10 @@ void outer_shadowing_test(void) {
   }
 }
 
-void g18(void) { // expected-note{{'g18' declared here}}
+void g18(void) {
   extern int g19;
 }
-int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}} \
-             // expected-warning{{incompatible pointer types}}
+int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}}
 
 // PR3645
 static int a;
diff --git a/clang/test/SemaCXX/arrow-operator.cpp b/clang/test/SemaCXX/arrow-operator.cpp
index 295dea3c1756c..39a1932ca91e3 100644
--- a/clang/test/SemaCXX/arrow-operator.cpp
+++ b/clang/test/SemaCXX/arrow-operator.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-struct T { 
+struct T {
   void f();
 };
 
@@ -47,23 +47,22 @@ class wrapped_ptr {
  public:
   wrapped_ptr(T* ptr) : ptr_(ptr) {}
   T* operator->() { return ptr_; }
-  void Check(); // expected-note {{'Check' declared here}}
+  void Check();
  private:
   T *ptr_;
 };
 
 class Worker {
  public:
-  void DoSomething(); // expected-note {{'DoSomething' declared here}}
+  void DoSomething();
   void Chuck();
 };
 
 void test() {
   wrapped_ptr<Worker> worker(new Worker);
   worker.DoSomething(); // expected-error {{no member named 'DoSomething' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'; did you mean to use '->' instead of '.'?}}
-  worker.DoSamething(); // expected-error {{no member named 'DoSamething' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'; did you mean to use '->' instead of '.'?}} \
-                        // expected-error {{no member named 'DoSamething' in 'arrow_suggest::Worker'; did you mean 'DoSomething'?}}
-  worker.Chuck(); // expected-error {{no member named 'Chuck' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'; did you mean 'Check'?}}
+  worker.DoSamething(); // expected-error {{no member named 'DoSamething' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'}}
+  worker.Chuck(); // expected-error {{no member named 'Chuck' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'}}
 }
 
 } // namespace arrow_suggest
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 0a135654fab18..9cbc74d5f4cd0 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1888,10 +1888,11 @@ namespace PR15884 {
 }
 
 namespace AfterError {
-  constexpr int error() {
+  constexpr int error() { // pre-cxx23-error {{no return statement in constexpr function}}
     return foobar; // expected-error {{undeclared identifier}}
-  }
-  constexpr int k = error(); // expected-error {{constexpr variable 'k' must be initialized by a constant expression}}
+  } // cxx23-note {{control reached end of constexpr function}}
+  constexpr int k = error(); // cxx23-error {{constexpr variable 'k' must be initialized by a constant expression}} \
+                                cxx23-note {{in call to 'error()'}}
 }
 
 namespace std {
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index 068fdab4bfe38..c9cefeb30c15a 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -8,19 +8,16 @@
 // RUN: not %clang_cc1 -std=c++20 -fsyntax-only %s -fcxx-exceptions -fexceptions -Wunused-result 2>&1 | FileCheck %s
 
 void no_coroutine_traits_bad_arg_await() {
-  co_await a; // expected-error {{include <coroutine>}}
-  // expected-error at -1 {{use of undeclared identifier 'a'}}
+  co_await a; // expected-error {{use of undeclared identifier 'a'}}
 }
 
 void no_coroutine_traits_bad_arg_yield() {
-  co_yield a; // expected-error {{include <coroutine>}}
-  // expected-error at -1 {{use of undeclared identifier 'a'}}
+  co_yield a; // expected-error {{use of undeclared identifier 'a'}}
 }
 
 
 void no_coroutine_traits_bad_arg_return() {
-  co_return a; // expected-error {{include <coroutine>}}
-  // expected-error at -1 {{use of undeclared identifier 'a'}}
+  co_return a; // expected-error {{use of undeclared identifier 'a'}}
 }
 
 void no_coroutine_traits() {
@@ -208,8 +205,7 @@ void mixed_yield() {
 
 void mixed_yield_invalid() {
   co_yield blah; // expected-error {{use of undeclared identifier}}
-  // expected-note at -1 {{function is a coroutine due to use of 'co_yield'}}
-  return; // expected-error {{return statement not allowed in coroutine}}
+  return;
 }
 
 void mixed_yield_return_first(bool b) {
@@ -231,8 +227,7 @@ void mixed_return_for_range(bool b, T t) {
 template <class T>
 void mixed_yield_template(T) {
   co_yield blah; // expected-error {{use of undeclared identifier}}
-  // expected-note at -1 {{function is a coroutine due to use of 'co_yield'}}
-  return; // expected-error {{return statement not allowed in coroutine}}
+  return;
 }
 
 template <class T>
@@ -314,10 +309,9 @@ template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{r
 template <class T>
 void mixed_coreturn_template2(bool b, T) {
   if (b)
-    co_return v; // expected-note {{use of 'co_return'}}
-    // expected-error at -1 {{use of undeclared identifier 'v'}}
+    co_return v; // expected-error {{use of undeclared identifier 'v'}}
   else
-    return; // expected-error {{not allowed in coroutine}}
+    return;
 }
 
 struct promise_handle;
diff --git a/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
new file mode 100644
index 0000000000000..d0ae88ac4e6d6
--- /dev/null
+++ b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace GH138850 {
+void test() {
+  int tmp = add(int, 0, 0);    // expected-error {{expected '(' for function-style cast or type construction}} \
+                                  expected-note {{previous definition is here}}
+  uint tmp = add(uint, 1, 1);  // expected-error {{use of undeclared identifier 'uint'; did you mean 'int'?}} \
+                                  expected-error {{redefinition of 'tmp'}} \
+                                  expected-error {{use of undeclared identifier 'uint'}}
+  call(void, f, (int)tmp);     // expected-error {{expected '(' for function-style cast or type construction}} \
+                                  expected-error {{use of undeclared identifier 'f'}}
+}
+}
+
+namespace GH107840 {
+struct tm {};          // expected-note {{'tm' declared here}}
+
+auto getCache = [&] {  // expected-error {{non-local lambda expression cannot have a capture-default}}
+  ::foo([=] {          // expected-error {{no member named 'foo' in the global namespace}}
+    tms time;          // expected-error {{unknown type name 'tms'; did you mean 'tm'?}}
+    (void)time;
+  });
+};
+}
+
+namespace GH59391 {
+template <typename b> class c {
+  c(b);
+  b e;
+  void f() {
+    for (auto core : a::c(cores)) { // expected-error {{use of undeclared identifier 'cores'}} \
+                                       expected-error {{use of undeclared identifier 'a'}}
+    }
+  }
+};
+}
+
+namespace GH45915 {
+short g_volatile_ushort;
+namespace a {
+   int b = l_volatile_uwchar.a ::c ::~d<>; // expected-error {{use of undeclared identifier 'l_volatile_uwchar'}}
+}
+}
+
+namespace GH45891 {
+int a = b.c < enum , > :: template ~d < > [ e; // expected-error {{use of undeclared identifier 'b'}} \
+                                                  expected-error {{expected identifier or '{'}} \
+                                                  expected-error {{expected ';' after top level declarator}}
+}
+
+namespace GH32903 {
+void
+B(
+  char cat_dog_3, char cat_dog_2, char cat_dog_1, char cat_dog_0, char pigeon_dog_3, char pigeon_dog_2,
+  char pigeon_dog_1, char pigeon_dog_0, short &elefant15_lion, short &elefant14_lion, short &elefant13_lion,
+  short &elefant12_lion, short &elefant11_lion, short &elefant10_lion, short &elefant9_lion, short &elefant8_lion,
+  short &elefant7_lion, short &elefant6_lion, short &elefant5_lion, short &elefant4_lion, short &elefant3_lion,
+  short &elefant2_lion, short &elefant1_lion, short &elefant0_lion, char& no_animal)
+{
+
+    A(  // FIXME: it's surprising that we don't issue a "use of undeclared identifier" diagnostic for the call itself.
+        elefant_15_lion, elefant_14_lion, elefant_13_lion, elefant_12_lion, elefant_11_lion, elefant_10_lion, elefant_9_lion, // expected-error 7 {{use of undeclared identifier}}
+        elefant_8_lion, elefant_7_lion, elefant_6_lion, elefant_5_lion, elefant_4_lion, elefant_3_lion, elefant_2_lion,       // expected-error 7 {{use of undeclared identifier}}
+        elefant_1_lion, elefant_0_lion, no_animal, other_mammal);                                                             // expected-error 3 {{use of undeclared identifier}}
+}
+}
diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp
index 11bc42315421d..669c6706e3c13 100644
--- a/clang/test/SemaCXX/cxx11-crashes.cpp
+++ b/clang/test/SemaCXX/cxx11-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins
+// RUN: %clang_cc1 -std=c++11 -fdelayed-typo-correction -verify %s -Wno-deprecated-builtins
 
 namespace rdar12240916 {
 
diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp
index 5340c6c7d0bf3..55e1e3467018f 100644
--- a/clang/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp
@@ -9,25 +9,25 @@ namespace variadic_expansion {
     f([&a(t)]()->decltype(auto) {
       return a;
     }() ...);
-    
+
     auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
     const int y = 10;
-    auto M = [x = y, 
-                &z = y](T& ... t) { }; 
-    auto N = [x = y, 
-                &z = y, n = f(t...), 
-                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { 
-                  fv([&a(t)]()->decltype(auto) { 
+    auto M = [x = y,
+                &z = y](T& ... t) { };
+    auto N = [x = y,
+                &z = y, n = f(t...),
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) {
+                  fv([&a(t)]()->decltype(auto) {
                     return a;
                   }() ...);
-                };                 
+                };
     auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}}
-                &z = y, n = f(t...), 
+                &z = y, n = f(t...),
                 o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}}
                 fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
                     return a;
                   }() ...);
-                };                 
+                };
 
   }
 
@@ -37,7 +37,7 @@ namespace variadic_expansion {
 namespace odr_use_within_init_capture {
 
 int test() {
-  
+
   { // no captures
     const int x = 10;
     auto L = [z = x + 2](int a) {
@@ -46,14 +46,14 @@ int test() {
       };
       return M;
     };
-        
+
   }
   { // should not capture
     const int x = 10;
     auto L = [&z = x](int a) {
       return a;;
     };
-        
+
   }
   {
     const int x = 10;
@@ -67,9 +67,9 @@ int test() {
   }
   {
     const int x = 10;
-    auto L = [k = x](char a) { 
-      return [=](int b) { 
-        return [j = k](int c) { 
+    auto L = [k = x](char a) {
+      return [=](int b) {
+        return [j = k](int c) {
           return c;
         };
       };
@@ -77,9 +77,9 @@ int test() {
   }
   {
     const int x = 10;
-    auto L = [k = x](char a) { 
-      return [k](int b) { 
-        return [j = k](int c) { 
+    auto L = [k = x](char a) {
+      return [k](int b) {
+        return [j = k](int c) {
           return c;
         };
       };
@@ -106,14 +106,14 @@ int test(T t = T{}) {
       };
       return M;
     };
-        
+
   }
   { // should not capture
     const T x = 10;
     auto L = [&z = x](T a) {
       return a;;
     };
-        
+
   }
   { // will need to capture x in outer lambda
     const T x = 10; //expected-note {{declared}}
@@ -125,19 +125,19 @@ int test(T t = T{}) {
     };
   }
   { // will need to capture x in outer lambda
-    const T x = 10; 
-    auto L = [=,z = x](char a) { 
-      auto M = [&y = x](T b) { 
+    const T x = 10;
+    auto L = [=,z = x](char a) {
+      auto M = [&y = x](T b) {
         return y;
       };
       return M;
     };
-        
+
   }
   { // will need to capture x in outer lambda
-    const T x = 10; 
-    auto L = [x, z = x](char a) { 
-      auto M = [&y = x](T b) { 
+    const T x = 10;
+    auto L = [x, z = x](char a) {
+      auto M = [&y = x](T b) {
         return y;
       };
       return M;
@@ -155,12 +155,12 @@ int test(T t = T{}) {
   {
     // no captures
     const T x = 10;
-    auto L = [z = 
-                  [z = x, &y = x](char a) { return z + y; }('a')](char a) 
+    auto L = [z =
+                  [z = x, &y = x](char a) { return z + y; }('a')](char a)
       { return z; };
-  
+
   }
-  
+
   return 0;
 }
 
@@ -210,9 +210,9 @@ void test(double weight) {
 namespace init_capture_undeclared_identifier {
   auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
 
-  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
-  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
-  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+  int typo_foo;
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'}}
 }
 
 namespace copy_evasion {
diff --git a/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp b/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp
new file mode 100644
index 0000000000000..a16a7f8255f7c
--- /dev/null
+++ b/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+#include "Inputs/std-coroutine.h"
+
+namespace GH58172 {
+template<typename Fn>
+int f2(int, Fn&&)
+{
+  return 0;
+}
+
+int f1()
+{
+  return f2(v1, []() -> task<int> {   // expected-error {{no template named 'task'}} \
+                                         expected-error {{use of undeclared identifier 'v1'}}
+    co_return v2;                     // expected-error {{use of undeclared identifier 'v2'}}
+  });
+}
+}
diff --git a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
index 5c0d89d9125f2..187ab0685b2cd 100644
--- a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
+++ b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
@@ -37,7 +37,7 @@ void disambig() {
   f < 1 + 3 > (q); // ok, function call
 }
 
-bool typo(int something) { // expected-note 4{{declared here}}
+bool typo(int something) { // expected-note 2{{declared here}}
   // FIXME: We shouldn't suggest the N:: for an ADL call if the candidate can be found by ADL.
   some_logn_name<3>(q); // expected-error {{did you mean 'N::some_long_name'?}}
   somethign < 3 ? h() > 4 : h(0); // expected-error {{did you mean 'something'}}
@@ -45,8 +45,8 @@ bool typo(int something) { // expected-note 4{{declared here}}
   somethign < 3 ? h() + 4 : h(0); // expected-error {{did you mean 'something'}}
   // This is parsed as an ADL-only template-id call.
   somethign < 3 ? h() + 4 : h(0) >(0); // expected-error {{undeclared identifier 'somethign'}}
-  bool k(somethign < 3); // expected-error {{did you mean 'something'}}
-  return somethign < 3; // expected-error {{did you mean 'something'}}
+  bool k(somethign < 3); // expected-error {{use of undeclared identifier 'somethign'}}
+  return somethign < 3; // expected-error {{use of undeclared identifier 'somethign'}}
 }
 
 // Ensure that treating undeclared identifiers as template names doesn't cause
@@ -61,7 +61,7 @@ struct A : X<int> { // expected-error {{no template named 'X'}}
 // Similarly for treating overload sets of functions as template names.
 struct g<int> {}; // expected-error {{'g' refers to a function template}}
 g<int>::Y xy; // expected-error {{no template named 'g'}} FIXME lies
-void xf(g<int> x); // expected-error {{variable has incomplete type 'void'}} expected-error 1+{{}} expected-note {{}}
+void xf(g<int> x); // expected-error {{variable has incomplete type 'void'}} expected-error 1+{{}}
 struct B : g<int> { // expected-error {{expected class name}}
   B() : g<int>() {} // expected-error {{expected class member or base class name}}
 };
diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp
index 589616ef8e437..b9e0b17d510ab 100644
--- a/clang/test/SemaCXX/destructor.cpp
+++ b/clang/test/SemaCXX/destructor.cpp
@@ -58,7 +58,7 @@ struct D {
 
 struct D2 {
   void ~D2() { } //                          \
-  // expected-error{{destructor cannot have a return type}}  
+  // expected-error{{destructor cannot have a return type}}
 };
 
 
@@ -86,7 +86,7 @@ struct G {
 G::~G() { }
 
 struct H {
-  ~H(void) { } 
+  ~H(void) { }
 };
 
 struct X {};
@@ -103,7 +103,7 @@ namespace PR6421 {
     template<typename U>
     void foo(T t) // expected-error{{variable has incomplete type}}
     { }
-    
+
     void disconnect()
     {
       T* t;
@@ -364,7 +364,7 @@ struct __is_destructor_wellformed {
                        decltype(_Tp1().~_Tp1())>::type);
   template <typename _Tp1>
   static __two __test (...);
-              
+
   static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
 };
 
@@ -553,14 +553,11 @@ namespace crash_on_invalid_base_dtor {
 struct Test {
   virtual ~Test();
 };
-struct Baz : public Test { // expected-warning {{non-virtual destructor}}
+struct Baz : public Test {
   Baz() {}
-  ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}} \
-                   // expected-error {{initializer on function}} \
-                   // expected-note {{overridden virtual function is here}}
+  ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}}
 };
-struct Foo : public Baz { // expected-error {{cannot override a non-deleted function}} \
-                          // expected-note {{destructor of 'Foo' is implicitly deleted}}
+struct Foo : public Baz {
   Foo() {}
 };
 }
@@ -579,11 +576,9 @@ static_assert(!__is_trivially_constructible(Foo, Foo &&), "");
 
 namespace GH97230 {
 struct X {
-  ~X() = defaul; // expected-error {{initializer on function does not look like a pure-specifier}} \
-                 // expected-error {{use of undeclared identifier 'defaul'}}
+  ~X() = defaul; // expected-error {{use of undeclared identifier 'defaul'}}
 };
-struct Y : X {} y1{ }; // expected-error {{call to implicitly-deleted default constructor of 'struct Y'}} \
-                       // expected-note {{default constructor of 'Y' is implicitly deleted because base class 'X' has no destructor}}
+struct Y : X {} y1{ };
 }
 
 namespace GH121706 {
diff --git a/clang/test/SemaCXX/invalid-if-constexpr.cpp b/clang/test/SemaCXX/invalid-if-constexpr.cpp
index 0007f2739cbbd..c2638ed9c817f 100644
--- a/clang/test/SemaCXX/invalid-if-constexpr.cpp
+++ b/clang/test/SemaCXX/invalid-if-constexpr.cpp
@@ -1,13 +1,13 @@
 // RUN: %clang_cc1 -verify -std=c++20 %s
 
 namespace GH61885 {
-void similar() { // expected-note {{'similar' declared here}}
-  if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'; did you mean 'similar'?}}
+void similar() {
+  if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'}}
 }
-void a() { if constexpr (__adl_swap<>) {}} // expected-error{{use of undeclared identifier '__adl_swap'; did you mean '__sync_swap'?}}
+void a() { if constexpr (__adl_swap<>) {}} // expected-error{{use of undeclared identifier '__adl_swap'}}
 
-int AA() { return true;} // expected-note {{'AA' declared here}}
+int AA() { return true;}
 
-void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'; did you mean 'AA'?}}
+void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'}}
 }
 
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 2d2dde82a28e6..199b165b55edd 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -591,7 +591,7 @@ int func() {
 }
 
 namespace PR30566 {
-int name1; // expected-note {{'name1' declared here}}
+int name1;
 
 struct S1 {
   template<class T>
@@ -601,8 +601,7 @@ struct S1 {
 
 void foo1() {
   auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
-  auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
-                                  // cxx03-cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
+  auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'}}
 }
 }
 
diff --git a/clang/test/SemaCXX/member-expr.cpp b/clang/test/SemaCXX/member-expr.cpp
index 0596e40f6c2f6..902b09097a120 100644
--- a/clang/test/SemaCXX/member-expr.cpp
+++ b/clang/test/SemaCXX/member-expr.cpp
@@ -96,11 +96,11 @@ namespace test5 {
 namespace PR7508 {
   struct A {
     struct CleanupScope {};
-    void PopCleanupBlock(); // expected-note{{'PopCleanupBlock' declared here}}
+    void PopCleanupBlock();
   };
 
   void foo(A &a) {
-    a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'; did you mean 'PopCleanupBlock'?}}
+    a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'}}
   }
 }
 
@@ -189,7 +189,7 @@ namespace PR15045 {
   }
 
   struct bar {
-    void func();  // expected-note {{'func' declared here}}
+    void func();
   };
 
   struct foo {
@@ -207,7 +207,7 @@ namespace PR15045 {
 
     // Show that recovery has happened by also triggering typo correction
     e->Func();  // expected-error {{member reference type 'bar' is not a pointer; did you mean to use '.'?}} \
-                // expected-error {{no member named 'Func' in 'PR15045::bar'; did you mean 'func'?}}
+                // expected-error {{no member named 'Func' in 'PR15045::bar'}}
 
     // Make sure a fixit isn't given in the case that the '->' isn't actually
     // the problem (the problem is with the return value of an operator->).
diff --git a/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp b/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
index 9d05d64ab4062..0b346a4b8094e 100644
--- a/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
+++ b/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fdelayed-typo-correction -Wno-c++11-extensions %s
 
 namespace fizbin { class Foobar {}; } // expected-note 2 {{'fizbin::Foobar' declared here}} \
                                       // expected-note {{'Foobar' declared here}}
diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp
index 981152dda23f5..5a2529dc2bed8 100644
--- a/clang/test/SemaCXX/nested-name-spec.cpp
+++ b/clang/test/SemaCXX/nested-name-spec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s 
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s
 namespace A {
   struct C {
     static int cx;
@@ -111,7 +111,7 @@ void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member mus
 
 namespace E {
   int X = 5;
-  
+
   namespace Nested {
     enum E {
       X = 0
@@ -146,7 +146,7 @@ Operators::operator bool() {
 
 namespace A {
   void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
-} 
+}
 
 void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
 
@@ -303,14 +303,14 @@ struct A2<T>::B::C; // expected-error {{no struct named 'C'}}
 
 namespace PR13033 {
 namespace NS {
- int a; // expected-note {{'NS::a' declared here}}
- int longer_b; //expected-note {{'NS::longer_b' declared here}}
+ int a;
+ int longer_b;
 }
 
 // Suggest adding a namespace qualifier to both variable names even though one
 // is only a single character long.
-int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \
-                           // expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}}
+int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'}} \
+                           // expected-error {{use of undeclared identifier 'longer_b'}}
 }
 
 namespace N {
diff --git a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp b/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
index 304ee92f6a8da..b9fd221c7ece8 100644
--- a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ b/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// Don't crash (PR13394).
+// RUN: %clang_cc1 -fsyntax-only -verify -fdelayed-typo-correction -std=c++11 %s
+// Don't crash (PR13394). The crash was from delayed typo correction, which is
+// why we're enabling that flag for the test.
 
 namespace stretch_v1 {
   struct closure_t {
diff --git a/clang/test/SemaCXX/qualified-id-lookup.cpp b/clang/test/SemaCXX/qualified-id-lookup.cpp
index 8eef6f4182746..18a25cfc61b24 100644
--- a/clang/test/SemaCXX/qualified-id-lookup.cpp
+++ b/clang/test/SemaCXX/qualified-id-lookup.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 namespace Ns {
   int f(); // expected-note{{previous declaration is here}}
 
@@ -44,8 +44,8 @@ namespace N {
   }
 }
 
-void N::f1::foo(int i) { 
-  f1::member = i; 
+void N::f1::foo(int i) {
+  f1::member = i;
   f1::type &ir = i;
 }
 
@@ -83,20 +83,20 @@ namespace a {
 }
 
 // PR clang/3291
-namespace a {  
+namespace a {
   namespace a {   // A1
     namespace a { // A2
-      int i; // expected-note{{'a::a::a::i' declared here}}
+      int i;
     }
   }
 }
 
 void test_a() {
-  a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
+  a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'}}
   a::a::a::i = 4;
   a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
 }
-  
+
 struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
   typedef int type;
 
@@ -123,7 +123,7 @@ namespace test1 {
     }
   };
 
-  template class ClassChecker<int>;  
+  template class ClassChecker<int>;
 }
 
 namespace PR6830 {
diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp
index 7f1af5bbee4f9..6ba3b32e2e743 100644
--- a/clang/test/SemaCXX/return.cpp
+++ b/clang/test/SemaCXX/return.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
+// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fdelayed-typo-correction -fsyntax-only -Wignored-qualifiers -verify
 
 int test1() {
   throw;
@@ -73,7 +73,7 @@ const int ret_array()[4]; // expected-error {{cannot return array}}
 
 namespace PR9328 {
   typedef char *PCHAR;
-  class Test 
+  class Test
   {
     const PCHAR GetName() { return 0; } // expected-warning{{'const' type qualifier on return type has no effect}}
   };
@@ -109,7 +109,7 @@ namespace return_has_expr {
 // pr17759
 namespace ctor_returns_void {
   void f() {}
-  struct S { 
+  struct S {
     S() { return f(); } // expected-error {{constructor 'S' must not return void expression}}
     ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
   };
diff --git a/clang/test/SemaCXX/typo-correction-blocks.c b/clang/test/SemaCXX/typo-correction-blocks.c
index 300a5be3969da..43ec498870f93 100644
--- a/clang/test/SemaCXX/typo-correction-blocks.c
+++ b/clang/test/SemaCXX/typo-correction-blocks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-apple-macosx -fblocks -fsyntax-only -fdelayed-typo-correction -verify %s
 
 extern int h(int *);
 extern void g(int, void (^)(void));
diff --git a/clang/test/SemaCXX/typo-correction-crash.cpp b/clang/test/SemaCXX/typo-correction-crash.cpp
index 2a77c9df505e8..100d0f227a6c7 100644
--- a/clang/test/SemaCXX/typo-correction-crash.cpp
+++ b/clang/test/SemaCXX/typo-correction-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -fdelayed-typo-correction -verify %s
 auto check1() {
   return 1;
   return s; // expected-error {{use of undeclared identifier 's'}}
diff --git a/clang/test/SemaCXX/typo-correction-cxx11.cpp b/clang/test/SemaCXX/typo-correction-cxx11.cpp
index 8c588203cc128..594a5ec3d9038 100644
--- a/clang/test/SemaCXX/typo-correction-cxx11.cpp
+++ b/clang/test/SemaCXX/typo-correction-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fdelayed-typo-correction -fsyntax-only -verify %s
 
 namespace PR23186 {
 decltype(ned);  // expected-error-re {{use of undeclared identifier 'ned'{{$}}}}
diff --git a/clang/test/SemaCXX/typo-correction-delayed.cpp b/clang/test/SemaCXX/typo-correction-delayed.cpp
index fdb1f740fda6a..b6512cd3eec3c 100644
--- a/clang/test/SemaCXX/typo-correction-delayed.cpp
+++ b/clang/test/SemaCXX/typo-correction-delayed.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wno-c++11-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -Wno-c++11-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -std=c++98 -Wno-c++11-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -std=c++11 %s
 
 struct A {};
 struct B {};
diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp
index 45f42c4260358..5b00124576393 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions %s
-// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -std=c++20 %s
+// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -fdelayed-typo-correction %s
+// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -fdelayed-typo-correction -std=c++20 %s
 
 namespace PR21817{
 int a(-rsing[2]); // expected-error {{undeclared identifier 'rsing'; did you mean 'using'?}}
diff --git a/clang/test/SemaCXX/virtuals.cpp b/clang/test/SemaCXX/virtuals.cpp
index 2a22ab9fc2b09..f6f52d51f650c 100644
--- a/clang/test/SemaCXX/virtuals.cpp
+++ b/clang/test/SemaCXX/virtuals.cpp
@@ -58,10 +58,8 @@ struct Base {
 };
 
 struct Derived final : Base {
-  virtual ~Derived() = defaul; // #default
+  virtual ~Derived() = defaul; // expected-error {{use of undeclared identifier 'defaul'}}
 } do_not_crash;
-// expected-error@#default {{initializer on function does not look like a pure-specifier}}
-// expected-error@#default {{use of undeclared identifier 'defaul'}}
 }
 
 namespace VirtualFriend {
diff --git a/clang/test/SemaObjC/call-super-2.m b/clang/test/SemaObjC/call-super-2.m
index 01acff70c2301..7018fd633a9be 100644
--- a/clang/test/SemaObjC/call-super-2.m
+++ b/clang/test/SemaObjC/call-super-2.m
@@ -107,7 +107,7 @@ - (id) initWithInt: (int) i
 @end
 
 @class C;
- at interface A // expected-note {{receiver is instance of class declared here}}
+ at interface A
 - (instancetype)initWithCoder:(A *)coder;
 @end
 
@@ -116,7 +116,7 @@ @interface B : A
 
 @implementation B
 - (instancetype)initWithCoder:(C *)coder {
-  if (0 != (self = [super initWithCode:code])) // expected-error {{use of undeclared identifier 'code'}} expected-warning {{instance method '-initWithCode:' not found}}
+  if (0 != (self = [super initWithCode:code])) // expected-error {{use of undeclared identifier 'code'}}
     return (void *)0;
   return (void *)0;
 }
diff --git a/clang/test/SemaObjC/default-synthesize-2.m b/clang/test/SemaObjC/default-synthesize-2.m
index ec67baf4dd002..ef4d5dde7747b 100644
--- a/clang/test/SemaObjC/default-synthesize-2.m
+++ b/clang/test/SemaObjC/default-synthesize-2.m
@@ -85,7 +85,7 @@ - (id) myMethod {
 
 @interface Test6 
 { 
-  id _var; // expected-note {{'_var' declared here}}
+  id _var;
 } 
 @property (readwrite, assign) id var; 
 @end
diff --git a/clang/test/SemaObjC/error-outof-scope-property-use.m b/clang/test/SemaObjC/error-outof-scope-property-use.m
index 413161c2ef2d4..b7c0e592bb0ad 100644
--- a/clang/test/SemaObjC/error-outof-scope-property-use.m
+++ b/clang/test/SemaObjC/error-outof-scope-property-use.m
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
 // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
 
- at class NSMutableDictionary; // expected-note {{receiver is instance of class declared here}}
+ at class NSMutableDictionary;
 
 @interface LaunchdJobs 
 
- at property (nonatomic,retain) NSMutableDictionary *uuids_jobs; // expected-note {{'_uuids_jobs' declared here}}
+ at property (nonatomic,retain) NSMutableDictionary *uuids_jobs;
 
 @end
 
@@ -14,8 +14,7 @@ @implementation LaunchdJobs
 -(void)job
 {
 
- [uuids_jobs objectForKey]; // expected-error {{use of undeclared identifier 'uuids_jobs'}} \
-                            // expected-warning {{instance method '-objectForKey' not found}}
+ [uuids_jobs objectForKey]; // expected-error {{use of undeclared identifier 'uuids_jobs'}}
 }
 
 
diff --git a/clang/test/SemaObjC/objc-array-literal.m b/clang/test/SemaObjC/objc-array-literal.m
index fc02a70bf187a..01ca039a75e58 100644
--- a/clang/test/SemaObjC/objc-array-literal.m
+++ b/clang/test/SemaObjC/objc-array-literal.m
@@ -65,10 +65,10 @@ id radar15147688(void) {
   return x;
 }
 
-enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}}
+enum XXXYYYZZZType { XXXYYYZZZTypeAny };
 void foo(void) {
   NSArray *array = @[
-    @(XXXYYYZZZTypeA),                 // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}}
-    @(XXXYYYZZZTypeSomethingSomething) // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
+    @(XXXYYYZZZTypeA),                 // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'}}
+    @(XXXYYYZZZTypeSomethingSomething) // FIXME-expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
   ];
 }
diff --git a/clang/test/SemaObjC/objc-dictionary-literal.m b/clang/test/SemaObjC/objc-dictionary-literal.m
index 142765f5e2608..499ab84aaac6e 100644
--- a/clang/test/SemaObjC/objc-dictionary-literal.m
+++ b/clang/test/SemaObjC/objc-dictionary-literal.m
@@ -60,10 +60,10 @@ int main(void) {
 	return 0;
 }
 
-enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}}
+enum XXXYYYZZZType { XXXYYYZZZTypeAny };
 void foo(void) {
   NSDictionary *d = @{
-    @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}}
-    @"F" : @(XXXYYYZZZTypeSomethingSomething), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
+    @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'}}
+    @"F" : @(XXXYYYZZZTypeSomethingSomething),
   };
 }
diff --git a/clang/test/SemaObjC/super.m b/clang/test/SemaObjC/super.m
index a86dc6376e5d9..557f5db1ec6b5 100644
--- a/clang/test/SemaObjC/super.m
+++ b/clang/test/SemaObjC/super.m
@@ -52,7 +52,7 @@ void f(id super) {
 void f0(int super) {
   [super m]; // expected-warning{{receiver type 'int' is not 'id'}}
 }
-void f1(id puper) {  // expected-note {{'puper' declared here}}
+void f1(id puper) {
   [super m]; // expected-error{{use of undeclared identifier 'super'}}
 }
 
diff --git a/clang/test/SemaObjC/synth-provisional-ivars.m b/clang/test/SemaObjC/synth-provisional-ivars.m
index d2eb61a056978..7a41bee0a1c2a 100644
--- a/clang/test/SemaObjC/synth-provisional-ivars.m
+++ b/clang/test/SemaObjC/synth-provisional-ivars.m
@@ -30,7 +30,7 @@ - (int) Meth3 { return PROP3; }  // expected-error {{use of undeclared identifie
 @synthesize PROP3=IVAR;
 
 - (int) Meth4 { return PROP4; }
- at synthesize PROP4=PROP4; // expected-note 4 {{'PROP4' declared here}}
+ at synthesize PROP4=PROP4;
 
 - (int) Meth5 { return bar; }
 @synthesize bar = _bar;
diff --git a/clang/test/SemaObjC/typo-correction-arc.m b/clang/test/SemaObjC/typo-correction-arc.m
index 206d545ae7e37..ed478ee0ba1ee 100644
--- a/clang/test/SemaObjC/typo-correction-arc.m
+++ b/clang/test/SemaObjC/typo-correction-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -Wno-objc-root-class %s -verify
+// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class %s -verify
 
 typedef unsigned long NSUInteger;
 
diff --git a/clang/test/SemaObjC/typo-correction-subscript.m b/clang/test/SemaObjC/typo-correction-subscript.m
index 340f3cfe2743c..70f60c855a90a 100644
--- a/clang/test/SemaObjC/typo-correction-subscript.m
+++ b/clang/test/SemaObjC/typo-correction-subscript.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -Wno-objc-root-class %s -verify
+// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class %s -verify
 
 @class Dictionary;
 
diff --git a/clang/test/SemaObjC/typo-correction.m b/clang/test/SemaObjC/typo-correction.m
index 5635f5f56fcf8..f2d336f3777c0 100644
--- a/clang/test/SemaObjC/typo-correction.m
+++ b/clang/test/SemaObjC/typo-correction.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-runtime=ios
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-runtime=ios -fdelayed-typo-correction
 
 @protocol P
 -(id)description;
diff --git a/clang/test/SemaObjC/undef-arg-super-method-call.m b/clang/test/SemaObjC/undef-arg-super-method-call.m
index 11fd97f2c00d8..b8cbe7f69f2f5 100644
--- a/clang/test/SemaObjC/undef-arg-super-method-call.m
+++ b/clang/test/SemaObjC/undef-arg-super-method-call.m
@@ -11,12 +11,12 @@ @interface DBGViewDebuggerSupport_iOS : DBGViewDebuggerSupport
 @end
 
 @implementation DBGViewDebuggerSupport_iOS
-+ (void)addViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}}
++ (void)addViewLayerInfo:(id)aView;
 {
-    [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}}
+    [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'}}
 }
-- (void)addInstViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}}
+- (void)addInstViewLayerInfo:(id)aView;
 {
-    [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}}
+    [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'}}
 }
 @end
diff --git a/clang/test/SemaObjCXX/typo-correction.mm b/clang/test/SemaObjCXX/typo-correction.mm
index 38624e9cd350f..3fc11bf91666d 100644
--- a/clang/test/SemaObjCXX/typo-correction.mm
+++ b/clang/test/SemaObjCXX/typo-correction.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-objc-root-class
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class
 
 class ClassA {};
 
diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
index c6dbe4db2be64..0cf27666dd030 100644
--- a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
@@ -119,8 +119,7 @@ struct HasInt {
 
 template <typename T>
 void TestInst() {
-  // expected-error at +2{{no member named 'Invalid' in 'HasInt'}}
-  // expected-error at +1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}}
+  // expected-error at +1{{no member named 'Invalid' in 'HasInt'}}
 #pragma acc serial num_gangs(HasInt::Invalid)
   while(1);
 
@@ -137,8 +136,7 @@ void TestInst() {
 #pragma acc parallel num_gangs(T::Invalid, 1)
   while(1);
 
-  // expected-error at +2{{no member named 'Invalid' in 'HasInt'}}
-  // expected-error at +1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}}
+  // expected-error at +1{{no member named 'Invalid' in 'HasInt'}}
 #pragma acc serial num_gangs(1, HasInt::Invalid)
   while(1);
 
diff --git a/clang/test/SemaOpenCL/atomic-ops.cl b/clang/test/SemaOpenCL/atomic-ops.cl
index 7a273546db772..d9b24f16ddecc 100644
--- a/clang/test/SemaOpenCL/atomic-ops.cl
+++ b/clang/test/SemaOpenCL/atomic-ops.cl
@@ -167,7 +167,6 @@ void syncscope_checks(atomic_int *Ap, int scope) {
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_all_devices);
 #if __OPENCL_C_VERSION__ < CL_VERSION_3_0
   // expected-error at -2{{use of undeclared identifier 'memory_scope_all_devices'}}
-  // expected-note@* {{'memory_scope_all_svm_devices' declared here}}
 #endif
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_sub_group);
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope);
diff --git a/clang/test/SemaOpenCL/clang-builtin-version.cl b/clang/test/SemaOpenCL/clang-builtin-version.cl
index ec6eecee3106c..21cbf2d8f28d4 100644
--- a/clang/test/SemaOpenCL/clang-builtin-version.cl
+++ b/clang/test/SemaOpenCL/clang-builtin-version.cl
@@ -17,12 +17,8 @@ kernel void dse_builtins(void) {
   });
 #if (__OPENCL_C_VERSION__ >= CL_VERSION_3_0) && !defined(__opencl_c_device_enqueue)
 // expected-error at -10{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}}
-// FIXME: the typo correction for the undeclared identifiers finds alternative
-// suggestions, but instantiating the typo correction causes us to
-// re-instantiate the argument to the call, which triggers the support
-// diagnostic a second time.
-// expected-error at -12 2{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}}
-// expected-error at -10 2{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}}
+// expected-error at -8 {{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}}
+// expected-error at -6 {{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}}
 #endif
 }
 
diff --git a/clang/test/SemaTemplate/concepts-recovery-expr.cpp b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
index b338f3bc271bf..485598492757c 100644
--- a/clang/test/SemaTemplate/concepts-recovery-expr.cpp
+++ b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++20 -fdelayed-typo-correction -verify %s
 
 // expected-error at +1{{use of undeclared identifier 'b'}}
 constexpr bool CausesRecoveryExpr = b;
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index f335ca3bd22bc..742cde3679300 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -814,11 +814,7 @@ static_assert(invalid<int> also here ; // expected-error{{use of undeclared iden
 
 int foo() {
     bool b;
-    b = invalid<int> not just in declarations; // expected-error{{expected ';' after expression}}
-                                               // expected-error at -1{{use of undeclared identifier 'invalid'}}
-                                               // expected-error at -2{{expected ';' after expression}}
-                                               // expected-error at -3{{use of undeclared identifier 'just'}}
-                                               // expected-error at -4{{unknown type name 'in'}}
+    b = invalid<int> not just in declarations; // expected-error{{use of undeclared identifier 'invalid'}}
     return b;
 }
 } // namespace GH48182
diff --git a/clang/test/SemaTemplate/dependent-typos-recovery.cpp b/clang/test/SemaTemplate/dependent-typos-recovery.cpp
index 3f89ca1dbec95..c95921e8a4515 100644
--- a/clang/test/SemaTemplate/dependent-typos-recovery.cpp
+++ b/clang/test/SemaTemplate/dependent-typos-recovery.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
 // There should be no extra errors about missing 'template' keywords.
 struct B {
diff --git a/clang/test/SemaTemplate/typo-variadic.cpp b/clang/test/SemaTemplate/typo-variadic.cpp
index c9b777aebbe91..48306fb9ce805 100644
--- a/clang/test/SemaTemplate/typo-variadic.cpp
+++ b/clang/test/SemaTemplate/typo-variadic.cpp
@@ -1,2 +1,2 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify
-int x = m(s...); // expected-error{{pack expansion does not}} expected-error{{undeclared identifier}}
+int x = m(s...); // expected-error{{undeclared identifier}}

>From 88ad970d82bc740aff2c607b2a62ecec0275cc90 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Mon, 2 Jun 2025 12:27:09 -0400
Subject: [PATCH 02/11] Get the modules diagnostics back again

This corrects non-delayed typos more aggressively which improves
diagnostic output for the most part, but did expose a few more crashes
---
 clang/lib/Sema/SemaExpr.cpp                   |  7 +-
 clang/lib/Sema/SemaOverload.cpp               |  6 +-
 clang/test/AST/ByteCode/literals.cpp          |  8 ++-
 .../test/CXX/class.access/class.friend/p1.cpp | 16 ++---
 clang/test/CXX/class.access/p6.cpp            |  4 +-
 .../basic.namespace/namespace.def/p8.cpp      |  8 +--
 clang/test/CXX/drs/cwg14xx.cpp                |  6 +-
 clang/test/CXX/drs/cwg2xx.cpp                 |  3 +-
 .../test/CXX/module/basic/basic.link/p2.cppm  |  4 +-
 clang/test/CXX/module/module.interface/p2.cpp | 12 ++--
 .../temp.class/temp.mem.enum/p1.cpp           |  6 +-
 clang/test/Modules/auto-module-import.m       |  9 +--
 clang/test/Modules/cxx-templates.cpp          |  2 +-
 clang/test/Modules/normal-module-map.cpp      |  7 +-
 clang/test/Modules/subframeworks.m            |  3 +-
 clang/test/Modules/submodule-visibility.cpp   |  7 +-
 clang/test/Modules/submodules-merge-defs.cpp  |  7 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 .../distribute_simd_linear_messages.cpp       |  6 +-
 clang/test/OpenMP/for_linear_messages.cpp     |  4 +-
 .../test/OpenMP/for_simd_linear_messages.cpp  |  4 +-
 .../masked_taskloop_simd_linear_messages.cpp  |  4 +-
 .../master_taskloop_simd_linear_messages.cpp  |  4 +-
 .../OpenMP/parallel_for_linear_messages.cpp   |  4 +-
 .../parallel_for_simd_linear_messages.cpp     |  4 +-
 ...l_masked_taskloop_simd_linear_messages.cpp |  4 +-
 ...l_master_taskloop_simd_linear_messages.cpp |  4 +-
 clang/test/OpenMP/simd_linear_messages.cpp    |  4 +-
 clang/test/OpenMP/target_map_messages.cpp     |  8 ++-
 .../target_parallel_for_linear_messages.cpp   |  4 +-
 ...rget_parallel_for_simd_linear_messages.cpp |  4 +-
 .../OpenMP/target_simd_linear_messages.cpp    |  4 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 ..._teams_distribute_simd_linear_messages.cpp |  4 +-
 .../OpenMP/taskloop_simd_linear_messages.cpp  |  4 +-
 ...bute_parallel_for_simd_linear_messages.cpp |  4 +-
 .../teams_distribute_simd_linear_messages.cpp |  4 +-
 clang/test/PCH/race-condition.cpp             |  6 +-
 clang/test/Parser/cxx-invalid-for-range.cpp   |  4 +-
 clang/test/Parser/cxx1z-decomposition.cpp     |  6 +-
 .../ParserOpenACC/parse-cache-construct.cpp   |  4 +-
 clang/test/ParserOpenACC/parse-constructs.cpp | 12 ++--
 clang/test/ParserOpenACC/parse-sub-array.cpp  |  5 +-
 .../Sema/delayed-typo-correction-crashes.c    | 12 ----
 clang/test/Sema/var-redecl.c                  |  5 +-
 clang/test/SemaCXX/conversion-function.cpp    |  2 +-
 .../cxx-delayed-typo-correction-crashes.cpp   | 11 +--
 clang/test/SemaCXX/cxx1y-init-captures.cpp    | 70 +++++++++----------
 clang/test/SemaCXX/cxx1z-decomposition.cpp    |  3 +-
 .../SemaCXX/cxx2a-adl-only-template-id.cpp    |  6 +-
 clang/test/SemaCXX/invalid-if-constexpr.cpp   | 12 ++--
 clang/test/SemaCXX/lambda-expressions.cpp     |  5 +-
 clang/test/SemaCXX/nested-name-spec.cpp       | 20 +++---
 clang/test/SemaCXX/qualified-id-lookup.cpp    | 16 ++---
 clang/test/SemaObjC/call-super-2.m            |  6 +-
 clang/test/SemaObjC/default-synthesize-2.m    |  2 +-
 .../SemaObjC/error-outof-scope-property-use.m |  7 +-
 clang/test/SemaObjC/objc-array-literal.m      |  6 +-
 clang/test/SemaObjC/objc-dictionary-literal.m |  6 +-
 clang/test/SemaObjC/super.m                   |  2 +-
 clang/test/SemaObjC/synth-provisional-ivars.m |  2 +-
 clang/test/SemaObjC/typo-correction-arc.m     |  2 +-
 clang/test/SemaObjC/typo-correction.m         |  2 +-
 .../SemaObjCXX/block-for-lambda-conversion.mm |  7 +-
 clang/test/SemaOpenCL/atomic-ops.cl           |  1 +
 .../unittests/Sema/ExternalSemaSourceTest.cpp |  2 +-
 66 files changed, 237 insertions(+), 208 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 21bd7315e3dd4..419612cf2fdb6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2627,9 +2627,10 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
         nullptr, CorrectTypoKind::ErrorRecovery, LookupCtx);
     if (*Out)
       return true;
-  } else if (S && (Corrected = CorrectTypo(
-                       R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
-                       CorrectTypoKind::ErrorRecovery, LookupCtx))) {
+  }
+  if (S && (Corrected =
+                CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
+                            CCC, CorrectTypoKind::ErrorRecovery, LookupCtx))) {
     std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
     bool DroppedSpecifier =
         Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 69768dd3a7212..37ed55fb08d70 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -13968,8 +13968,10 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
     //   specified and it, along with any default template arguments,
     //   identifies a single function template specialization, then the
     //   template-id is an lvalue for the function template specialization.
-    FunctionTemplateDecl *FunctionTemplate
-      = cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl());
+    FunctionTemplateDecl *FunctionTemplate =
+        dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl());
+    if (!FunctionTemplate)
+      continue;
 
     // C++ [over.over]p2:
     //   If the name is a function template, template argument deduction is
diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp
index 2fa7b69b93470..699746c0b2c4a 100644
--- a/clang/test/AST/ByteCode/literals.cpp
+++ b/clang/test/AST/ByteCode/literals.cpp
@@ -910,7 +910,8 @@ namespace CompoundLiterals {
   constexpr int f2(int *x =(int[]){1,2,3}) {
     return x[0];
   }
-  constexpr int g = f2(); // Should evaluate to 1?
+  // Should evaluate to 1?
+  constexpr int g = f2(); // #g_decl
   static_assert(g == 1, "");
 
   // This example should be rejected because the lifetime of the compound
@@ -1347,7 +1348,10 @@ namespace NTTP {
 namespace UnaryOpError {
   constexpr int foo() {
     int f = 0;
-    ++g; // both-error {{use of undeclared identifier 'g'}}
+    ++g; // both-error {{use of undeclared identifier 'g'}} \
+            both-error {{cannot assign to variable 'g' with const-qualified type 'const int'}} \
+            both-note@#g_decl {{'CompoundLiterals::g' declared here}} \
+            both-note@#g_decl {{variable 'g' declared const here}}
     return f;
   }
 }
diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp
index 01d9405dcdb73..4b18036365c1c 100644
--- a/clang/test/CXX/class.access/class.friend/p1.cpp
+++ b/clang/test/CXX/class.access/class.friend/p1.cpp
@@ -11,7 +11,7 @@
 //   friends members of the befriending class.
 
 struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
-S* g() { return 0; }
+S* g() { return 0; } // expected-note 2 {{'g' declared here}}
 
 struct X {
   friend struct S;
@@ -22,7 +22,7 @@ void test1() {
   S s;
   g()->f();
   S::f();
-  X::g(); // expected-error{{no member named 'g' in 'X'}}
+  X::g(); // expected-error{{no member named 'g' in 'X'; did you mean simply 'g'?}}
   X::S x_s; // expected-error{{no type named 'S' in 'X'; did you mean simply 'S'?}}
   X x;
   x.g(); // expected-error{{no member named 'g' in 'X'}}
@@ -40,22 +40,22 @@ namespace N {
   };
 
   struct S2 { static void f2(); }; // expected-note 2 {{'S2' declared here}}
-  S2* g2() { return 0; }
+  S2* g2() { return 0; } // expected-note 2 {{'g2' declared here}}
 
   void test() {
     g()->f();
     S s;
     S::f();
-    X::g(); // expected-error{{no member named 'g' in 'N::X'}}
+    X::g(); // expected-error{{no member named 'g' in 'N::X'; did you mean simply 'g'?}}
     X::S x_s; // expected-error{{no type named 'S' in 'N::X'; did you mean simply 'S'?}}
     X x;
     x.g(); // expected-error{{no member named 'g' in 'N::X'}}
 
     g2();
     S2 s2;
-    ::g2(); // expected-error{{no member named 'g2' in the global namespace}}
+    ::g2(); // expected-error{{no member named 'g2' in the global namespace; did you mean simply 'g2'?}}
     ::S2 g_s2; // expected-error{{no type named 'S2' in the global namespace; did you mean simply 'S2'?}}
-    X::g2(); // expected-error{{no member named 'g2' in 'N::X'}}
+    X::g2(); // expected-error{{no member named 'g2' in 'N::X'; did you mean simply 'g2'?}}
     X::S2 x_s2; // expected-error{{no type named 'S2' in 'N::X'; did you mean simply 'S2'?}}
     x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}
   }
@@ -139,7 +139,7 @@ namespace test2 {
   struct ilist_walker {
     static X *getPrev(X *N) { return N->getPrev(); }
     static X *getNext(X *N) { return N->getNext(); }
-  };
+  };  
 
   struct ilist_walker_bad {
     static X *getPrev(X *N) { return N->getPrev(); } // \
@@ -147,7 +147,7 @@ namespace test2 {
 
     static X *getNext(X *N) { return N->getNext(); } // \
     // expected-error {{'getNext' is a private member of 'test2::ilist_node'}}
-  };
+  };  
 }
 
 namespace test3 {
diff --git a/clang/test/CXX/class.access/p6.cpp b/clang/test/CXX/class.access/p6.cpp
index face8ef177589..15f2644f6ac1d 100644
--- a/clang/test/CXX/class.access/p6.cpp
+++ b/clang/test/CXX/class.access/p6.cpp
@@ -92,7 +92,7 @@ namespace test3 {
 
   template <class T> class Outer::A<T, typename T::nature> {
   public:
-    static void foo();
+    static void foo(); // expected-note {{'Outer::A<test3::B, test3::Green>::foo' declared here}}
   };
 
   class B {
@@ -102,7 +102,7 @@ namespace test3 {
 
   void test() {
     Outer::A<B, Green>::foo();
-    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'}}
+    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<test3::B, test3::Green>::foo'?}}
   }
 }
 
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
index 03eb9aebd7402..3b2c48920b37b 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
@@ -3,7 +3,7 @@
 // Fun things you can do with inline namespaces:
 
 inline namespace X {
-  void f1();
+  void f1(); // expected-note {{'f1' declared here}}
 
   inline namespace Y {
     void f2();
@@ -21,7 +21,7 @@ void foo1() {
   f1();
   ::f1();
   X::f1();
-  Y::f1(); // expected-error {{no member named 'f1' in namespace 'Y'}}
+  Y::f1(); // expected-error {{no member named 'f1' in namespace 'Y'; did you mean simply 'f1'?}}
 
   f2();
   ::f2();
@@ -90,7 +90,7 @@ namespace redecl { inline namespace n1 {
   {
   public:
       typedef Tp& reference;
-
+  
       void allocate(allocator<void>::const_pointer = 0);
   };
 
@@ -99,7 +99,7 @@ namespace redecl { inline namespace n1 {
 // Normal redeclarations (not for explicit instantiations or
 // specializations) are distinct in an inline namespace vs. not in an
 // inline namespace.
-namespace redecl2 {
+namespace redecl2 { 
   inline namespace n1 {
     void f(int) { }
     struct X1 { };
diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp
index 12de8722a8e1b..17d5c2fc2e210 100644
--- a/clang/test/CXX/drs/cwg14xx.cpp
+++ b/clang/test/CXX/drs/cwg14xx.cpp
@@ -21,19 +21,23 @@ namespace cwg1413 { // cwg1413: 12
       // expected-error at -1 {{use of undeclared identifier 'var1'}}
 
       // ok, variable declaration
-      Check<true ? 0 : a>::type *var2;
+      Check<true ? 0 : a>::type *var2; // #cwg1413-var2
       Check<true ? 0 : b>::type *var3;
       // expected-error at -1 {{use of undeclared identifier 'var3'}}
+      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
       Check<true ? 0 : ((void)c, 0)>::type *var4;
       // expected-error at -1 {{use of undeclared identifier 'var4'}}
+      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
 
       // value-dependent because of the implied type-dependent 'this->', not because of 'd'
       Check<true ? 0 : (d(), 0)>::type *var5;
       // expected-error at -1 {{use of undeclared identifier 'var5'}}
+      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
 
       // value-dependent because of the value-dependent '&' operator, not because of 'A::d'
       Check<true ? 0 : (&A::d(), 0)>::type *var5;
       // expected-error at -1 {{use of undeclared identifier 'var5'}}
+      //   expected-note@#cwg1413-var2 {{'var2' declared here}}
     }
   };
 } // namespace cwg1413
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index f664b4bee284d..a53a8d1ed64a8 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -588,7 +588,8 @@ namespace cwg231 { // cwg231: 2.7
     }
     void f() { using namespace inner; }
     int j = i;
-    // expected-error at -1 {{use of undeclared identifier 'i'}}
+    // expected-error at -1 {{use of undeclared identifier 'i'; did you mean 'inner::i'?}}
+    //   expected-note@#cwg231-i {{'inner::i' declared here}}
   }
 } // namespace cwg231
 
diff --git a/clang/test/CXX/module/basic/basic.link/p2.cppm b/clang/test/CXX/module/basic/basic.link/p2.cppm
index c70abdc461502..6a2c67526c9a1 100644
--- a/clang/test/CXX/module/basic/basic.link/p2.cppm
+++ b/clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -51,7 +51,7 @@ void use_from_module_impl() {
   (void)external_linkage_var;
   (void)module_linkage_var;
 
-  (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}}
+  (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} // expected-note@* {{}}
   (void)internal_linkage_var; // expected-error {{use of undeclared identifier 'internal_linkage_var'}}
 }
 
@@ -64,7 +64,7 @@ void use_from_module_impl() {
   internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} // expected-note@* {{}}
-  (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}}
+  (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} // expected-note@* {{}}
   (void)external_linkage_var;
   (void)module_linkage_var; // expected-error {{undeclared identifier}}
   (void)internal_linkage_var; // expected-error {{undeclared identifier}}
diff --git a/clang/test/CXX/module/module.interface/p2.cpp b/clang/test/CXX/module/module.interface/p2.cpp
index 36c2b9baf5e10..4f06b9f386869 100644
--- a/clang/test/CXX/module/module.interface/p2.cpp
+++ b/clang/test/CXX/module/module.interface/p2.cpp
@@ -72,15 +72,18 @@ import "header.h";
 
 void use() {
   // namespace A is implicitly exported by the export of A::g.
-  A::f(); // expected-error {{no member named 'f' in namespace 'A'}}
+  A::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
+          // expected-note@* {{declaration here is not visible}}
   A::g();
-  A::h();                   // expected-error {{no member named 'h' in namespace 'A'}}
+  A::h();                   // expected-error {{declaration of 'h' must be imported from module 'p2' before it is required}}
+                            // expected-note@* {{declaration here is not visible}}
   using namespace A::inner; // expected-error {{declaration of 'inner' must be imported from module 'p2' before it is required}}
 
   // namespace B and B::inner are explicitly exported
   using namespace B;
   using namespace B::inner;
-  B::f(); // expected-error {{no member named 'f' in namespace 'B'}}
+  B::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
+          // expected-note@* {{declaration here is not visible}}
   f();    // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
           // expected-note@* {{declaration here is not visible}}
 
@@ -88,7 +91,8 @@ void use() {
   using namespace C; // expected-error {{declaration of 'C' must be imported from module 'p2' before it is required}}
 
   // namespace D is exported, but D::f is not
-  D::f(); // expected-error {{no member named 'f' in namespace 'D'}}
+  D::f(); // expected-error {{declaration of 'f' must be imported from module 'p2' before it is required}}
+          // expected-note@* {{declaration here is not visible}}
 }
 
 int use_header() { return foo + bar::baz(); }
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
index 2da1592c57b84..e5807993a7a18 100644
--- a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
@@ -12,7 +12,7 @@ A<int> a;
 A<int>::E a0 = A<int>().v;
 int n = A<int>::E::e1; // expected-error {{implicit instantiation of undefined member}}
 
-template<typename T> enum A<T>::E : T { e1, e2 };
+template<typename T> enum A<T>::E : T { e1, e2 }; // expected-note 2 {{declared here}}
 
 // FIXME: Now that A<T>::E is defined, we are supposed to inject its enumerators
 // into the already-instantiated class A<T>. This seems like a really bad idea,
@@ -20,7 +20,7 @@ template<typename T> enum A<T>::E : T { e1, e2 };
 //
 // Either do as the standard says, or only include enumerators lexically defined
 // within the class in its scope.
-A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'}}
+A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'; did you mean simply 'e1'?}}
 
 A<char>::E a2 = A<char>::e2;
 
@@ -94,7 +94,7 @@ D<int>::E d1 = D<int>::E::e1; // expected-error {{incomplete type 'D<int>::E'}}
 template<> enum class D<int>::E { e2 };
 D<int>::E d2 = D<int>::E::e2;
 D<char>::E d3 = D<char>::E::e1; // expected-note {{first required here}}
-D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'}}
+D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'; did you mean simply 'e2'?}}
 template<> enum class D<char>::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}}
 
 template<> enum class D<short>::E;
diff --git a/clang/test/Modules/auto-module-import.m b/clang/test/Modules/auto-module-import.m
index dd1a367f7b2e7..cfbb28fa20e66 100644
--- a/clang/test/Modules/auto-module-import.m
+++ b/clang/test/Modules/auto-module-import.m
@@ -28,7 +28,8 @@
 
 void testSubframeworkOther(void) {
 #ifdef ERRORS
-  double *sfo1 = sub_framework_other; // expected-error{{use of undeclared identifier 'sub_framework_other'}}
+  double *sfo1 = sub_framework_other; // expected-error{{declaration of 'sub_framework_other' must be imported from module 'DependsOnModule.SubFramework.Other'}}
+  // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h:15 {{not visible}}
 #endif
 }
 
@@ -46,8 +47,7 @@ void testSubframeworkOther(void) {
 #endif
 
 void testSubframeworkOtherAgain(void) {
-  // FIXME: this diagnostic should be triggered consistently.
-  double *sfo1 = sub_framework_other; // expected-error 0+{{use of undeclared identifier 'sub_framework_other'}}
+  double *sfo1 = sub_framework_other;
 }
 
 void testModuleSubFramework(void) {
@@ -72,7 +72,8 @@ void testModuleSubFrameworkAgain(void) {
 #include <NoUmbrella/A_Private.h> // expected-remark{{treating #include as an import of module 'NoUmbrella.Private.A_Private'}}
 int getNoUmbrellaAPrivate(void) { return no_umbrella_A_private; }
 
-int getNoUmbrellaBPrivateFail(void) { return no_umbrella_B_private; } // expected-error{{use of undeclared identifier 'no_umbrella_B_private'}}
+int getNoUmbrellaBPrivateFail(void) { return no_umbrella_B_private; } // expected-error{{declaration of 'no_umbrella_B_private' must be imported from module 'NoUmbrella.Private.B_Private'}}
+// expected-note at Inputs/NoUmbrella.framework/PrivateHeaders/B_Private.h:1 {{not visible}}
 
 // Test inclusion of headers that are under an umbrella directory but
 // not actually part of the module.
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index d7938f51985cc..f587af4beb7ce 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -200,7 +200,7 @@ namespace hidden_specializations {
     // For enums, uses that would trigger instantiations of definitions are not
     // allowed.
     cls<void>::nested_enum e; // ok
-    (void)cls<void>::nested_enum::e; // expected-error 1+{{definition of 'nested_enum' must be imported}} expected-error 1+{{no member named 'e' in 'hidden_specializations::cls<void>::nested_enum'}}
+    (void)cls<void>::nested_enum::e; // expected-error 1+{{definition of 'nested_enum' must be imported}} expected-error 1+{{declaration of 'e'}}
 
     // For variable template specializations, no uses are allowed because
     // specializations can change the type.
diff --git a/clang/test/Modules/normal-module-map.cpp b/clang/test/Modules/normal-module-map.cpp
index 9b249786dbbc0..1f4e3e57d20e8 100644
--- a/clang/test/Modules/normal-module-map.cpp
+++ b/clang/test/Modules/normal-module-map.cpp
@@ -2,8 +2,8 @@
 // RUN: %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/normal-module-map %s -verify
 #include "Umbrella/umbrella_sub.h"
 
-int getUmbrella(void) {
-  return umbrella + umbrella_sub;
+int getUmbrella(void) { 
+  return umbrella + umbrella_sub; 
 }
 
 @import Umbrella2;
@@ -24,7 +24,8 @@ int testNestedUmbrellaA(void) {
 
 int testNestedUmbrellaBFail(void) {
   return nested_umbrella_b;
-  // expected-error at -1{{use of undeclared identifier 'nested_umbrella_b'}}
+  // expected-error at -1{{declaration of 'nested_umbrella_b' must be imported from module 'nested_umbrella.b' before it is required}}
+  // expected-note at Inputs/normal-module-map/nested_umbrella/b.h:1{{here}}
 }
 
 @import nested_umbrella.b;
diff --git a/clang/test/Modules/subframeworks.m b/clang/test/Modules/subframeworks.m
index cd6e1a40c9ee4..cf94c5e3549f6 100644
--- a/clang/test/Modules/subframeworks.m
+++ b/clang/test/Modules/subframeworks.m
@@ -5,7 +5,8 @@
 @import DependsOnModule;
 
 void testSubFramework(void) {
-  float *sf1 = sub_framework; // expected-error{{use of undeclared identifier 'sub_framework'}}
+  float *sf1 = sub_framework; // expected-error{{declaration of 'sub_framework' must be imported from module 'DependsOnModule.SubFramework' before it is required}}
+  // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h:2 {{here}}
 }
 
 @import DependsOnModule.SubFramework;
diff --git a/clang/test/Modules/submodule-visibility.cpp b/clang/test/Modules/submodule-visibility.cpp
index dad19ae50a780..6a1a816ed67e5 100644
--- a/clang/test/Modules/submodule-visibility.cpp
+++ b/clang/test/Modules/submodule-visibility.cpp
@@ -28,7 +28,8 @@
 // The use of -fmodule-name=x causes us to textually include the above headers.
 // The submodule visibility rules are still applied in this case.
 //
-// expected-error at b.h:1 {{use of undeclared identifier 'n'}}
+// expected-error at b.h:1 {{missing '#include "a.h"'; 'n' must be declared}}
+// expected-note at a.h:1 {{here}}
 #endif
 
 int k = n + m; // OK, a and b are visible here.
@@ -44,8 +45,8 @@ int k = n + m; // OK, a and b are visible here.
 // Ensure we don't compute the linkage of this struct before we find it has a
 // typedef name for linkage purposes.
 typedef struct {
-  int p;
-  void (*f)(int p);
+  int p;                 
+  void (*f)(int p);                                                                       
 } name_for_linkage;
 
 void g() { b_template<int>(); }
diff --git a/clang/test/Modules/submodules-merge-defs.cpp b/clang/test/Modules/submodules-merge-defs.cpp
index c4a51ebfe4584..0a54699a96723 100644
--- a/clang/test/Modules/submodules-merge-defs.cpp
+++ b/clang/test/Modules/submodules-merge-defs.cpp
@@ -48,11 +48,10 @@ int pre_fg = F<int>().g<int>(); // expected-error +{{must be declared}}
 // expected-note at defs.h:34 +{{here}}
 
 G::A pre_ga // expected-error +{{must be declared}}
-  = G::a; // expected-error +{{no member named 'a' in namespace 'G'}}
+  = G::a; // expected-error +{{must be declared}}
 // expected-note at defs.h:50 +{{here}}
-decltype(G::h) pre_gh = G::h; // expected-error +{{no member named 'h' in namespace 'G'}}
-// FIXME: some of the RUN lines emit this note, textual ones do not.
-// expected-note at defs.h:51 0+{{here}}
+decltype(G::h) pre_gh = G::h; // expected-error +{{must be declared}} expected-error +{{must be defined}}
+// expected-note at defs.h:51 +{{here}}
 
 int pre_h = H(); // expected-error +{{must be declared}}
 // expected-note at defs.h:56 +{{here}}
diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index a8efe0f414333..08d745f3b1a07 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -46,7 +46,7 @@ void test_linear_colons()
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/distribute_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
index daf15ffd935a3..64bcdb4812979 100644
--- a/clang/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -40,13 +40,13 @@ void test_linear_colons()
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier}}
+#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/for_linear_messages.cpp b/clang/test/OpenMP/for_linear_messages.cpp
index 84c2c1e6baf77..2e10230630adb 100644
--- a/clang/test/OpenMP/for_linear_messages.cpp
+++ b/clang/test/OpenMP/for_linear_messages.cpp
@@ -20,7 +20,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -37,7 +37,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp for linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp for linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/for_simd_linear_messages.cpp b/clang/test/OpenMP/for_simd_linear_messages.cpp
index 787c499db34d6..30c6f7274b5da 100644
--- a/clang/test/OpenMP/for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -35,7 +35,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp for simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp for simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
index 064ce1ec0a3fd..f67af47fc1dfb 100644
--- a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp masked taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp masked taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
index 18fbaa682b205..555c81c34c703 100644
--- a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp master taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp master taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_for_linear_messages.cpp b/clang/test/OpenMP/parallel_for_linear_messages.cpp
index c36ac5dffe22d..ba80c8e1ce689 100644
--- a/clang/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_linear_messages.cpp
@@ -18,7 +18,7 @@ int x;
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -36,7 +36,7 @@ void test_linear_colons() {
 #pragma omp parallel for linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
 #pragma omp parallel for linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
index b7a68eac91732..7d540bcac8640 100644
--- a/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -17,7 +17,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -34,7 +34,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel for simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp parallel for simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
index f76d31c6a0d74..a3befd481aa90 100644
--- a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel masked taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp parallel masked taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
index 6c5a1f76b7619..b406f36df167b 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp parallel master taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp parallel master taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/simd_linear_messages.cpp b/clang/test/OpenMP/simd_linear_messages.cpp
index 3055999994020..3ce4de697de0c 100644
--- a/clang/test/OpenMP/simd_linear_messages.cpp
+++ b/clang/test/OpenMP/simd_linear_messages.cpp
@@ -17,7 +17,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -34,7 +34,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp
index 91006860ee2b8..911031d5412a9 100644
--- a/clang/test/OpenMP/target_map_messages.cpp
+++ b/clang/test/OpenMP/target_map_messages.cpp
@@ -136,7 +136,7 @@ struct SA {
     {}
     #pragma omp target map(self, tofrom: c[:],f)   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
     {}
-    #pragma omp target map(self, tofrom: c,f[:])   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+    #pragma omp target map(self, tofrom: c,f[:])   // lt60-error {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper'}} // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} 
     {}
     #pragma omp target map(close, tofrom: c,f)
     {}
@@ -997,8 +997,10 @@ int main(int argc, char **argv) {
   #pragma omp target map(iterator(it=0:10), tofrom:a[it])
   {}
 
-  // ompx-error at +6 {{use of undeclared identifier 'itt'}}
-  // omp-error at +5 {{use of undeclared identifier 'itt'}}
+  // ompx-error at +8 {{use of undeclared identifier 'itt'; did you mean 'it'?}}
+  // ompx-note at +7 {{'it' declared here}}
+  // omp-error at +6 {{use of undeclared identifier 'itt'; did you mean 'it'?}}
+  // omp-note at +5 {{'it' declared here}}
   // ge51-ompx-error at +4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}}
   // lt51-ompx-error at +3 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}}
   // ge51-omp-error at +2 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present'}}
diff --git a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
index acedc3e1d57a4..62aed5780c0cc 100644
--- a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -27,7 +27,7 @@ int x;
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -45,7 +45,7 @@ void test_linear_colons() {
 #pragma omp target parallel for linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
 #pragma omp target parallel for linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
index 1936d8188acbf..e4e3f9c94febe 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -29,7 +29,7 @@ int x;
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -47,7 +47,7 @@ void test_linear_colons() {
 #pragma omp target parallel for simd linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
 #pragma omp target parallel for simd linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_simd_linear_messages.cpp b/clang/test/OpenMP/target_simd_linear_messages.cpp
index a337052a0d1e7..c31ba0dec8c3c 100644
--- a/clang/test/OpenMP/target_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_simd_linear_messages.cpp
@@ -28,7 +28,7 @@ int x;
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -46,7 +46,7 @@ void test_linear_colons() {
 #pragma omp target simd linear(B::ib : B : bfoo())
   for (int i = 0; i < 10; ++i)
     ;
-// expected-error at +1 {{use of undeclared identifier 'ib'}}
+// expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
 #pragma omp target simd linear(B : ib)
   for (int i = 0; i < 10; ++i)
     ;
diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index 250dec62f3a93..a77c1ac6201b8 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -26,7 +26,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -48,7 +48,7 @@ void test_linear_colons()
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp target teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index f071dd4c1ceec..dfa0f2a1e38e4 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -26,7 +26,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -48,7 +48,7 @@ void test_linear_colons()
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp target teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
index 927f13510626d..3741f4e8286bd 100644
--- a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
@@ -27,7 +27,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -44,7 +44,7 @@ void test_linear_colons()
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
   #pragma omp taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
-  // expected-error at +1 {{use of undeclared identifier 'ib'}}
+  // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   #pragma omp taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index 299a3a7fa508d..193f53e52bbf1 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -43,7 +43,7 @@ void test_linear_colons()
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
-#pragma omp teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp teams distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index 885df92b59d16..129d88f5b3bcc 100644
--- a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -18,7 +18,7 @@ namespace X {
 };
 
 struct B {
-  static int ib;
+  static int ib; // expected-note {{'B::ib' declared here}}
   static int bfoo() { return 8; }
 };
 
@@ -43,7 +43,7 @@ void test_linear_colons()
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
 #pragma omp target
-#pragma omp teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'}}
+#pragma omp teams distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
   for (int i = 0; i < 10; ++i) ;
 
 // expected-error at +2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
diff --git a/clang/test/PCH/race-condition.cpp b/clang/test/PCH/race-condition.cpp
index 4f1fa14b93475..752b0cc3ff628 100644
--- a/clang/test/PCH/race-condition.cpp
+++ b/clang/test/PCH/race-condition.cpp
@@ -31,7 +31,11 @@ constexpr enable_if_t<meta<F>::value == 2, void> midpoint(F) {}
 
 #else
 
+// expected-error at 27{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'F'}}
+// expected-error at 24{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'U'}}
+// expected-note at 21{{but in '' found 1st parameter with type 'T'}}
 int x = N::something;
-// expected-error at -1{{no member named 'something' in namespace 'N'}}
+// expected-error at 37{{no member named 'something' in namespace 'N'}}
+// expected-note at 21{{but in '' found 1st parameter with type 'T'}}
 
 #endif
diff --git a/clang/test/Parser/cxx-invalid-for-range.cpp b/clang/test/Parser/cxx-invalid-for-range.cpp
index 009b10fc69f25..557c1da209a9a 100644
--- a/clang/test/Parser/cxx-invalid-for-range.cpp
+++ b/clang/test/Parser/cxx-invalid-for-range.cpp
@@ -3,12 +3,12 @@
 // From PR23057 comment #18 (https://llvm.org/bugs/show_bug.cgi?id=23057#c18).
 
 namespace N {
-  int X[10];
+  int X[10]; // expected-note{{declared here}}}}
 }
 
 void f1() {
   for (auto operator new : X); // expected-error{{'operator new' cannot be the name of a variable or data member}}
-                               // expected-error at -1{{use of undeclared identifier 'X'}}
+                               // expected-error at -1{{use of undeclared identifier 'X'; did you mean 'N::X'?}}
 }
 
 void f2() {
diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp
index 3e2526979be8b..b7a8d30bd16c5 100644
--- a/clang/test/Parser/cxx1z-decomposition.cpp
+++ b/clang/test/Parser/cxx1z-decomposition.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -std=c++2c %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2c,post2b -fcxx-exceptions
 // RUN: not %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -emit-llvm-only -fcxx-exceptions
 
-struct S { int a, b, c; };
+struct S { int a, b, c; }; // expected-note 2 {{'S::a' declared here}}
 
 // A simple-declaration can be a decompsition declaration.
 namespace SimpleDecl {
@@ -32,7 +32,7 @@ namespace ForRangeDecl {
 namespace OtherDecl {
   // A parameter-declaration is not a simple-declaration.
   // This parses as an array declaration.
-  void f(auto [a, b, c]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error {{'a'}}
+  void f(auto [a, b, c]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error 1+{{'a'}}
 
   void g() {
     // A condition is allowed as a Clang extension.
@@ -46,7 +46,7 @@ namespace OtherDecl {
 
     // An exception-declaration is not a simple-declaration.
     try {}
-    catch (auto [a, b, c]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error {{'a'}}
+    catch (auto [a, b, c]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error 1+{{'a'}}
   }
 
   // A member-declaration is not a simple-declaration.
diff --git a/clang/test/ParserOpenACC/parse-cache-construct.cpp b/clang/test/ParserOpenACC/parse-cache-construct.cpp
index 1c7f5a852e266..948f2e30f149c 100644
--- a/clang/test/ParserOpenACC/parse-cache-construct.cpp
+++ b/clang/test/ParserOpenACC/parse-cache-construct.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 %s -verify -fopenacc
 
 namespace NS {
-  static char* NSArray;
-  static int NSInt;
+  static char* NSArray; // expected-note {{'NS::NSArray' declared here}}
+  static int NSInt;     // expected-note 2 {{'NS::NSInt' declared here}}
 }
 char *getArrayPtr();
 template<typename T, int I>
diff --git a/clang/test/ParserOpenACC/parse-constructs.cpp b/clang/test/ParserOpenACC/parse-constructs.cpp
index ead3077f178bb..69b04bcbad9e3 100644
--- a/clang/test/ParserOpenACC/parse-constructs.cpp
+++ b/clang/test/ParserOpenACC/parse-constructs.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 %s -verify -fopenacc
 
 namespace NS {
-  void foo();
+  void foo(); // expected-note{{declared here}}
 
   template<typename T>
-  void templ();
+  void templ(); // expected-note 2{{declared here}}
 
   class C { // #CDef
     void private_mem_func(); // #PrivateMemFunc
@@ -13,16 +13,18 @@ namespace NS {
   };
 }
 
-// expected-error at +1{{use of undeclared identifier 'foo'}}
+// expected-error at +1{{use of undeclared identifier 'foo'; did you mean 'NS::foo'?}}
 #pragma acc routine(foo) seq
 #pragma acc routine(NS::foo) seq
 
-// expected-error at +1{{use of undeclared identifier 'templ'}}
+// expected-error at +2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}}
+// expected-error at +1{{OpenACC routine name 'templ' names a set of overloads}}
 #pragma acc routine(templ) seq
 // expected-error at +1{{OpenACC routine name 'NS::templ' names a set of overloads}}
 #pragma acc routine(NS::templ) seq
 
-// expected-error at +1{{use of undeclared identifier 'templ'}}
+// expected-error at +2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}}
+// expected-error at +1{{OpenACC routine name 'templ<int>' names a set of overloads}}
 #pragma acc routine(templ<int>) seq
 // expected-error at +1{{OpenACC routine name 'NS::templ<int>' names a set of overloads}}
 #pragma acc routine(NS::templ<int>) seq
diff --git a/clang/test/ParserOpenACC/parse-sub-array.cpp b/clang/test/ParserOpenACC/parse-sub-array.cpp
index f4777820867c3..c0d3f89159e89 100644
--- a/clang/test/ParserOpenACC/parse-sub-array.cpp
+++ b/clang/test/ParserOpenACC/parse-sub-array.cpp
@@ -35,7 +35,7 @@ void Func(int i, int j) {
   while (true);
 }
 
-template<typename T, unsigned I, auto &IPtr>
+template<typename T, unsigned I, auto &IPtr>// #IPTR
 void TemplFunc() {
   T array[I];
   T array2[2*I];
@@ -73,7 +73,8 @@ void TemplFunc() {
   // expected-note at +1{{to match this '['}}
 #pragma acc parallel private(array[:I:])
   while (true);
-  // expected-error at +1{{no member named 'IPtr' in the global namespace}}
+  // expected-error at +2{{no member named 'IPtr' in the global namespace}}
+  // expected-note@#IPTR{{'IPtr' declared here}}
 #pragma acc parallel private(array[::IPtr])
   while (true);
   // expected-error at +2{{expected ']'}}
diff --git a/clang/test/Sema/delayed-typo-correction-crashes.c b/clang/test/Sema/delayed-typo-correction-crashes.c
index ec75109f8f550..81c966789ccb5 100644
--- a/clang/test/Sema/delayed-typo-correction-crashes.c
+++ b/clang/test/Sema/delayed-typo-correction-crashes.c
@@ -12,19 +12,7 @@ void GH137860_test(void) {
 int (^GH69470) (int i, int j) = ^(int i, int j)
 { return i / j; }/ j; // expected-error {{use of undeclared identifier 'j'}}
 
-void GH51210(void) {
-  _Complex int a_1;
-   0.5r / a_2; // expected-error {{use of undeclared identifier 'a_2'}}
-}
-
 void GH69874(void) {
   *a = (a_struct){0}; // expected-error {{use of undeclared identifier 'a'}} \
                          expected-error {{use of undeclared identifier 'a_struct'}}
 }
-
-__attribute__((address_space(1))) typedef int *GH140584;
-void topo_print() {
-  GH140584 b1 = topo_parent; // expected-error {{use of undeclared identifier 'topo_parent'}}
-  GH140584 b2;
-  b2 = topo_parent;          // expected-error {{use of undeclared identifier 'topo_parent'}}
-}
diff --git a/clang/test/Sema/var-redecl.c b/clang/test/Sema/var-redecl.c
index 2616002ccf390..30f1fb229d8c8 100644
--- a/clang/test/Sema/var-redecl.c
+++ b/clang/test/Sema/var-redecl.c
@@ -50,10 +50,11 @@ void outer_shadowing_test(void) {
   }
 }
 
-void g18(void) {
+void g18(void) { // expected-note{{'g18' declared here}}
   extern int g19;
 }
-int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}}
+int *p=&g19; // expected-error{{use of undeclared identifier 'g19'}} \
+             // expected-warning{{incompatible pointer types}}
 
 // PR3645
 static int a;
diff --git a/clang/test/SemaCXX/conversion-function.cpp b/clang/test/SemaCXX/conversion-function.cpp
index b653a3bf1a1d2..717c73c4786eb 100644
--- a/clang/test/SemaCXX/conversion-function.cpp
+++ b/clang/test/SemaCXX/conversion-function.cpp
@@ -458,7 +458,7 @@ namespace PR18234 {
 #endif
   } a;
   A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
-  A::E e = a;
+  A::E e = a; // expected-note {{'e' declared here}}
   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
   bool k2 = e.n == 0;
 }
diff --git a/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
index d0ae88ac4e6d6..f3aa051532815 100644
--- a/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
+++ b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp
@@ -36,9 +36,10 @@ template <typename b> class c {
 }
 
 namespace GH45915 {
-short g_volatile_ushort;
+short g_volatile_ushort;                   // expected-note {{'g_volatile_ushort' declared here}}
 namespace a {
-   int b = l_volatile_uwchar.a ::c ::~d<>; // expected-error {{use of undeclared identifier 'l_volatile_uwchar'}}
+   int b = l_volatile_uwchar.a ::c ::~d<>; // expected-error {{use of undeclared identifier 'l_volatile_uwchar'}} \
+                                              expected-error {{no member named 'd' in namespace 'GH45915::a'}}
 }
 }
 
@@ -52,9 +53,9 @@ namespace GH32903 {
 void
 B(
   char cat_dog_3, char cat_dog_2, char cat_dog_1, char cat_dog_0, char pigeon_dog_3, char pigeon_dog_2,
-  char pigeon_dog_1, char pigeon_dog_0, short &elefant15_lion, short &elefant14_lion, short &elefant13_lion,
-  short &elefant12_lion, short &elefant11_lion, short &elefant10_lion, short &elefant9_lion, short &elefant8_lion,
-  short &elefant7_lion, short &elefant6_lion, short &elefant5_lion, short &elefant4_lion, short &elefant3_lion,
+  char pigeon_dog_1, char pigeon_dog_0, short &elefant15_lion, short &elefant14_lion, short &elefant13_lion,       // expected-note 3 {{declared here}}
+  short &elefant12_lion, short &elefant11_lion, short &elefant10_lion, short &elefant9_lion, short &elefant8_lion, // expected-note 5 {{declared here}}
+  short &elefant7_lion, short &elefant6_lion, short &elefant5_lion, short &elefant4_lion, short &elefant3_lion,    // expected-note 2 {{declared here}}
   short &elefant2_lion, short &elefant1_lion, short &elefant0_lion, char& no_animal)
 {
 
diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp
index 55e1e3467018f..5340c6c7d0bf3 100644
--- a/clang/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp
@@ -9,25 +9,25 @@ namespace variadic_expansion {
     f([&a(t)]()->decltype(auto) {
       return a;
     }() ...);
-
+    
     auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
     const int y = 10;
-    auto M = [x = y,
-                &z = y](T& ... t) { };
-    auto N = [x = y,
-                &z = y, n = f(t...),
-                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) {
-                  fv([&a(t)]()->decltype(auto) {
+    auto M = [x = y, 
+                &z = y](T& ... t) { }; 
+    auto N = [x = y, 
+                &z = y, n = f(t...), 
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { 
+                  fv([&a(t)]()->decltype(auto) { 
                     return a;
                   }() ...);
-                };
+                };                 
     auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}}
-                &z = y, n = f(t...),
+                &z = y, n = f(t...), 
                 o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}}
                 fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
                     return a;
                   }() ...);
-                };
+                };                 
 
   }
 
@@ -37,7 +37,7 @@ namespace variadic_expansion {
 namespace odr_use_within_init_capture {
 
 int test() {
-
+  
   { // no captures
     const int x = 10;
     auto L = [z = x + 2](int a) {
@@ -46,14 +46,14 @@ int test() {
       };
       return M;
     };
-
+        
   }
   { // should not capture
     const int x = 10;
     auto L = [&z = x](int a) {
       return a;;
     };
-
+        
   }
   {
     const int x = 10;
@@ -67,9 +67,9 @@ int test() {
   }
   {
     const int x = 10;
-    auto L = [k = x](char a) {
-      return [=](int b) {
-        return [j = k](int c) {
+    auto L = [k = x](char a) { 
+      return [=](int b) { 
+        return [j = k](int c) { 
           return c;
         };
       };
@@ -77,9 +77,9 @@ int test() {
   }
   {
     const int x = 10;
-    auto L = [k = x](char a) {
-      return [k](int b) {
-        return [j = k](int c) {
+    auto L = [k = x](char a) { 
+      return [k](int b) { 
+        return [j = k](int c) { 
           return c;
         };
       };
@@ -106,14 +106,14 @@ int test(T t = T{}) {
       };
       return M;
     };
-
+        
   }
   { // should not capture
     const T x = 10;
     auto L = [&z = x](T a) {
       return a;;
     };
-
+        
   }
   { // will need to capture x in outer lambda
     const T x = 10; //expected-note {{declared}}
@@ -125,19 +125,19 @@ int test(T t = T{}) {
     };
   }
   { // will need to capture x in outer lambda
-    const T x = 10;
-    auto L = [=,z = x](char a) {
-      auto M = [&y = x](T b) {
+    const T x = 10; 
+    auto L = [=,z = x](char a) { 
+      auto M = [&y = x](T b) { 
         return y;
       };
       return M;
     };
-
+        
   }
   { // will need to capture x in outer lambda
-    const T x = 10;
-    auto L = [x, z = x](char a) {
-      auto M = [&y = x](T b) {
+    const T x = 10; 
+    auto L = [x, z = x](char a) { 
+      auto M = [&y = x](T b) { 
         return y;
       };
       return M;
@@ -155,12 +155,12 @@ int test(T t = T{}) {
   {
     // no captures
     const T x = 10;
-    auto L = [z =
-                  [z = x, &y = x](char a) { return z + y; }('a')](char a)
+    auto L = [z = 
+                  [z = x, &y = x](char a) { return z + y; }('a')](char a) 
       { return z; };
-
+  
   }
-
+  
   return 0;
 }
 
@@ -210,9 +210,9 @@ void test(double weight) {
 namespace init_capture_undeclared_identifier {
   auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
 
-  int typo_foo;
-  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'}}
-  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'}}
+  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
 }
 
 namespace copy_evasion {
diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index 95c64bc3b8bff..6ee1249a66c3f 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -121,7 +121,8 @@ void for_range() {
 }
 
 int error_recovery() {
-  auto [foobar]; // expected-error {{requires an initializer}}
+  auto [foobar]; // expected-error {{requires an initializer}} \
+                    expected-note {{'foobar' declared here}}
   return foobar_; // expected-error {{undeclared identifier 'foobar_'}}
 }
 
diff --git a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
index 187ab0685b2cd..1bc7f2cce3c92 100644
--- a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
+++ b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
@@ -37,7 +37,7 @@ void disambig() {
   f < 1 + 3 > (q); // ok, function call
 }
 
-bool typo(int something) { // expected-note 2{{declared here}}
+bool typo(int something) { // expected-note 4{{declared here}}
   // FIXME: We shouldn't suggest the N:: for an ADL call if the candidate can be found by ADL.
   some_logn_name<3>(q); // expected-error {{did you mean 'N::some_long_name'?}}
   somethign < 3 ? h() > 4 : h(0); // expected-error {{did you mean 'something'}}
@@ -45,8 +45,8 @@ bool typo(int something) { // expected-note 2{{declared here}}
   somethign < 3 ? h() + 4 : h(0); // expected-error {{did you mean 'something'}}
   // This is parsed as an ADL-only template-id call.
   somethign < 3 ? h() + 4 : h(0) >(0); // expected-error {{undeclared identifier 'somethign'}}
-  bool k(somethign < 3); // expected-error {{use of undeclared identifier 'somethign'}}
-  return somethign < 3; // expected-error {{use of undeclared identifier 'somethign'}}
+  bool k(somethign < 3); // expected-error {{did you mean 'something'}}
+  return somethign < 3; // expected-error {{did you mean 'something'}}
 }
 
 // Ensure that treating undeclared identifiers as template names doesn't cause
diff --git a/clang/test/SemaCXX/invalid-if-constexpr.cpp b/clang/test/SemaCXX/invalid-if-constexpr.cpp
index c2638ed9c817f..9f27741871484 100644
--- a/clang/test/SemaCXX/invalid-if-constexpr.cpp
+++ b/clang/test/SemaCXX/invalid-if-constexpr.cpp
@@ -1,13 +1,17 @@
 // RUN: %clang_cc1 -verify -std=c++20 %s
 
 namespace GH61885 {
-void similar() {
-  if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'}}
+void similar() { // expected-note {{'similar' declared here}}
+  if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'; did you mean 'similar'?}} \
+                                 expected-warning {{address of function 'similar<>' will always evaluate to 'true'}} \
+                                 expected-note {{prefix with the address-of operator to silence this warning}}
 }
 void a() { if constexpr (__adl_swap<>) {}} // expected-error{{use of undeclared identifier '__adl_swap'}}
 
-int AA() { return true;}
+int AA() { return true;} // expected-note {{'AA' declared here}}
 
-void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'}}
+void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'; did you mean 'AA'?}} \
+                                       expected-warning {{address of function 'AA<>' will always evaluate to 'true'}} \
+                                       expected-note {{prefix with the address-of operator to silence this warning}}
 }
 
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 199b165b55edd..2d2dde82a28e6 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -591,7 +591,7 @@ int func() {
 }
 
 namespace PR30566 {
-int name1;
+int name1; // expected-note {{'name1' declared here}}
 
 struct S1 {
   template<class T>
@@ -601,7 +601,8 @@ struct S1 {
 
 void foo1() {
   auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
-  auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'}}
+  auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
+                                  // cxx03-cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
 }
 }
 
diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp
index 5a2529dc2bed8..d7fa67c3d3a3b 100644
--- a/clang/test/SemaCXX/nested-name-spec.cpp
+++ b/clang/test/SemaCXX/nested-name-spec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s 
 namespace A {
   struct C {
     static int cx;
@@ -111,7 +111,7 @@ void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member mus
 
 namespace E {
   int X = 5;
-
+  
   namespace Nested {
     enum E {
       X = 0
@@ -146,7 +146,7 @@ Operators::operator bool() {
 
 namespace A {
   void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
-}
+} 
 
 void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
 
@@ -303,14 +303,14 @@ struct A2<T>::B::C; // expected-error {{no struct named 'C'}}
 
 namespace PR13033 {
 namespace NS {
- int a;
- int longer_b;
+ int a; // expected-note {{'NS::a' declared here}}
+ int longer_b; //expected-note {{'NS::longer_b' declared here}}
 }
 
 // Suggest adding a namespace qualifier to both variable names even though one
 // is only a single character long.
-int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'}} \
-                           // expected-error {{use of undeclared identifier 'longer_b'}}
+int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \
+                           // expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}}
 }
 
 namespace N {
@@ -409,7 +409,8 @@ T1<C2::N1> var_1a;
 T1<C2:N1> var_1b;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
 template<int N> int F() {}
 int (*X1)() = (B1::B2 ? F<1> : F<2>);
-int (*X2)() = (B1:B2 ? F<1> : F<2>);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+int (*X2)() = (B1:B2 ? F<1> : F<2>);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}} \
+                                         expected-note{{'PR18587::X2' declared here}}
 
 // Bit fields + templates
 struct S7a {
@@ -445,7 +446,8 @@ namespace PR16951 {
 
   int x4 = enumerator_2::ENUMERATOR_2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}}
   int x5 = enumerator_2::X2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \
-                             // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}}
+                             // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} \
+                             // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'int (*)()'}}
 
 }
 
diff --git a/clang/test/SemaCXX/qualified-id-lookup.cpp b/clang/test/SemaCXX/qualified-id-lookup.cpp
index 18a25cfc61b24..8eef6f4182746 100644
--- a/clang/test/SemaCXX/qualified-id-lookup.cpp
+++ b/clang/test/SemaCXX/qualified-id-lookup.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
 namespace Ns {
   int f(); // expected-note{{previous declaration is here}}
 
@@ -44,8 +44,8 @@ namespace N {
   }
 }
 
-void N::f1::foo(int i) {
-  f1::member = i;
+void N::f1::foo(int i) { 
+  f1::member = i; 
   f1::type &ir = i;
 }
 
@@ -83,20 +83,20 @@ namespace a {
 }
 
 // PR clang/3291
-namespace a {
+namespace a {  
   namespace a {   // A1
     namespace a { // A2
-      int i;
+      int i; // expected-note{{'a::a::a::i' declared here}}
     }
   }
 }
 
 void test_a() {
-  a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'}}
+  a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
   a::a::a::i = 4;
   a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
 }
-
+  
 struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
   typedef int type;
 
@@ -123,7 +123,7 @@ namespace test1 {
     }
   };
 
-  template class ClassChecker<int>;
+  template class ClassChecker<int>;  
 }
 
 namespace PR6830 {
diff --git a/clang/test/SemaObjC/call-super-2.m b/clang/test/SemaObjC/call-super-2.m
index 7018fd633a9be..885f392e353a6 100644
--- a/clang/test/SemaObjC/call-super-2.m
+++ b/clang/test/SemaObjC/call-super-2.m
@@ -107,7 +107,7 @@ - (id) initWithInt: (int) i
 @end
 
 @class C;
- at interface A
+ at interface A // expected-note {{receiver is instance of class declared here}}
 - (instancetype)initWithCoder:(A *)coder;
 @end
 
@@ -115,8 +115,8 @@ @interface B : A
 @end
 
 @implementation B
-- (instancetype)initWithCoder:(C *)coder {
-  if (0 != (self = [super initWithCode:code])) // expected-error {{use of undeclared identifier 'code'}}
+- (instancetype)initWithCoder:(C *)coder {     // expected-note {{'coder' declared here}}
+  if (0 != (self = [super initWithCode:code])) // expected-error {{use of undeclared identifier 'code'}} expected-warning {{instance method '-initWithCode:' not found}}
     return (void *)0;
   return (void *)0;
 }
diff --git a/clang/test/SemaObjC/default-synthesize-2.m b/clang/test/SemaObjC/default-synthesize-2.m
index ef4d5dde7747b..ec67baf4dd002 100644
--- a/clang/test/SemaObjC/default-synthesize-2.m
+++ b/clang/test/SemaObjC/default-synthesize-2.m
@@ -85,7 +85,7 @@ - (id) myMethod {
 
 @interface Test6 
 { 
-  id _var;
+  id _var; // expected-note {{'_var' declared here}}
 } 
 @property (readwrite, assign) id var; 
 @end
diff --git a/clang/test/SemaObjC/error-outof-scope-property-use.m b/clang/test/SemaObjC/error-outof-scope-property-use.m
index b7c0e592bb0ad..413161c2ef2d4 100644
--- a/clang/test/SemaObjC/error-outof-scope-property-use.m
+++ b/clang/test/SemaObjC/error-outof-scope-property-use.m
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
 // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
 
- at class NSMutableDictionary;
+ at class NSMutableDictionary; // expected-note {{receiver is instance of class declared here}}
 
 @interface LaunchdJobs 
 
- at property (nonatomic,retain) NSMutableDictionary *uuids_jobs;
+ at property (nonatomic,retain) NSMutableDictionary *uuids_jobs; // expected-note {{'_uuids_jobs' declared here}}
 
 @end
 
@@ -14,7 +14,8 @@ @implementation LaunchdJobs
 -(void)job
 {
 
- [uuids_jobs objectForKey]; // expected-error {{use of undeclared identifier 'uuids_jobs'}}
+ [uuids_jobs objectForKey]; // expected-error {{use of undeclared identifier 'uuids_jobs'}} \
+                            // expected-warning {{instance method '-objectForKey' not found}}
 }
 
 
diff --git a/clang/test/SemaObjC/objc-array-literal.m b/clang/test/SemaObjC/objc-array-literal.m
index 01ca039a75e58..fc02a70bf187a 100644
--- a/clang/test/SemaObjC/objc-array-literal.m
+++ b/clang/test/SemaObjC/objc-array-literal.m
@@ -65,10 +65,10 @@ id radar15147688(void) {
   return x;
 }
 
-enum XXXYYYZZZType { XXXYYYZZZTypeAny };
+enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}}
 void foo(void) {
   NSArray *array = @[
-    @(XXXYYYZZZTypeA),                 // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'}}
-    @(XXXYYYZZZTypeSomethingSomething) // FIXME-expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
+    @(XXXYYYZZZTypeA),                 // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}}
+    @(XXXYYYZZZTypeSomethingSomething) // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
   ];
 }
diff --git a/clang/test/SemaObjC/objc-dictionary-literal.m b/clang/test/SemaObjC/objc-dictionary-literal.m
index 499ab84aaac6e..142765f5e2608 100644
--- a/clang/test/SemaObjC/objc-dictionary-literal.m
+++ b/clang/test/SemaObjC/objc-dictionary-literal.m
@@ -60,10 +60,10 @@ int main(void) {
 	return 0;
 }
 
-enum XXXYYYZZZType { XXXYYYZZZTypeAny };
+enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}}
 void foo(void) {
   NSDictionary *d = @{
-    @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'}}
-    @"F" : @(XXXYYYZZZTypeSomethingSomething),
+    @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}}
+    @"F" : @(XXXYYYZZZTypeSomethingSomething), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}}
   };
 }
diff --git a/clang/test/SemaObjC/super.m b/clang/test/SemaObjC/super.m
index 557f5db1ec6b5..a86dc6376e5d9 100644
--- a/clang/test/SemaObjC/super.m
+++ b/clang/test/SemaObjC/super.m
@@ -52,7 +52,7 @@ void f(id super) {
 void f0(int super) {
   [super m]; // expected-warning{{receiver type 'int' is not 'id'}}
 }
-void f1(id puper) {
+void f1(id puper) {  // expected-note {{'puper' declared here}}
   [super m]; // expected-error{{use of undeclared identifier 'super'}}
 }
 
diff --git a/clang/test/SemaObjC/synth-provisional-ivars.m b/clang/test/SemaObjC/synth-provisional-ivars.m
index 7a41bee0a1c2a..d2eb61a056978 100644
--- a/clang/test/SemaObjC/synth-provisional-ivars.m
+++ b/clang/test/SemaObjC/synth-provisional-ivars.m
@@ -30,7 +30,7 @@ - (int) Meth3 { return PROP3; }  // expected-error {{use of undeclared identifie
 @synthesize PROP3=IVAR;
 
 - (int) Meth4 { return PROP4; }
- at synthesize PROP4=PROP4;
+ at synthesize PROP4=PROP4; // expected-note 4 {{'PROP4' declared here}}
 
 - (int) Meth5 { return bar; }
 @synthesize bar = _bar;
diff --git a/clang/test/SemaObjC/typo-correction-arc.m b/clang/test/SemaObjC/typo-correction-arc.m
index ed478ee0ba1ee..206d545ae7e37 100644
--- a/clang/test/SemaObjC/typo-correction-arc.m
+++ b/clang/test/SemaObjC/typo-correction-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class %s -verify
+// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -Wno-objc-root-class %s -verify
 
 typedef unsigned long NSUInteger;
 
diff --git a/clang/test/SemaObjC/typo-correction.m b/clang/test/SemaObjC/typo-correction.m
index f2d336f3777c0..5635f5f56fcf8 100644
--- a/clang/test/SemaObjC/typo-correction.m
+++ b/clang/test/SemaObjC/typo-correction.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-runtime=ios -fdelayed-typo-correction
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-runtime=ios
 
 @protocol P
 -(id)description;
diff --git a/clang/test/SemaObjCXX/block-for-lambda-conversion.mm b/clang/test/SemaObjCXX/block-for-lambda-conversion.mm
index 671e83dc22019..a3bcfab677197 100644
--- a/clang/test/SemaObjCXX/block-for-lambda-conversion.mm
+++ b/clang/test/SemaObjCXX/block-for-lambda-conversion.mm
@@ -8,19 +8,20 @@
   NSEventMaskLeftMouseDown = 1
 };
 
-static const NSEventType NSFlagsChanged = NSEventTypeFlagsChanged;
+static const NSEventType NSFlagsChanged = NSEventTypeFlagsChanged; // expected-note {{'NSFlagsChanged' declared here}}
 
 @interface NSObject
 @end
 @interface NSEvent : NSObject {
 }
 + (nullable id)
-addMonitor:(NSEventMask)mask handler:(NSEvent *_Nullable (^)(NSEvent *))block;
+addMonitor:(NSEventMask)mask handler:(NSEvent *_Nullable (^)(NSEvent *))block; // expected-note {{passing argument to parameter 'mask' here}}
 @end
 
 void test(id weakThis) {
   id m_flagsChangedEventMonitor = [NSEvent
-      addMonitor:NSFlagsChangedMask //expected-error {{use of undeclared identifier 'NSFlagsChangedMask'}}
+      addMonitor:NSFlagsChangedMask //expected-error {{use of undeclared identifier 'NSFlagsChangedMask'}} \
+                                      expected-error {{cannot initialize a parameter of type 'NSEventMask' with an lvalue of type 'const NSEventType'}}
          handler:[weakThis](NSEvent *flagsChangedEvent) {
              return flagsChangedEvent;
          }];
diff --git a/clang/test/SemaOpenCL/atomic-ops.cl b/clang/test/SemaOpenCL/atomic-ops.cl
index d9b24f16ddecc..babebba31e82b 100644
--- a/clang/test/SemaOpenCL/atomic-ops.cl
+++ b/clang/test/SemaOpenCL/atomic-ops.cl
@@ -167,6 +167,7 @@ void syncscope_checks(atomic_int *Ap, int scope) {
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_all_devices);
 #if __OPENCL_C_VERSION__ < CL_VERSION_3_0
   // expected-error at -2{{use of undeclared identifier 'memory_scope_all_devices'}}
+  // expected-note at opencl-c-base.h:*{{'memory_scope_all_svm_devices' declared here}}
 #endif
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_sub_group);
   (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope);
diff --git a/clang/unittests/Sema/ExternalSemaSourceTest.cpp b/clang/unittests/Sema/ExternalSemaSourceTest.cpp
index 2b271d4bf7825..4eb8f5193e04f 100644
--- a/clang/unittests/Sema/ExternalSemaSourceTest.cpp
+++ b/clang/unittests/Sema/ExternalSemaSourceTest.cpp
@@ -274,7 +274,7 @@ TEST(ExternalSemaSource, ExternalDelayedTypoCorrection) {
   DiagnosticWatcher Watcher("aaa", "bbb");
   Installer->PushSource(Provider.get());
   Installer->PushWatcher(&Watcher);
-  std::vector<std::string> Args(1, "-std=c++11");
+  std::vector<std::string> Args{"-std=c++11", "-fdelayed-typo-correction"};
   ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
       std::move(Installer), "namespace AAA { } void foo() { AAA::aaa(); }",
       Args));

>From 5ab6e53dabbd31ef6061a45191561f271a4beb71 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 3 Jun 2025 16:21:40 -0400
Subject: [PATCH 03/11] [WIP] Start ripping the functionality out entirely

There are some tests failing still, that's expected
---
 clang/include/clang/Parse/Parser.h            |   3 +-
 clang/include/clang/Sema/Sema.h               |  90 +-------
 clang/lib/Parse/ParseCXXInlineMethods.cpp     |   1 -
 clang/lib/Parse/ParseDecl.cpp                 |  33 +--
 clang/lib/Parse/ParseDeclCXX.cpp              |   8 +-
 clang/lib/Parse/ParseExpr.cpp                 |  94 ++------
 clang/lib/Parse/ParseExprCXX.cpp              |  13 +-
 clang/lib/Parse/ParseInit.cpp                 |   2 -
 clang/lib/Parse/ParseObjc.cpp                 |  23 +-
 clang/lib/Parse/ParseOpenACC.cpp              |  28 +--
 clang/lib/Parse/ParseOpenMP.cpp               |  19 +-
 clang/lib/Parse/ParseStmt.cpp                 |  16 +-
 clang/lib/Parse/ParseStmtAsm.cpp              |   2 +-
 clang/lib/Parse/ParseTemplate.cpp             |   3 +-
 clang/lib/Sema/Sema.cpp                       |   9 -
 clang/lib/Sema/SemaChecking.cpp               |   2 -
 clang/lib/Sema/SemaCoroutine.cpp              |  12 -
 clang/lib/Sema/SemaDecl.cpp                   |  39 +---
 clang/lib/Sema/SemaDeclCXX.cpp                |  27 +--
 clang/lib/Sema/SemaExpr.cpp                   | 122 +---------
 clang/lib/Sema/SemaExprCXX.cpp                |  42 +---
 clang/lib/Sema/SemaExprMember.cpp             | 102 ---------
 clang/lib/Sema/SemaLookup.cpp                 |  52 -----
 clang/lib/Sema/SemaObjC.cpp                   |   7 +-
 clang/lib/Sema/SemaStmt.cpp                   |  14 +-
 clang/lib/Sema/SemaStmtAttr.cpp               |   5 +-
 clang/lib/Sema/SemaTemplateVariadic.cpp       |  12 +-
 clang/test/AST/ast-dump-recovery.c            |   4 +-
 clang/test/AST/ast-dump-recovery.cpp          |   5 +-
 clang/test/AST/ast-dump-recovery.m            |   8 +-
 clang/test/FixIt/typo.cpp                     | 137 -----------
 clang/test/Index/complete-switch.c            |  10 -
 clang/test/Index/fix-its.c                    |  19 +-
 clang/test/Modules/diagnose-missing-import.m  |   2 -
 clang/test/Parser/switch-recovery.cpp         |   2 +-
 clang/test/Parser/switch-typo-correction.cpp  |   4 +-
 clang/test/Sema/typo-correction-ambiguity.cpp |   6 +-
 clang/test/Sema/typo-correction-no-hang.c     |  11 +-
 clang/test/Sema/typo-correction-no-hang.cpp   |  14 +-
 clang/test/Sema/typo-correction-recursive.cpp |  30 +--
 clang/test/Sema/typo-correction.c             |  28 ++-
 .../test/SemaCXX/pr13394-crash-on-invalid.cpp |  30 ---
 clang/test/SemaCXX/return.cpp                 |   8 +-
 clang/test/SemaCXX/typo-correction-crash.cpp  |  21 +-
 clang/test/SemaCXX/typo-correction-cxx11.cpp  |  13 +-
 .../test/SemaCXX/typo-correction-delayed.cpp  | 216 ------------------
 clang/test/SemaCXX/typo-correction.cpp        |  42 ++--
 .../test/SemaObjC/typo-correction-subscript.m |   5 +-
 48 files changed, 175 insertions(+), 1220 deletions(-)
 delete mode 100644 clang/test/FixIt/typo.cpp
 delete mode 100644 clang/test/Index/complete-switch.c
 delete mode 100644 clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
 delete mode 100644 clang/test/SemaCXX/typo-correction-delayed.cpp

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index c4bef4729fd36..63050adefd520 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -4172,8 +4172,7 @@ class Parser : public CodeCompletionHandler {
   bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
                            llvm::function_ref<void()> ExpressionStarts =
                                llvm::function_ref<void()>(),
-                           bool FailImmediatelyOnInvalidExpr = false,
-                           bool EarlyTypoCorrection = false);
+                           bool FailImmediatelyOnInvalidExpr = false);
 
   /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
   /// used for misc language extensions.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6ce9ae588b637..7d78f0b1bec83 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8730,40 +8730,6 @@ class Sema final : public SemaBase {
 
   ExprResult CheckUnevaluatedOperand(Expr *E);
 
-  /// Process any TypoExprs in the given Expr and its children,
-  /// generating diagnostics as appropriate and returning a new Expr if there
-  /// were typos that were all successfully corrected and ExprError if one or
-  /// more typos could not be corrected.
-  ///
-  /// \param E The Expr to check for TypoExprs.
-  ///
-  /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its
-  /// initializer.
-  ///
-  /// \param RecoverUncorrectedTypos If true, when typo correction fails, it
-  /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs.
-  ///
-  /// \param Filter A function applied to a newly rebuilt Expr to determine if
-  /// it is an acceptable/usable result from a single combination of typo
-  /// corrections. As long as the filter returns ExprError, different
-  /// combinations of corrections will be tried until all are exhausted.
-  ExprResult CorrectDelayedTyposInExpr(
-      Expr *E, VarDecl *InitDecl = nullptr,
-      bool RecoverUncorrectedTypos = false,
-      llvm::function_ref<ExprResult(Expr *)> Filter =
-          [](Expr *E) -> ExprResult { return E; });
-
-  ExprResult CorrectDelayedTyposInExpr(
-      ExprResult ER, VarDecl *InitDecl = nullptr,
-      bool RecoverUncorrectedTypos = false,
-      llvm::function_ref<ExprResult(Expr *)> Filter =
-          [](Expr *E) -> ExprResult { return E; }) {
-    return ER.isInvalid()
-               ? ER
-               : CorrectDelayedTyposInExpr(ER.get(), InitDecl,
-                                           RecoverUncorrectedTypos, Filter);
-  }
-
   IfExistsResult
   CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS,
                                const DeclarationNameInfo &TargetNameInfo);
@@ -9714,51 +9680,6 @@ class Sema final : public SemaBase {
                              const ObjCObjectPointerType *OPT = nullptr,
                              bool RecordFailure = true);
 
-  /// Try to "correct" a typo in the source code by finding
-  /// visible declarations whose names are similar to the name that was
-  /// present in the source code.
-  ///
-  /// \param TypoName the \c DeclarationNameInfo structure that contains
-  /// the name that was present in the source code along with its location.
-  ///
-  /// \param LookupKind the name-lookup criteria used to search for the name.
-  ///
-  /// \param S the scope in which name lookup occurs.
-  ///
-  /// \param SS the nested-name-specifier that precedes the name we're
-  /// looking for, if present.
-  ///
-  /// \param CCC A CorrectionCandidateCallback object that provides further
-  /// validation of typo correction candidates. It also provides flags for
-  /// determining the set of keywords permitted.
-  ///
-  /// \param TDG A TypoDiagnosticGenerator functor that will be used to print
-  /// diagnostics when the actual typo correction is attempted.
-  ///
-  /// \param TRC A TypoRecoveryCallback functor that will be used to build an
-  /// Expr from a typo correction candidate.
-  ///
-  /// \param MemberContext if non-NULL, the context in which to look for
-  /// a member access expression.
-  ///
-  /// \param EnteringContext whether we're entering the context described by
-  /// the nested-name-specifier SS.
-  ///
-  /// \param OPT when non-NULL, the search for visible declarations will
-  /// also walk the protocols in the qualified interfaces of \p OPT.
-  ///
-  /// \returns a new \c TypoExpr that will later be replaced in the AST with an
-  /// Expr representing the result of performing typo correction, or nullptr if
-  /// typo correction is not possible. If nullptr is returned, no diagnostics
-  /// will be emitted and it is the responsibility of the caller to emit any
-  /// that are needed.
-  TypoExpr *CorrectTypoDelayed(
-      const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind,
-      Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC,
-      TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC,
-      CorrectTypoKind Mode, DeclContext *MemberContext = nullptr,
-      bool EnteringContext = false, const ObjCObjectPointerType *OPT = nullptr);
-
   /// Kinds of missing import. Note, the values of these enumerators correspond
   /// to %select values in diagnostics.
   enum class MissingImportKind {
@@ -9813,9 +9734,9 @@ class Sema final : public SemaBase {
   /// Determine if we could use all the declarations in the module.
   bool isUsableModule(const Module *M);
 
-  /// Helper for CorrectTypo and CorrectTypoDelayed used to create and
-  /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction
-  /// should be skipped entirely.
+  /// Helper for CorrectTypo used to create and populate a new
+  /// TypoCorrectionConsumer. Returns nullptr if typo correction should be
+  /// skipped entirely.
   std::unique_ptr<TypoCorrectionConsumer> makeTypoCorrectionConsumer(
       const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind,
       Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC,
@@ -9825,11 +9746,6 @@ class Sema final : public SemaBase {
   /// The set of unhandled TypoExprs and their associated state.
   llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos;
 
-  /// Creates a new TypoExpr AST node.
-  TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
-                              TypoDiagnosticGenerator TDG,
-                              TypoRecoveryCallback TRC, SourceLocation TypoLoc);
-
   /// Cache for module units which is usable for current module.
   llvm::DenseSet<const Module *> UsableModuleUnitsCache;
 
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index e215c64cccd11..9a010fb5f3427 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -422,7 +422,6 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
         DefArgResult = ParseBraceInitializer();
       } else
         DefArgResult = ParseAssignmentExpression();
-      DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param);
       if (DefArgResult.isInvalid()) {
         Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
                                                /*DefaultArg=*/nullptr);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index d6c36616bab47..1de6abf8fd333 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -436,7 +436,6 @@ bool Parser::ParseAttributeArgumentList(
     } else {
       Expr = ParseAssignmentExpression();
     }
-    Expr = Actions.CorrectDelayedTyposInExpr(Expr);
 
     if (Tok.is(tok::ellipsis))
       Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
@@ -472,15 +471,6 @@ bool Parser::ParseAttributeArgumentList(
     Arg++;
   }
 
-  if (SawError) {
-    // Ensure typos get diagnosed when errors were encountered while parsing the
-    // expression list.
-    for (auto &E : Exprs) {
-      ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E);
-      if (Expr.isUsable())
-        E = Expr.get();
-    }
-  }
   return SawError;
 }
 
@@ -565,9 +555,7 @@ unsigned Parser::ParseAttributeArgsCommon(
               nullptr,
               Sema::ExpressionEvaluationContextRecord::EK_AttrArgument);
 
-          ExprResult ArgExpr(
-              Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
-
+          ExprResult ArgExpr = ParseAssignmentExpression();
           if (ArgExpr.isInvalid()) {
             SkipUntil(tok::r_paren, StopAtSemi);
             return 0;
@@ -3212,9 +3200,7 @@ void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
       Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, nullptr,
       ExpressionKind::EK_AttrArgument);
 
-  ExprResult ArgExpr(
-      Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
-
+  ExprResult ArgExpr = ParseAssignmentExpression();
   if (ArgExpr.isInvalid()) {
     Parens.skipToEnd();
     return;
@@ -6891,8 +6877,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
       //   void (f()) requires true;
       Diag(Tok, diag::err_requires_clause_inside_parens);
       ConsumeToken();
-      ExprResult TrailingRequiresClause = Actions.CorrectDelayedTyposInExpr(
-         ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true));
+      ExprResult TrailingRequiresClause =
+          ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);
       if (TrailingRequiresClause.isUsable() && D.isFunctionDeclarator() &&
           !D.hasTrailingRequiresClause())
         // We're already ill-formed if we got here but we'll accept it anyway.
@@ -7539,8 +7525,7 @@ void Parser::ParseParameterDeclarationClause(
       Diag(Tok,
            diag::err_requires_clause_on_declarator_not_declaring_a_function);
       ConsumeToken();
-      Actions.CorrectDelayedTyposInExpr(
-         ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true));
+      ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);
     }
 
     // Remember this parsed parameter in ParamInfo.
@@ -7654,7 +7639,6 @@ void Parser::ParseParameterDeclarationClause(
             }
             DefArgResult = ParseAssignmentExpression();
           }
-          DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
           if (DefArgResult.isInvalid()) {
             Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
                                                    /*DefaultArg=*/nullptr);
@@ -7800,8 +7784,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
     } else {
       EnterExpressionEvaluationContext Unevaluated(
           Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-      NumElements =
-          Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+      NumElements = ParseAssignmentExpression();
     }
   } else {
     if (StaticLoc.isValid()) {
@@ -7938,8 +7921,8 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
   bool isCastExpr;
   ParsedType CastTy;
   SourceRange CastRange;
-  ExprResult Operand = Actions.CorrectDelayedTyposInExpr(
-      ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
+  ExprResult Operand =
+      ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
   if (HasParens)
     DS.setTypeArgumentRange(CastRange);
 
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 2cf33a856c4f4..93e2d749d7c06 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1071,10 +1071,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
       EnterExpressionEvaluationContext Unevaluated(
           Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
           Sema::ExpressionEvaluationContextRecord::EK_Decltype);
-      Result = Actions.CorrectDelayedTyposInExpr(
-          ParseExpression(), /*InitDecl=*/nullptr,
-          /*RecoverUncorrectedTypos=*/false,
-          [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; });
+      Result = ParseExpression();
       if (Result.isInvalid()) {
         DS.SetTypeSpecError();
         if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
@@ -4465,8 +4462,7 @@ bool Parser::ParseCXXAssumeAttributeArg(
       Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
 
   TentativeParsingAction TPA(*this);
-  ExprResult Res(
-      Actions.CorrectDelayedTyposInExpr(ParseConditionalExpression()));
+  ExprResult Res = ParseConditionalExpression();
   if (Res.isInvalid()) {
     TPA.Commit();
     SkipUntil(tok::r_paren, tok::r_square, StopAtSemi | StopBeforeMatch);
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 951a157305ddc..a27a44455b621 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -183,7 +183,6 @@ ExprResult Parser::ParseConstraintExpression() {
   ExprResult LHS(ParseCastExpression(CastParseKind::AnyCastExpr));
   ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
   if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {
-    Actions.CorrectDelayedTyposInExpr(Res);
     return ExprError();
   }
   return Res;
@@ -244,7 +243,6 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
       // the rest of the addition expression). Try to parse the rest of it here.
       if (PossibleNonPrimary)
         E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr);
-      Actions.CorrectDelayedTyposInExpr(E);
       return ExprError();
     }
     return E;
@@ -256,14 +254,11 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
     SourceLocation LogicalAndLoc = ConsumeToken();
     ExprResult RHS = ParsePrimary();
     if (RHS.isInvalid()) {
-      Actions.CorrectDelayedTyposInExpr(LHS);
       return ExprError();
     }
     ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc,
                                        tok::ampamp, LHS.get(), RHS.get());
     if (!Op.isUsable()) {
-      Actions.CorrectDelayedTyposInExpr(RHS);
-      Actions.CorrectDelayedTyposInExpr(LHS);
       return ExprError();
     }
     LHS = Op;
@@ -281,14 +276,11 @@ Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) {
     ExprResult RHS =
         ParseConstraintLogicalAndExpression(IsTrailingRequiresClause);
     if (!RHS.isUsable()) {
-      Actions.CorrectDelayedTyposInExpr(LHS);
       return ExprError();
     }
     ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc,
                                        tok::pipepipe, LHS.get(), RHS.get());
     if (!Op.isUsable()) {
-      Actions.CorrectDelayedTyposInExpr(RHS);
-      Actions.CorrectDelayedTyposInExpr(LHS);
       return ExprError();
     }
     LHS = Op;
@@ -408,7 +400,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
       }
 
       if (TernaryMiddle.isInvalid()) {
-        Actions.CorrectDelayedTyposInExpr(LHS);
         LHS = ExprError();
         TernaryMiddle = nullptr;
       }
@@ -466,11 +457,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
       RHS = ParseCastExpression(CastParseKind::AnyCastExpr);
 
     if (RHS.isInvalid()) {
-      // FIXME: Errors generated by the delayed typo correction should be
-      // printed before errors from parsing the RHS, not after.
-      Actions.CorrectDelayedTyposInExpr(LHS);
-      if (TernaryMiddle.isUsable())
-        TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
       LHS = ExprError();
     }
 
@@ -503,11 +489,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
       RHSIsInitList = false;
 
       if (RHS.isInvalid()) {
-        // FIXME: Errors generated by the delayed typo correction should be
-        // printed before errors from ParseRHSOfBinaryExpression, not after.
-        Actions.CorrectDelayedTyposInExpr(LHS);
-        if (TernaryMiddle.isUsable())
-          TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
         LHS = ExprError();
       }
 
@@ -571,17 +552,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
 
         LHS = CondOp;
       }
-      // In this case, ActOnBinOp or ActOnConditionalOp performed the
-      // CorrectDelayedTyposInExpr check.
-      if (!getLangOpts().CPlusPlus)
-        continue;
-    }
-
-    // Ensure potential typos aren't left undiagnosed.
-    if (LHS.isInvalid()) {
-      Actions.CorrectDelayedTyposInExpr(OrigLHS);
-      Actions.CorrectDelayedTyposInExpr(TernaryMiddle);
-      Actions.CorrectDelayedTyposInExpr(RHS);
     }
   }
 }
@@ -1711,7 +1681,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
       // Reject array indices starting with a lambda-expression. '[[' is
       // reserved for attributes.
       if (CheckProhibitedCXX11Attribute()) {
-        (void)Actions.CorrectDelayedTyposInExpr(LHS);
         return ExprError();
       }
       BalancedDelimiterTracker T(*this, tok::l_square);
@@ -1737,8 +1706,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
           } else {
             Idx = ParseExpression(); // May be a comma expression
           }
-          LHS = Actions.CorrectDelayedTyposInExpr(LHS);
-          Idx = Actions.CorrectDelayedTyposInExpr(Idx);
           if (Idx.isInvalid()) {
             HasError = true;
           } else {
@@ -1746,7 +1713,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
           }
         } else if (Tok.isNot(tok::r_square)) {
           if (ParseExpressionList(ArgExprs)) {
-            LHS = Actions.CorrectDelayedTyposInExpr(LHS);
             HasError = true;
           }
         }
@@ -1762,7 +1728,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
           // Consume ':'
           ColonLocFirst = ConsumeToken();
           if (Tok.isNot(tok::r_square))
-            Length = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+            Length = ParseExpression();
         }
       } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) {
         ColonProtectionRAIIObject RAII(*this);
@@ -1773,7 +1739,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
               (getLangOpts().OpenMP < 50 ||
                ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) {
             Length = ParseExpression();
-            Length = Actions.CorrectDelayedTyposInExpr(Length);
           }
         }
         if (getLangOpts().OpenMP >= 50 &&
@@ -1789,8 +1754,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
       }
 
       SourceLocation RLoc = Tok.getLocation();
-      LHS = Actions.CorrectDelayedTyposInExpr(LHS);
-
       if (!LHS.isInvalid() && !HasError && !Length.isInvalid() &&
           !Stride.isInvalid() && Tok.is(tok::r_square)) {
         if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) {
@@ -1838,7 +1801,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
         SourceLocation OpenLoc = ConsumeToken();
 
         if (ParseSimpleExpressionList(ExecConfigExprs)) {
-          (void)Actions.CorrectDelayedTyposInExpr(LHS);
           LHS = ExprError();
         }
 
@@ -1889,16 +1851,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
                  PreferredType.enterFunctionArgument(Tok.getLocation(),
                                                      RunSignatureHelp);
                }))) {
-            (void)Actions.CorrectDelayedTyposInExpr(LHS);
             // If we got an error when parsing expression list, we don't call
             // the CodeCompleteCall handler inside the parser. So call it here
             // to make sure we get overload suggestions even when we are in the
             // middle of a parameter.
             if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
               RunSignatureHelp();
-          } else if (LHS.isInvalid()) {
-            for (auto &E : ArgExprs)
-              Actions.CorrectDelayedTyposInExpr(E);
           }
         }
       }
@@ -1913,16 +1871,16 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
                                          ArgExprs);
         SkipUntil(tok::r_paren, StopAtSemi);
       } else if (Tok.isNot(tok::r_paren)) {
-        bool HadDelayedTypo = false;
-        if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get())
-          HadDelayedTypo = true;
+        bool HadErrors = false;
+        if (LHS.get()->containsErrors())
+          HadErrors = true;
         for (auto &E : ArgExprs)
-          if (Actions.CorrectDelayedTyposInExpr(E).get() != E)
-            HadDelayedTypo = true;
-        // If there were delayed typos in the LHS or ArgExprs, call SkipUntil
-        // instead of PT.consumeClose() to avoid emitting extra diagnostics for
-        // the unmatched l_paren.
-        if (HadDelayedTypo)
+          if (E->containsErrors())
+            HadErrors = true;
+        // If there were errors in the LHS or ArgExprs, call SkipUntil instead
+        // of PT.consumeClose() to avoid emitting extra diagnostics for the
+        // unmatched l_paren.
+        if (HadErrors)
           SkipUntil(tok::r_paren, StopAtSemi);
         else
           PT.consumeClose();
@@ -2050,7 +2008,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
                      /*AllowConstructorName=*/
                      getLangOpts().MicrosoftExt && SS.isNotEmpty(),
                      /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) {
-        (void)Actions.CorrectDelayedTyposInExpr(LHS);
         LHS = ExprError();
       }
 
@@ -2921,8 +2878,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
     do {
       BalancedDelimiterTracker TS(*this, tok::l_square);
       TS.consumeOpen();
-      ExprResult NumElements =
-          Actions.CorrectDelayedTyposInExpr(ParseExpression());
+      ExprResult NumElements = ParseExpression();
       if (!NumElements.isUsable()) {
         ErrorFound = true;
         while (!SkipUntil(tok::r_square, tok::r_paren,
@@ -2936,7 +2892,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
     // Match the ')'.
     T.consumeClose();
     RParenLoc = T.getCloseLocation();
-    Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+    Result = ParseAssignmentExpression();
     if (ErrorFound) {
       Result = ExprError();
     } else if (!Result.isInvalid()) {
@@ -2948,12 +2904,6 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
     InMessageExpressionRAIIObject InMessage(*this, false);
 
     Result = ParseExpression(TypeCastState::MaybeTypeCast);
-    if (!getLangOpts().CPlusPlus && Result.isUsable()) {
-      // Correct typos in non-C++ code earlier so that implicit-cast-like
-      // expressions are parsed correctly.
-      Result = Actions.CorrectDelayedTyposInExpr(Result);
-    }
-
     if (ExprType >= ParenParseOption::FoldExpr &&
         isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
       ExprType = ParenParseOption::FoldExpr;
@@ -3057,8 +3007,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
     // not evaluated."
     EnterExpressionEvaluationContext Unevaluated(
         Actions, Sema::ExpressionEvaluationContext::Unevaluated);
-    ControllingExpr =
-        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+    ControllingExpr = ParseAssignmentExpression();
     if (ControllingExpr.isInvalid()) {
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
@@ -3104,8 +3053,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
 
     // FIXME: These expressions should be parsed in a potentially potentially
     // evaluated context.
-    ExprResult ER(
-        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
+    ExprResult ER = ParseAssignmentExpression();
     if (ER.isInvalid()) {
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
@@ -3199,8 +3147,7 @@ void Parser::injectEmbedTokens() {
 
 bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
                                  llvm::function_ref<void()> ExpressionStarts,
-                                 bool FailImmediatelyOnInvalidExpr,
-                                 bool EarlyTypoCorrection) {
+                                 bool FailImmediatelyOnInvalidExpr) {
   bool SawError = false;
   while (true) {
     if (ExpressionStarts)
@@ -3213,9 +3160,6 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
     } else
       Expr = ParseAssignmentExpression();
 
-    if (EarlyTypoCorrection)
-      Expr = Actions.CorrectDelayedTyposInExpr(Expr);
-
     if (Tok.is(tok::ellipsis))
       Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
     else if (Tok.is(tok::code_completion)) {
@@ -3244,14 +3188,6 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
     ConsumeToken();
     checkPotentialAngleBracketDelimiter(Comma);
   }
-  if (SawError) {
-    // Ensure typos get diagnosed when errors were encountered while parsing the
-    // expression list.
-    for (auto &E : Exprs) {
-      ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E);
-      if (Expr.isUsable()) E = Expr.get();
-    }
-  }
   return SawError;
 }
 
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index d95260829e4a0..6505f433dc1ba 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -972,8 +972,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
           SourceLocation StartLoc = Tok.getLocation();
           InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
           Init = ParseInitializer();
-          if (!Init.isInvalid())
-            Init = Actions.CorrectDelayedTyposInExpr(Init.get());
 
           if (Tok.getLocation() != StartLoc) {
             // Back out the lexing of the token after the initializer.
@@ -1065,8 +1063,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
     // enclosing the lambda-expression, rather than in the context of the
     // lambda-expression itself.
     ParsedType InitCaptureType;
-    if (Init.isUsable())
-      Init = Actions.CorrectDelayedTyposInExpr(Init.get());
     if (Init.isUsable()) {
       NonTentativeAction([&] {
         // Get the pointer and store it in an lvalue, so we can use it as an
@@ -3202,8 +3198,7 @@ ExprResult Parser::ParseRequiresExpression() {
         //             cv-qualifier-seq[opt] abstract-declarator[opt]
         BalancedDelimiterTracker ExprBraces(*this, tok::l_brace);
         ExprBraces.consumeOpen();
-        ExprResult Expression =
-            Actions.CorrectDelayedTyposInExpr(ParseExpression());
+        ExprResult Expression = ParseExpression();
         if (!Expression.isUsable()) {
           ExprBraces.skipToEnd();
           SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
@@ -3306,8 +3301,7 @@ ExprResult Parser::ParseRequiresExpression() {
             // C++ [expr.prim.req.nested]
             //     nested-requirement:
             //         'requires' constraint-expression ';'
-            ExprResult ConstraintExpr =
-                Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());
+            ExprResult ConstraintExpr = ParseConstraintExpression();
             if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) {
               SkipUntil(tok::semi, tok::r_brace,
                         SkipUntilFlags::StopBeforeMatch);
@@ -3373,8 +3367,7 @@ ExprResult Parser::ParseRequiresExpression() {
         //     simple-requirement:
         //         expression ';'
         SourceLocation StartLoc = Tok.getLocation();
-        ExprResult Expression =
-            Actions.CorrectDelayedTyposInExpr(ParseExpression());
+        ExprResult Expression = ParseExpression();
         if (!Expression.isUsable()) {
           SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
           break;
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index df8372b995e55..a3be3744a9327 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -477,8 +477,6 @@ ExprResult Parser::ParseBraceInitializer() {
     if (Tok.is(tok::ellipsis))
       SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
 
-    SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get());
-
     // If we couldn't parse the subelement, bail out.
     if (SubElt.isUsable()) {
       InitExprs.push_back(SubElt.get());
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 6afb7809d3cd2..8ef16a4d3808a 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2629,10 +2629,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
   if (!Tok.isSimpleTypeSpecifier(getLangOpts())) {
     //   objc-receiver:
     //     expression
-    // Make sure any typos in the receiver are corrected or diagnosed, so that
-    // proper recovery can happen. FIXME: Perhaps filter the corrected expr to
-    // only the things that are valid ObjC receivers?
-    ExprResult Receiver = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+    ExprResult Receiver = ParseExpression();
     if (Receiver.isInvalid())
       return true;
 
@@ -2809,7 +2806,7 @@ ExprResult Parser::ParseObjCMessageExpression() {
   }
 
   // Otherwise, an arbitrary expression can be the receiver of a send.
-  ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+  ExprResult Res = ParseExpression();
   if (Res.isInvalid()) {
     SkipUntil(tok::r_square, StopAtSemi);
     return Res;
@@ -2930,8 +2927,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
       SourceLocation commaLoc = ConsumeToken(); // Eat the ','.
       ///  Parse the expression after ','
       ExprResult Res(ParseAssignmentExpression());
-      if (Tok.is(tok::colon))
-        Res = Actions.CorrectDelayedTyposInExpr(Res);
       if (Res.isInvalid()) {
         if (Tok.is(tok::colon)) {
           Diag(commaLoc, diag::note_extra_comma_message_arg) <<
@@ -3078,10 +3073,6 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
       return Res;
     }
 
-    Res = Actions.CorrectDelayedTyposInExpr(Res.get());
-    if (Res.isInvalid())
-      HasInvalidEltExpr = true;
-
     // Parse the ellipsis that indicates a pack expansion.
     if (Tok.is(tok::ellipsis))
       Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken());
@@ -3108,7 +3099,6 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
 ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
   SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements.
   ConsumeBrace(); // consume the l_square.
-  bool HasInvalidEltExpr = false;
   while (Tok.isNot(tok::r_brace)) {
     // Parse the comma separated key : value expressions.
     ExprResult KeyExpr;
@@ -3138,12 +3128,6 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
       return ValueExpr;
     }
 
-    // Check the key and value for possible typos
-    KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.get());
-    ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.get());
-    if (KeyExpr.isInvalid() || ValueExpr.isInvalid())
-      HasInvalidEltExpr = true;
-
     // Parse the ellipsis that designates this as a pack expansion. Do not
     // ActOnPackExpansion here, leave it to template instantiation time where
     // we can get better diagnostics.
@@ -3163,9 +3147,6 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
   }
   SourceLocation EndLoc = ConsumeBrace();
 
-  if (HasInvalidEltExpr)
-    return ExprError();
-
   // Create the ObjCDictionaryLiteral.
   return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
                                                    Elements);
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index e2c2463200892..748068927c0a7 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -653,7 +653,7 @@ ExprResult Parser::ParseOpenACCConditionExpr() {
   // it does in an if/while/etc (See ParseCXXCondition), however as it was
   // written with Fortran/C in mind, we're going to assume it just means an
   // 'expression evaluating to boolean'.
-  ExprResult ER = getActions().CorrectDelayedTyposInExpr(ParseExpression());
+  ExprResult ER = ParseExpression();
 
   if (!ER.isUsable())
     return ER;
@@ -760,12 +760,6 @@ Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
   if (!ER.isUsable())
     return {ER, OpenACCParseCanContinue::Cannot};
 
-  // Parsing can continue after the initial assignment expression parsing, so
-  // even if there was a typo, we can continue.
-  ER = getActions().CorrectDelayedTyposInExpr(ER);
-  if (!ER.isUsable())
-    return {ER, OpenACCParseCanContinue::Can};
-
   return {getActions().OpenACC().ActOnIntExpr(DK, CK, Loc, ER.get()),
           OpenACCParseCanContinue::Can};
 }
@@ -835,8 +829,7 @@ ExprResult Parser::ParseOpenACCSizeExpr(OpenACCClauseKind CK) {
     return getActions().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
   }
 
-  ExprResult SizeExpr =
-      getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
+  ExprResult SizeExpr = ParseConstantExpression();
 
   if (!SizeExpr.isUsable())
     return SizeExpr;
@@ -890,8 +883,7 @@ Parser::OpenACCGangArgRes Parser::ParseOpenACCGangArg(SourceLocation GangLoc) {
     ConsumeToken();
     // Parse this as a const-expression, and we'll check its integer-ness/value
     // in CheckGangExpr.
-    ExprResult Res =
-        getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
+    ExprResult Res = ParseConstantExpression();
     return {OpenACCGangKind::Dim, Res};
   }
 
@@ -1065,8 +1057,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
     case OpenACCClauseKind::Collapse: {
       bool HasForce = tryParseAndConsumeSpecialTokenKind(
           *this, OpenACCSpecialTokenKind::Force, ClauseKind);
-      ExprResult LoopCount =
-          getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
+      ExprResult LoopCount = ParseConstantExpression();
       if (LoopCount.isInvalid()) {
         Parens.skipToEnd();
         return OpenACCCanContinue();
@@ -1363,7 +1354,7 @@ ExprResult Parser::ParseOpenACCIDExpression() {
                                     /*isAddressOfOperand=*/false);
   }
 
-  return getActions().CorrectDelayedTyposInExpr(Res);
+  return Res;
 }
 
 std::variant<std::monostate, clang::StringLiteral *, IdentifierInfo *>
@@ -1390,9 +1381,8 @@ Parser::ParseOpenACCBindClauseArgument() {
     return std::monostate{};
   }
 
-  ExprResult Res =
-      getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression(
-          /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true));
+  ExprResult Res = ParseStringLiteralExpression(
+      /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true);
   if (!Res.isUsable())
     return std::monostate{};
   return cast<StringLiteral>(Res.get());
@@ -1406,10 +1396,6 @@ Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCDirectiveKind DK,
   if (!Res.isUsable())
     return {Res, OpenACCParseCanContinue::Cannot};
 
-  Res = getActions().CorrectDelayedTyposInExpr(Res.get());
-  if (!Res.isUsable())
-    return {Res, OpenACCParseCanContinue::Can};
-
   Res = getActions().OpenACC().ActOnVar(DK, CK, Res.get());
 
   return {Res, OpenACCParseCanContinue::Can};
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 1e39d89a0c211..c8c83550cbb5e 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3589,8 +3589,7 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
       while (Tok.isNot(tok::r_paren)) {
         SourceLocation Loc = Tok.getLocation();
         ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
-        ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
-            ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+        ExprResult PTExpr = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
         PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
                                              /*DiscardedValue=*/false);
         if (PTExpr.isUsable()) {
@@ -3651,8 +3650,7 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
 
   // Parse the variable.
   SourceLocation VarLoc = Tok.getLocation();
-  ExprResult InteropVarExpr =
-      Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+  ExprResult InteropVarExpr = ParseAssignmentExpression();
   if (!InteropVarExpr.isUsable()) {
     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
               StopBeforeMatch);
@@ -4277,8 +4275,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() {
     // Parse <begin>
     SourceLocation Loc = Tok.getLocation();
     ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
-    ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
-        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+    ExprResult Begin = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
                                         /*DiscardedValue=*/false);
     // Parse ':'.
@@ -4289,8 +4286,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() {
     // Parse <end>
     Loc = Tok.getLocation();
     LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
-    ExprResult End = Actions.CorrectDelayedTyposInExpr(
-        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+    ExprResult End = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
                                       /*DiscardedValue=*/false);
 
@@ -4303,8 +4299,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() {
       // Parse <step>
       Loc = Tok.getLocation();
       LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
-      Step = Actions.CorrectDelayedTyposInExpr(
-          ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+      Step = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
                                          /*DiscardedValue=*/false);
     }
@@ -4786,7 +4781,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
       Tail = ParseOpenMPIteratorsExpr();
     }
-    Tail = Actions.CorrectDelayedTyposInExpr(Tail);
     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
                                        /*DiscardedValue=*/false);
     if (Tail.isUsable() || Data.AllocateAlignment) {
@@ -4846,8 +4840,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
     if (!ParseOpenMPReservedLocator(Kind, Data, getLangOpts())) {
       // Parse variable
-      ExprResult VarExpr =
-          Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+      ExprResult VarExpr = ParseAssignmentExpression();
       if (VarExpr.isUsable()) {
         Vars.push_back(VarExpr.get());
       } else {
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index c788723023c8b..e680aaa361f36 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -602,7 +602,7 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
   {
     ParseScopeFlags FilterScope(this, getCurScope()->getFlags() |
                                           Scope::SEHFilterScope);
-    FilterExpr = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+    FilterExpr = ParseExpression();
   }
 
   if (getLangOpts().Borland) {
@@ -1829,11 +1829,7 @@ StmtResult Parser::ParseDoStatement() {
 
   SourceLocation Start = Tok.getLocation();
   ExprResult Cond = ParseExpression();
-  // Correct the typos in condition before closing the scope.
-  if (Cond.isUsable())
-    Cond = Actions.CorrectDelayedTyposInExpr(Cond, /*InitDecl=*/nullptr,
-                                             /*RecoverUncorrectedTypos=*/true);
-  else {
+  if (!Cond.isUsable()) {
     if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
       SkipUntil(tok::semi);
     Cond = Actions.CreateRecoveryExpr(
@@ -2015,7 +2011,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
     }
   } else {
     ProhibitAttributes(attrs);
-    Value = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+    Value = ParseExpression();
 
     ForEach = isTokIdentifier_in();
 
@@ -2174,12 +2170,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
   StmtResult ForEachStmt;
 
   if (ForRangeInfo.ParsedForRangeDecl()) {
-    ExprResult CorrectedRange =
-        Actions.CorrectDelayedTyposInExpr(ForRangeInfo.RangeExpr.get());
     ForRangeStmt = Actions.ActOnCXXForRangeStmt(
         getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(),
-        ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.get(),
-        T.getCloseLocation(), Sema::BFRK_Build,
+        ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc,
+        ForRangeInfo.RangeExpr.get(), T.getCloseLocation(), Sema::BFRK_Build,
         ForRangeInfo.LifetimeExtendTemps);
   } else if (ForEach) {
     // Similarly, we need to do the semantic analysis for a for-range
diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp
index f2417479a0e78..182907df56070 100644
--- a/clang/lib/Parse/ParseStmtAsm.cpp
+++ b/clang/lib/Parse/ParseStmtAsm.cpp
@@ -864,7 +864,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
     // Read the parenthesized expression.
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
-    ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression());
+    ExprResult Res = ParseExpression();
     T.consumeClose();
     if (Res.isInvalid()) {
       SkipUntil(tok::r_paren, StopAtSemi);
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index d3c9ca029c9aa..a16dbe95b788d 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -296,8 +296,7 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
     return nullptr;
   }
 
-  ExprResult ConstraintExprResult =
-      Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());
+  ExprResult ConstraintExprResult = ParseConstraintExpression();
   if (ConstraintExprResult.isInvalid()) {
     SkipUntil(tok::semi);
     if (D)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f8bfd60f2faad..cf7fc8100b1cf 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1202,15 +1202,6 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
   assert(LateParsedInstantiations.empty() &&
          "end of TU template instantiation should not create more "
          "late-parsed templates");
-
-  // Report diagnostics for uncorrected delayed typos. Ideally all of them
-  // should have been corrected by that time, but it is very hard to cover all
-  // cases in practice.
-  for (const auto &Typo : DelayedTypos) {
-    // We pass an empty TypoCorrection to indicate no correction was performed.
-    Typo.second.DiagHandler(TypoCorrection());
-  }
-  DelayedTypos.clear();
 }
 
 void Sema::ActOnEndOfTranslationUnit() {
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 930e9083365a1..4674ee9bedc3a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2607,8 +2607,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
     bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
     ExprResult Res =
         BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
-    if (Res.isInvalid())
-      CorrectDelayedTyposInExpr(TheCallResult.get());
     return Res;
   }
   case Builtin::BI__builtin_dump_struct:
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 425b32e53a7b7..a1389c6c034b1 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -309,15 +309,6 @@ static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc,
   if (Result.isInvalid())
     return ExprError();
 
-  // We meant exactly what we asked for. No need for typo correction.
-  if (auto *TE = dyn_cast<TypoExpr>(Result.get())) {
-    S.clearDelayedTypo(TE);
-    S.Diag(Loc, diag::err_no_member)
-        << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl()
-        << Base->getSourceRange();
-    return ExprError();
-  }
-
   auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
   return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, EndLoc, nullptr);
 }
@@ -811,7 +802,6 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
     return ExprError();
 
   if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
-    CorrectDelayedTyposInExpr(E);
     return ExprError();
   }
 
@@ -970,7 +960,6 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
     return ExprError();
 
   if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) {
-    CorrectDelayedTyposInExpr(E);
     return ExprError();
   }
 
@@ -1025,7 +1014,6 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
 
 StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
   if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
-    CorrectDelayedTyposInExpr(E);
     return StmtError();
   }
   return BuildCoreturnStmt(Loc, E);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 86b871396ec90..384536aa2d5d2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13586,7 +13586,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
   if (!RealDecl) {
-    CorrectDelayedTyposInExpr(Init, dyn_cast_or_null<VarDecl>(RealDecl));
     return;
   }
 
@@ -13609,12 +13608,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   }
 
   if (VDecl->isInvalidDecl()) {
-    ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
-    SmallVector<Expr *> SubExprs;
-    if (Res.isUsable())
-      SubExprs.push_back(Res.get());
     ExprResult Recovery =
-        CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs);
+        CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init});
     if (Expr *E = Recovery.get())
       VDecl->setInit(E);
     return;
@@ -13629,23 +13624,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
 
   // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (VDecl->getType()->isUndeducedType()) {
-    // Attempt typo correction early so that the type of the init expression can
-    // be deduced based on the chosen correction if the original init contains a
-    // TypoExpr.
-    ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
-    if (!Res.isUsable()) {
-      // There are unresolved typos in Init, just drop them.
-      // FIXME: improve the recovery strategy to preserve the Init.
-      RealDecl->setInvalidDecl();
-      return;
-    }
-    if (Res.get()->containsErrors()) {
+    if (Init->containsErrors()) {
       // Invalidate the decl as we don't know the type for recovery-expr yet.
       RealDecl->setInvalidDecl();
-      VDecl->setInit(Res.get());
+      VDecl->setInit(Init);
       return;
     }
-    Init = Res.get();
 
     if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))
       return;
@@ -13791,23 +13775,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
       InitializedFromParenListExpr = true;
     }
 
-    // Try to correct any TypoExprs in the initialization arguments.
-    for (size_t Idx = 0; Idx < Args.size(); ++Idx) {
-      ExprResult Res = CorrectDelayedTyposInExpr(
-          Args[Idx], VDecl, /*RecoverUncorrectedTypos=*/true,
-          [this, Entity, Kind](Expr *E) {
-            InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E));
-            return Init.Failed() ? ExprError() : E;
-          });
-      if (!Res.isUsable()) {
-        VDecl->setInvalidDecl();
-      } else if (Res.get() != Args[Idx]) {
-        Args[Idx] = Res.get();
-      }
-    }
-    if (VDecl->isInvalidDecl())
-      return;
-
     InitializationSequence InitSeq(*this, Entity, Kind, Args,
                                    /*TopLevelOfInitList=*/false,
                                    /*TreatUnavailableAsInvalid=*/false);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 4a735992cec68..ce82ca2812690 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4155,10 +4155,6 @@ ExprResult Sema::ActOnRequiresClause(ExprResult ConstraintExpr) {
   if (ConstraintExpr.isInvalid())
     return ExprError();
 
-  ConstraintExpr = CorrectDelayedTyposInExpr(ConstraintExpr);
-  if (ConstraintExpr.isInvalid())
-    return ExprError();
-
   if (DiagnoseUnexpandedParameterPack(ConstraintExpr.get(),
                                       UPPC_RequiresClause))
     return ExprError();
@@ -4208,23 +4204,20 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
     return;
   }
 
-  ExprResult Init = CorrectDelayedTyposInExpr(InitExpr, /*InitDecl=*/nullptr,
-                                              /*RecoverUncorrectedTypos=*/true);
-  assert(Init.isUsable() && "Init should at least have a RecoveryExpr");
-  if (!FD->getType()->isDependentType() && !Init.get()->isTypeDependent()) {
-    Init = ConvertMemberDefaultInitExpression(FD, Init.get(), InitLoc);
+  if (!FD->getType()->isDependentType() && !InitExpr.get()->isTypeDependent()) {
+    InitExpr = ConvertMemberDefaultInitExpression(FD, InitExpr.get(), InitLoc);
     // C++11 [class.base.init]p7:
     //   The initialization of each base and member constitutes a
     //   full-expression.
-    if (!Init.isInvalid())
-      Init = ActOnFinishFullExpr(Init.get(), /*DiscarededValue=*/false);
-    if (Init.isInvalid()) {
+    if (!InitExpr.isInvalid())
+      InitExpr = ActOnFinishFullExpr(InitExpr.get(), /*DiscarededValue=*/false);
+    if (InitExpr.isInvalid()) {
       FD->setInvalidDecl();
       return;
     }
   }
 
-  FD->setInClassInitializer(Init.get());
+  FD->setInClassInitializer(InitExpr.get());
 }
 
 /// Find the direct and/or virtual base specifiers that
@@ -4394,13 +4387,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD,
                           SourceLocation IdLoc,
                           Expr *Init,
                           SourceLocation EllipsisLoc) {
-  ExprResult Res = CorrectDelayedTyposInExpr(Init, /*InitDecl=*/nullptr,
-                                             /*RecoverUncorrectedTypos=*/true);
-  if (!Res.isUsable())
-    return true;
-  Init = Res.get();
-
-  if (!ConstructorD)
+  if (!ConstructorD || !Init)
     return true;
 
   AdjustDeclIfTemplate(ConstructorD);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 419612cf2fdb6..b490cb2ce9224 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2615,19 +2615,6 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
 
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
-  if (S && Out) {
-    assert(!ExplicitTemplateArgs &&
-           "Diagnosing an empty lookup with explicit template args!");
-    *Out = CorrectTypoDelayed(
-        R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
-        [=](const TypoCorrection &TC) {
-          emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, NameRange,
-                                        diagnostic, diagnostic_suggest);
-        },
-        nullptr, CorrectTypoKind::ErrorRecovery, LookupCtx);
-    if (*Out)
-      return true;
-  }
   if (S && (Corrected =
                 CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
                             CCC, CorrectTypoKind::ErrorRecovery, LookupCtx))) {
@@ -7023,40 +7010,6 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
                          CurFPFeatureOverrides(), NumParams, UsesADL);
   }
 
-  if (!Context.isDependenceAllowed()) {
-    // Forget about the nulled arguments since typo correction
-    // do not handle them well.
-    TheCall->shrinkNumArgs(Args.size());
-    // C cannot always handle TypoExpr nodes in builtin calls and direct
-    // function calls as their argument checking don't necessarily handle
-    // dependent types properly, so make sure any TypoExprs have been
-    // dealt with.
-    ExprResult Result = CorrectDelayedTyposInExpr(TheCall);
-    if (!Result.isUsable()) return ExprError();
-    CallExpr *TheOldCall = TheCall;
-    TheCall = dyn_cast<CallExpr>(Result.get());
-    bool CorrectedTypos = TheCall != TheOldCall;
-    if (!TheCall) return Result;
-    Args = llvm::ArrayRef(TheCall->getArgs(), TheCall->getNumArgs());
-
-    // A new call expression node was created if some typos were corrected.
-    // However it may not have been constructed with enough storage. In this
-    // case, rebuild the node with enough storage. The waste of space is
-    // immaterial since this only happens when some typos were corrected.
-    if (CorrectedTypos && Args.size() < NumParams) {
-      if (Config)
-        TheCall = CUDAKernelCallExpr::Create(
-            Context, Fn, cast<CallExpr>(Config), Args, ResultTy, VK_PRValue,
-            RParenLoc, CurFPFeatureOverrides(), NumParams);
-      else
-        TheCall =
-            CallExpr::Create(Context, Fn, Args, ResultTy, VK_PRValue, RParenLoc,
-                             CurFPFeatureOverrides(), NumParams, UsesADL);
-    }
-    // We can now handle the nulled arguments for the default arguments.
-    TheCall->setNumArgsUnsafe(std::max<unsigned>(Args.size(), NumParams));
-  }
-
   // Bail out early if calling a builtin with custom type checking.
   if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) {
     ExprResult E = CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
@@ -7947,12 +7900,6 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
   if (getLangOpts().CPlusPlus) {
     // Check that there are no default arguments (C++ only).
     CheckExtraCXXDefaultArguments(D);
-  } else {
-    // Make sure any TypoExprs have been dealt with.
-    ExprResult Res = CorrectDelayedTyposInExpr(CastExpr);
-    if (!Res.isUsable())
-      return ExprError();
-    CastExpr = Res.get();
   }
 
   checkUnusedDeclAttributes(D);
@@ -8998,30 +8945,6 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
                                     SourceLocation ColonLoc,
                                     Expr *CondExpr, Expr *LHSExpr,
                                     Expr *RHSExpr) {
-  if (!Context.isDependenceAllowed()) {
-    // C cannot handle TypoExpr nodes in the condition because it
-    // doesn't handle dependent types properly, so make sure any TypoExprs have
-    // been dealt with before checking the operands.
-    ExprResult CondResult = CorrectDelayedTyposInExpr(CondExpr);
-    ExprResult LHSResult = CorrectDelayedTyposInExpr(LHSExpr);
-    ExprResult RHSResult = CorrectDelayedTyposInExpr(RHSExpr);
-
-    if (!CondResult.isUsable())
-      return ExprError();
-
-    if (LHSExpr) {
-      if (!LHSResult.isUsable())
-        return ExprError();
-    }
-
-    if (!RHSResult.isUsable())
-      return ExprError();
-
-    CondExpr = CondResult.get();
-    LHSExpr = LHSResult.get();
-    RHSExpr = RHSResult.get();
-  }
-
   // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
   // was the condition.
   OpaqueValueExpr *opaqueValue = nullptr;
@@ -15068,28 +14991,6 @@ static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS,
   return convertVector(BO, ResultTy->castAs<VectorType>()->getElementType(), S);
 }
 
-static std::pair<ExprResult, ExprResult>
-CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr,
-                           Expr *RHSExpr) {
-  ExprResult LHS = LHSExpr, RHS = RHSExpr;
-  if (!S.Context.isDependenceAllowed()) {
-    // C cannot handle TypoExpr nodes on either side of a binop because it
-    // doesn't handle dependent types properly, so make sure any TypoExprs have
-    // been dealt with before checking the operands.
-    LHS = S.CorrectDelayedTyposInExpr(LHS);
-    RHS = S.CorrectDelayedTyposInExpr(
-        RHS, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false,
-        [Opc, LHS](Expr *E) {
-          if (Opc != BO_Assign)
-            return ExprResult(E);
-          // Avoid correcting the RHS to the same Expr as the LHS.
-          Decl *D = getDeclFromExpr(E);
-          return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E;
-        });
-  }
-  return std::make_pair(LHS, RHS);
-}
-
 /// Returns true if conversion between vectors of halfs and vectors of floats
 /// is needed.
 static bool needsConversionOfHalfVec(bool OpRequiresConversion, ASTContext &Ctx,
@@ -15146,7 +15047,6 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
   ExprObjectKind OK = OK_Ordinary;
   bool ConvertHalfVec = false;
 
-  std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr);
   if (!LHS.isUsable() || !RHS.isUsable())
     return ExprError();
 
@@ -15662,12 +15562,8 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,
 ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                             BinaryOperatorKind Opc, Expr *LHSExpr,
                             Expr *RHSExpr, bool ForFoldExpression) {
-  ExprResult LHS, RHS;
-  std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr);
-  if (!LHS.isUsable() || !RHS.isUsable())
+  if (!LHSExpr || !RHSExpr)
     return ExprError();
-  LHSExpr = LHS.get();
-  RHSExpr = RHS.get();
 
   // We want to end up calling one of SemaPseudoObject::checkAssignment
   // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if
@@ -18194,8 +18090,6 @@ HandleImmediateInvocations(Sema &SemaRef,
 
 void Sema::PopExpressionEvaluationContext() {
   ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
-  unsigned NumTypos = Rec.NumTypos;
-
   if (!Rec.Lambdas.empty()) {
     using ExpressionKind = ExpressionEvaluationContextRecord::ExpressionKind;
     if (!getLangOpts().CPlusPlus20 &&
@@ -18263,9 +18157,6 @@ void Sema::PopExpressionEvaluationContext() {
 
   // Pop the current expression evaluation context off the stack.
   ExprEvalContexts.pop_back();
-
-  // The global expression evaluation context record is never popped.
-  ExprEvalContexts.back().NumTypos += NumTypos;
 }
 
 void Sema::DiscardCleanupsInEvaluationContext() {
@@ -20023,8 +19914,6 @@ ExprResult Sema::CheckLValueToRValueConversionOperand(Expr *E) {
 }
 
 ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
-  Res = CorrectDelayedTyposInExpr(Res);
-
   if (!Res.isUsable())
     return Res;
 
@@ -21350,15 +21239,6 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
 }
 
 ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
-  if (!Context.isDependenceAllowed()) {
-    // C cannot handle TypoExpr nodes on either side of a binop because it
-    // doesn't handle dependent types properly, so make sure any TypoExprs have
-    // been dealt with before checking the operands.
-    ExprResult Result = CorrectDelayedTyposInExpr(E);
-    if (!Result.isUsable()) return ExprError();
-    E = Result.get();
-  }
-
   const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();
   if (!placeholderType) return E;
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 7b08fb869ccca..c901ab2ca3cfa 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1500,13 +1500,7 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
 
   auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs,
                                           RParenOrBraceLoc, ListInitialization);
-  // Avoid creating a non-type-dependent expression that contains typos.
-  // Non-type-dependent expressions are liable to be discarded without
-  // checking for embedded typos.
-  if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
-      !Result.get()->isTypeDependent())
-    Result = CorrectDelayedTyposInExpr(Result.get());
-  else if (Result.isInvalid())
+  if (Result.isInvalid())
     Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
                                 RParenOrBraceLoc, exprs, Ty);
   return Result;
@@ -8023,38 +8017,6 @@ class TransformTypos : public TreeTransform<TransformTypos> {
 };
 }
 
-ExprResult
-Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl,
-                                bool RecoverUncorrectedTypos,
-                                llvm::function_ref<ExprResult(Expr *)> Filter) {
-  // If the current evaluation context indicates there are uncorrected typos
-  // and the current expression isn't guaranteed to not have typos, try to
-  // resolve any TypoExpr nodes that might be in the expression.
-  if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos &&
-      (E->isTypeDependent() || E->isValueDependent() ||
-       E->isInstantiationDependent())) {
-    auto TyposResolved = DelayedTypos.size();
-    auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E);
-    TyposResolved -= DelayedTypos.size();
-    if (Result.isInvalid() || Result.get() != E) {
-      ExprEvalContexts.back().NumTypos -= TyposResolved;
-      if (Result.isInvalid() && RecoverUncorrectedTypos) {
-        struct TyposReplace : TreeTransform<TyposReplace> {
-          TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {}
-          ExprResult TransformTypoExpr(clang::TypoExpr *E) {
-            return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(),
-                                                    E->getEndLoc(), {});
-          }
-        } TT(*this);
-        return TT.TransformExpr(E);
-      }
-      return Result;
-    }
-    assert(TyposResolved == 0 && "Corrected typo but got same Expr back?");
-  }
-  return E;
-}
-
 ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
                                      bool DiscardedValue, bool IsConstexpr,
                                      bool IsTemplateArgument) {
@@ -8086,8 +8048,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
     DiagnoseUnusedExprResult(FullExpr.get(), diag::warn_unused_expr);
   }
 
-  FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr,
-                                       /*RecoverUncorrectedTypos=*/true);
   if (FullExpr.isInvalid())
     return ExprError();
 
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 39c162c3b835d..100aeb7ebcdd3 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -650,58 +650,6 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
   return true;
 }
 
-namespace {
-
-// Callback to only accept typo corrections that are either a ValueDecl or a
-// FunctionTemplateDecl and are declared in the current record or, for a C++
-// classes, one of its base classes.
-class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback {
-public:
-  explicit RecordMemberExprValidatorCCC(QualType RTy)
-      : Record(RTy->getAsRecordDecl()) {
-    // Don't add bare keywords to the consumer since they will always fail
-    // validation by virtue of not being associated with any decls.
-    WantTypeSpecifiers = false;
-    WantExpressionKeywords = false;
-    WantCXXNamedCasts = false;
-    WantFunctionLikeCasts = false;
-    WantRemainingKeywords = false;
-  }
-
-  bool ValidateCandidate(const TypoCorrection &candidate) override {
-    NamedDecl *ND = candidate.getCorrectionDecl();
-    // Don't accept candidates that cannot be member functions, constants,
-    // variables, or templates.
-    if (!ND || !(isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)))
-      return false;
-
-    // Accept candidates that occur in the current record.
-    if (Record->containsDecl(ND))
-      return true;
-
-    if (const auto *RD = dyn_cast<CXXRecordDecl>(Record)) {
-      // Accept candidates that occur in any of the current class' base classes.
-      for (const auto &BS : RD->bases()) {
-        if (const auto *BSTy = BS.getType()->getAs<RecordType>()) {
-          if (BSTy->getDecl()->containsDecl(ND))
-            return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-  std::unique_ptr<CorrectionCandidateCallback> clone() override {
-    return std::make_unique<RecordMemberExprValidatorCCC>(*this);
-  }
-
-private:
-  const RecordDecl *const Record;
-};
-
-}
-
 static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
                                      Expr *BaseExpr, QualType RTy,
                                      SourceLocation OpLoc, bool IsArrow,
@@ -724,56 +672,6 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
                                       /*EnteringContext=*/false, TemplateKWLoc);
 
   SemaRef.LookupParsedName(R, /*S=*/nullptr, &SS, ObjectType);
-
-  if (!R.empty() || R.wasNotFoundInCurrentInstantiation())
-    return false;
-
-  DeclarationName Typo = R.getLookupName();
-  SourceLocation TypoLoc = R.getNameLoc();
-  // Recompute the lookup context.
-  DeclContext *DC = SS.isSet() ? SemaRef.computeDeclContext(SS)
-                               : SemaRef.computeDeclContext(RTy);
-
-  struct QueryState {
-    Sema &SemaRef;
-    DeclarationNameInfo NameInfo;
-    Sema::LookupNameKind LookupKind;
-    RedeclarationKind Redecl;
-  };
-  QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
-                  R.redeclarationKind()};
-  RecordMemberExprValidatorCCC CCC(RTy);
-  TE = SemaRef.CorrectTypoDelayed(
-      R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC,
-      [=, &SemaRef](const TypoCorrection &TC) {
-        if (TC) {
-          assert(!TC.isKeyword() &&
-                 "Got a keyword as a correction for a member!");
-          bool DroppedSpecifier =
-              TC.WillReplaceSpecifier() &&
-              Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
-          SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
-                                       << Typo << DC << DroppedSpecifier
-                                       << SS.getRange());
-        } else {
-          SemaRef.Diag(TypoLoc, diag::err_no_member)
-              << Typo << DC << (SS.isSet() ? SS.getRange() : BaseRange);
-        }
-      },
-      [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
-        LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl);
-        R.clear(); // Ensure there's no decls lingering in the shared state.
-        R.suppressDiagnostics();
-        R.setLookupName(TC.getCorrection());
-        for (NamedDecl *ND : TC)
-          R.addDecl(ND);
-        R.resolveKind();
-        return SemaRef.BuildMemberReferenceExpr(
-            BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(),
-            nullptr, R, nullptr, nullptr);
-      },
-      CorrectTypoKind::ErrorRecovery, DC);
-
   return false;
 }
 
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 269ec888f299d..867034c932326 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -5431,43 +5431,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
   return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure && !SecondBestTC);
 }
 
-TypoExpr *Sema::CorrectTypoDelayed(
-    const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
-    Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC,
-    TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode,
-    DeclContext *MemberContext, bool EnteringContext,
-    const ObjCObjectPointerType *OPT) {
-  if (!LangOpts.DelayedTypoCorrection)
-    return nullptr;
-
-  auto Consumer = makeTypoCorrectionConsumer(
-      TypoName, LookupKind, S, SS, CCC, MemberContext, EnteringContext, OPT,
-      Mode == CorrectTypoKind::ErrorRecovery);
-
-  // Give the external sema source a chance to correct the typo.
-  TypoCorrection ExternalTypo;
-  if (ExternalSource && Consumer) {
-    ExternalTypo = ExternalSource->CorrectTypo(
-        TypoName, LookupKind, S, SS, *Consumer->getCorrectionValidator(),
-        MemberContext, EnteringContext, OPT);
-    if (ExternalTypo)
-      Consumer->addCorrection(ExternalTypo);
-  }
-
-  if (!Consumer || Consumer->empty())
-    return nullptr;
-
-  // Make sure the best edit distance (prior to adding any namespace qualifiers)
-  // is not more that about a third of the length of the typo's identifier.
-  unsigned ED = Consumer->getBestEditDistance(true);
-  IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();
-  if (!ExternalTypo && ED > 0 && Typo->getName().size() / ED < 3)
-    return nullptr;
-  ExprEvalContexts.back().NumTypos++;
-  return createDelayedTypo(std::move(Consumer), std::move(TDG), std::move(TRC),
-                           TypoName.getLoc());
-}
-
 void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
   if (!CDecl) return;
 
@@ -5792,21 +5755,6 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,
     Diag(Correction.getCorrectionRange().getBegin(), PD);
 }
 
-TypoExpr *Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
-                                  TypoDiagnosticGenerator TDG,
-                                  TypoRecoveryCallback TRC,
-                                  SourceLocation TypoLoc) {
-  assert(TCC && "createDelayedTypo requires a valid TypoCorrectionConsumer");
-  auto TE = new (Context) TypoExpr(Context.DependentTy, TypoLoc);
-  auto &State = DelayedTypos[TE];
-  State.Consumer = std::move(TCC);
-  State.DiagHandler = std::move(TDG);
-  State.RecoveryHandler = std::move(TRC);
-  if (TE)
-    TypoExprs.push_back(TE);
-  return TE;
-}
-
 const Sema::TypoExprState &Sema::getTypoExprState(TypoExpr *TE) const {
   auto Entry = DelayedTypos.find(TE);
   assert(Entry != DelayedTypos.end() &&
diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp
index 56815cd2731a1..0f39a9817ce7f 100644
--- a/clang/lib/Sema/SemaObjC.cpp
+++ b/clang/lib/Sema/SemaObjC.cpp
@@ -124,17 +124,12 @@ ExprResult SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc,
   if (!collection)
     return ExprError();
 
-  ExprResult result = SemaRef.CorrectDelayedTyposInExpr(collection);
-  if (!result.isUsable())
-    return ExprError();
-  collection = result.get();
-
   // Bail out early if we've got a type-dependent expression.
   if (collection->isTypeDependent())
     return collection;
 
   // Perform normal l-value conversion.
-  result = SemaRef.DefaultFunctionArrayLvalueConversion(collection);
+  ExprResult result = SemaRef.DefaultFunctionArrayLvalueConversion(collection);
   if (result.isInvalid())
     return ExprError();
   collection = result.get();
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index bc873937f6dc5..b9711306ad871 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -535,12 +535,7 @@ Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) {
     return ER;
   };
 
-  ExprResult Converted = CorrectDelayedTyposInExpr(
-      Val, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false,
-      CheckAndFinish);
-  if (Converted.get() == Val.get())
-    Converted = CheckAndFinish(Val.get());
-  return Converted;
+  return CheckAndFinish(Val.get());
 }
 
 StmtResult
@@ -2344,7 +2339,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
 static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
                                   SourceLocation Loc, int DiagID) {
   if (Decl->getType()->isUndeducedType()) {
-    ExprResult Res = SemaRef.CorrectDelayedTyposInExpr(Init);
+    ExprResult Res = Init;
     if (!Res.isUsable()) {
       Decl->setInvalidDecl();
       return true;
@@ -3845,10 +3840,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
 StmtResult
 Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
                       Scope *CurScope) {
-  // Correct typos, in case the containing function returns 'auto' and
-  // RetValExp should determine the deduced type.
-  ExprResult RetVal = CorrectDelayedTyposInExpr(
-      RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true);
+  ExprResult RetVal = RetValExp;
   if (RetVal.isInvalid())
     return StmtError();
 
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index 17da5fd8325be..b78080c991763 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -782,11 +782,10 @@ ExprResult Sema::ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A,
 ExprResult Sema::BuildCXXAssumeExpr(Expr *Assumption,
                                     const IdentifierInfo *AttrName,
                                     SourceRange Range) {
-  ExprResult Res = CorrectDelayedTyposInExpr(Assumption);
-  if (Res.isInvalid())
+  if (!Assumption)
     return ExprError();
 
-  Res = CheckPlaceholderExpr(Res.get());
+  ExprResult Res = CheckPlaceholderExpr(Assumption);
   if (Res.isInvalid())
     return ExprError();
 
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 5f0e968ff18c4..572dbf2e7393f 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -741,7 +741,6 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
   if (!Pattern->containsUnexpandedParameterPack()) {
     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
     << Pattern->getSourceRange();
-    CorrectDelayedTyposInExpr(Pattern);
     return ExprError();
   }
 
@@ -1201,11 +1200,9 @@ ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression,
                                        SourceLocation RSquareLoc) {
   bool isParameterPack = ::isParameterPack(PackExpression);
   if (!isParameterPack) {
-    if (!PackExpression->containsErrors()) {
-      CorrectDelayedTyposInExpr(IndexExpr);
+    if (!PackExpression->containsErrors())
       Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack)
           << PackExpression;
-    }
     return ExprError();
   }
   ExprResult Res =
@@ -1403,11 +1400,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
   CheckFoldOperand(*this, LHS);
   CheckFoldOperand(*this, RHS);
 
-  auto DiscardOperands = [&] {
-    CorrectDelayedTyposInExpr(LHS);
-    CorrectDelayedTyposInExpr(RHS);
-  };
-
   // [expr.prim.fold]p3:
   //   In a binary fold, op1 and op2 shall be the same fold-operator, and
   //   either e1 shall contain an unexpanded parameter pack or e2 shall contain
@@ -1415,7 +1407,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
   if (LHS && RHS &&
       LHS->containsUnexpandedParameterPack() ==
           RHS->containsUnexpandedParameterPack()) {
-    DiscardOperands();
     return Diag(EllipsisLoc,
                 LHS->containsUnexpandedParameterPack()
                     ? diag::err_fold_expression_packs_both_sides
@@ -1430,7 +1421,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
     Expr *Pack = LHS ? LHS : RHS;
     assert(Pack && "fold expression with neither LHS nor RHS");
     if (!Pack->containsUnexpandedParameterPack()) {
-      DiscardOperands();
       return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
              << Pack->getSourceRange();
     }
diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c
index ac3e69b9c8f99..dec5554c7d020 100644
--- a/clang/test/AST/ast-dump-recovery.c
+++ b/clang/test/AST/ast-dump-recovery.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -fdelayed-typo-correction -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
 
 int some_func(int);
 
@@ -23,7 +23,7 @@ int postfix_inc = a++;
 // CHECK-NEXT:      `-IntegerLiteral {{.*}} 'int'
 int unary_address = &(a + 1);
 
-// CHECK:       VarDecl {{.*}} ternary 'int' cinit
+// CHECK:       VarDecl {{.*}} ternary 'int'
 // CHECK-NEXT:  `-ConditionalOperator {{.*}}
 // CHECK-NEXT:    |-DeclRefExpr {{.*}} 'a'
 // CHECK-NEXT:    |-RecoveryExpr {{.*}}
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index bd3057caa740a..b0d00fd349548 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -1,5 +1,5 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -fdelayed-typo-correction -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -fdelayed-typo-correction -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
 
 int some_func(int *);
 
@@ -444,7 +444,6 @@ void InitializerOfInvalidDecl() {
   Unknown InvalidDeclWithInvalidInit = Invalid;
   // CHECK:      VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NOT:    `-TypoExpr
 }
 
 void RecoverToAnInvalidDecl() {
diff --git a/clang/test/AST/ast-dump-recovery.m b/clang/test/AST/ast-dump-recovery.m
index 3c5ab125317b1..d47d2a438d5b1 100644
--- a/clang/test/AST/ast-dump-recovery.m
+++ b/clang/test/AST/ast-dump-recovery.m
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fdelayed-typo-correction -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
 
 @interface Foo
 - (void)method:(int)n;
@@ -6,9 +6,9 @@ - (void)method:(int)n;
 
 void k(Foo *foo) {
   // CHECK:       ObjCMessageExpr {{.*}} 'void' contains-errors
-  // CHECK-CHECK:  |-ImplicitCastExpr {{.*}} 'Foo *' <LValueToRValue>
-  // CHECK-CHECK:  | `-DeclRefExpr {{.*}} 'foo'
-  // CHECK-CHECK:  `-RecoveryExpr {{.*}}
+  // CHECK-NEXT:  |-ImplicitCastExpr {{.*}} 'Foo *' <LValueToRValue>
+  // CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'foo'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}}
   [foo method:undef];
 
   // CHECK:      ImplicitCastExpr {{.*}} '<dependent type>' contains-errors
diff --git a/clang/test/FixIt/typo.cpp b/clang/test/FixIt/typo.cpp
deleted file mode 100644
index 6ba2aed6baae8..0000000000000
--- a/clang/test/FixIt/typo.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
-// RUN: cp %s %t
-// RUN: not %clang_cc1 -fixit -fdelayed-typo-correction -x c++ %t
-// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
-// RUN: grep test_string %t
-
-namespace std {
-  template<typename T> class basic_string { // expected-note 3{{'basic_string' declared here}}
-  public:
-    int find(const char *substr); // expected-note{{'find' declared here}}
-    static const int npos = -1; // expected-note{{'npos' declared here}}
-  };
-
-  typedef basic_string<char> string; // expected-note 2{{'string' declared here}}
-}
-
-namespace otherstd { // expected-note 2{{'otherstd' declared here}} \
-                     // expected-note{{namespace 'otherstd' defined here}}
-  using namespace std;
-}
-
-using namespace std;
-
-other_std::strng str1; // expected-error{{use of undeclared identifier 'other_std'; did you mean 'otherstd'?}} \
-// expected-error{{no type named 'strng' in namespace 'otherstd'; did you mean 'string'?}}
-tring str2; // expected-error{{unknown type name 'tring'; did you mean 'string'?}}
-
-::other_std::string str3; // expected-error{{no member named 'other_std' in the global namespace; did you mean 'otherstd'?}}
-
-float area(float radius, // expected-note{{'radius' declared here}}
-           float pi) {
-  return radious * pi; // expected-error{{did you mean 'radius'?}}
-}
-
-using namespace othestd; // expected-error{{no namespace named 'othestd'; did you mean 'otherstd'?}}
-namespace blargh = otherstd; // expected-note 3{{namespace 'blargh' defined here}}
-using namespace ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}}
-
-namespace wibble = blarg; // expected-error{{no namespace named 'blarg'; did you mean 'blargh'?}}
-namespace wobble = ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}}
-
-bool test_string(std::string s) {
-  basc_string<char> b1; // expected-error{{no template named 'basc_string'; did you mean 'basic_string'?}}
-  std::basic_sting<char> b2; // expected-error{{no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'?}}
-  (void)b1;
-  (void)b2;
-  return s.fnd("hello") // expected-error{{no member named 'fnd' in 'std::basic_string<char>'; did you mean 'find'?}}
-    == std::string::pos; // expected-error{{no member named 'pos' in 'std::basic_string<char>'; did you mean 'npos'?}}
-}
-
-struct Base { };
-struct Derived : public Base { // expected-note{{base class 'Base' specified here}}
-  int member; // expected-note 3{{'member' declared here}}
-
-  Derived() : base(), // expected-error{{initializer 'base' does not name a non-static data member or base class; did you mean the base class 'Base'?}}
-              ember() { } // expected-error{{initializer 'ember' does not name a non-static data member or base class; did you mean the member 'member'?}}
-
-  int getMember() const {
-    return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}}
-  }
-
-  int &getMember();
-};
-
-int &Derived::getMember() {
-  return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}}
-}
-
-typedef int Integer; // expected-note{{'Integer' declared here}}
-int global_value; // expected-note{{'global_value' declared here}}
-
-int foo() {
-  integer * i = 0; // expected-error{{unknown type name 'integer'; did you mean 'Integer'?}}
-  unsinged *ptr = 0; // expected-error{{use of undeclared identifier 'unsinged'; did you mean 'unsigned'?}}
-  return *i + *ptr + global_val; // expected-error{{use of undeclared identifier 'global_val'; did you mean 'global_value'?}}
-}
-
-namespace nonstd {
-  typedef std::basic_string<char> yarn; // expected-note 2 {{'nonstd::yarn' declared here}}
-  int narf; // expected-note{{'nonstd::narf' declared here}}
-}
-
-yarn str4; // expected-error{{unknown type name 'yarn'; did you mean 'nonstd::yarn'?}}
-wibble::yarn str5; // expected-error{{no type named 'yarn' in namespace 'otherstd'; did you mean 'nonstd::yarn'?}}
-
-namespace another {
-  template<typename T> class wide_string {}; // expected-note {{'another::wide_string' declared here}}
-}
-int poit() {
-  nonstd::basic_string<char> str; // expected-error{{no template named 'basic_string' in namespace 'nonstd'; did you mean simply 'basic_string'?}}
-  nonstd::wide_string<char> str2; // expected-error{{no template named 'wide_string' in namespace 'nonstd'; did you mean 'another::wide_string'?}}
-  return wibble::narf; // expected-error{{no member named 'narf' in namespace 'otherstd'; did you mean 'nonstd::narf'?}}
-}
-
-namespace check_bool {
-  void f() {
-    Bool b; // expected-error{{use of undeclared identifier 'Bool'; did you mean 'bool'?}}
-  }
-}
-
-namespace outr {
-}
-namespace outer {
-  namespace inner { // expected-note{{'outer::inner' declared here}} \
-                    // expected-note{{namespace 'outer::inner' defined here}} \
-                    // expected-note{{'inner' declared here}}
-    int i;
-  }
-}
-
-using namespace outr::inner; // expected-error{{no namespace named 'inner' in namespace 'outr'; did you mean 'outer::inner'?}}
-
-void func() {
-  outr::inner::i = 3; // expected-error{{no member named 'inner' in namespace 'outr'; did you mean 'outer::inner'?}}
-  outer::innr::i = 4; // expected-error{{no member named 'innr' in namespace 'outer'; did you mean 'inner'?}}
-}
-
-struct base {
-};
-struct derived : base {
-  int i;
-};
-
-void func2() {
-  derived d;
-  // FIXME: we should offer a fix here. We do if the 'i' is misspelled, but we don't do name qualification changes
-  //        to replace base::i with derived::i as we would for other qualified name misspellings.
-  // d.base::i = 3;
-}
-
-class A {
-  void bar(int);
-};
-void bar(int, int);  // expected-note{{'::bar' declared here}}
-void A::bar(int x) {
-  bar(x, 5);  // expected-error{{too many arguments to function call, expected 1, have 2; did you mean '::bar'?}}
-}
diff --git a/clang/test/Index/complete-switch.c b/clang/test/Index/complete-switch.c
deleted file mode 100644
index d588993504eaf..0000000000000
--- a/clang/test/Index/complete-switch.c
+++ /dev/null
@@ -1,10 +0,0 @@
-void f() {
-  auto foo = bar;
-  switch(foo) {
-    case x:
-      break;
-  }
-}
-
-// RUN: not %clang_cc1 -fsyntax-only -fno-recovery-ast -fdelayed-typo-correction -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty
-// CHECK-NOT: COMPLETION: foo
diff --git a/clang/test/Index/fix-its.c b/clang/test/Index/fix-its.c
index be4ac4a4827b0..8378fd9da9b43 100644
--- a/clang/test/Index/fix-its.c
+++ b/clang/test/Index/fix-its.c
@@ -1,27 +1,12 @@
-// RUN: c-index-test -test-load-source all -fspell-checking -Xclang -fdelayed-typo-correction %s 2> %t
+// RUN: c-index-test -test-load-source all -fspell-checking %s 2> %t
 // RUN: FileCheck %s < %t
-struct X {
-  int wibble;
-};
-
 #define MACRO(X) X
 
-void f(struct X *x) {
-  // CHECK: error: no member named 'wobble' in 'struct X'; did you mean 'wibble'?
-  // CHECK: FIX-IT: Replace [13:12 - 13:18] with "wibble"
-  // CHECK: note: 'wibble' declared here
-  MACRO(x->wobble = 17);
-  // CHECK: error: no member named 'wabble' in 'struct X'; did you mean 'wibble'?
-  // CHECK: FIX-IT: Replace [17:6 - 17:12] with "wibble"
-  // CHECK: note: 'wibble' declared here
-  x->wabble = 17;
-}
-
 int printf(const char *restrict, ...);
 
 void f2() {
   unsigned long index;
   // CHECK: warning: format specifies type 'int' but the argument has type 'unsigned long'
-  // CHECK: FIX-IT: Replace [26:17 - 26:19] with "%lu"
+  // CHECK: FIX-IT: Replace [11:17 - 11:19] with "%lu"
   MACRO(printf("%d", index));
 }
diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m
index 12fa632618034..c770de13520df 100644
--- a/clang/test/Modules/diagnose-missing-import.m
+++ b/clang/test/Modules/diagnose-missing-import.m
@@ -7,11 +7,9 @@
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
                                                                   expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-                                                                  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
                                                                   expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
 }
 
-// expected-note at Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
 // expected-note at Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
 // expected-note at Inputs/diagnose-missing-import/a.h:6 {{declaration here is not visible}}
 
diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp
index db8d3c457b62b..2216761afb2ca 100644
--- a/clang/test/Parser/switch-recovery.cpp
+++ b/clang/test/Parser/switch-recovery.cpp
@@ -104,7 +104,7 @@ void test9(int x) { // expected-note {{'x' declared here}}
               expected-error {{expected expression}}
     8:: x; // expected-error {{expected ';' after expression}} \
               expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \
-              expected-warning {{expression result unused}}
+              expected-warning 2 {{expression result unused}}
     9:: :y; // expected-error {{expected ';' after expression}} \
                expected-error {{expected unqualified-id}} \
                expected-warning {{expression result unused}}
diff --git a/clang/test/Parser/switch-typo-correction.cpp b/clang/test/Parser/switch-typo-correction.cpp
index a923c35002c61..0744ce5f3598c 100644
--- a/clang/test/Parser/switch-typo-correction.cpp
+++ b/clang/test/Parser/switch-typo-correction.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
 
-namespace c { double xxx; } // expected-note{{'c::xxx' declared here}}
+namespace c { double xxx; }
 namespace d { float xxx; }
 namespace z { namespace xxx {} }
 
 void crash() {
-  switch (xxx) {} // expected-error{{use of undeclared identifier 'xxx'; did you mean }}
+  switch (xxx) {} // expected-error{{use of undeclared identifier 'xxx'}}
 }
diff --git a/clang/test/Sema/typo-correction-ambiguity.cpp b/clang/test/Sema/typo-correction-ambiguity.cpp
index 1cf30c2c80738..b2dae1d7696c3 100644
--- a/clang/test/Sema/typo-correction-ambiguity.cpp
+++ b/clang/test/Sema/typo-correction-ambiguity.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Check the following typo correction behavior in namespaces:
 // - no typos are diagnosed when an expression has ambiguous (multiple) corrections
@@ -18,12 +18,12 @@ void testAmbiguousNoSuggestions()
 
 namespace MultipleCorrectionsButNotAmbiguous
 {
-  int PrefixType_Name(int value);  // expected-note {{'PrefixType_Name' declared here}}
+  int PrefixType_Name(int value);
   int PrefixType_MIN();
   int PrefixType_MAX();
 };
 
 int testMultipleCorrectionsButNotAmbiguous() {
-  int val = MultipleCorrectionsButNotAmbiguous::PrefixType_Enum(0);  // expected-error {{no member named 'PrefixType_Enum' in namespace 'MultipleCorrectionsButNotAmbiguous'; did you mean 'PrefixType_Name'?}}
+  int val = MultipleCorrectionsButNotAmbiguous::PrefixType_Enum(0);  // expected-error {{no member named 'PrefixType_Enum' in namespace 'MultipleCorrectionsButNotAmbiguous'}}
   return val;
 }
diff --git a/clang/test/Sema/typo-correction-no-hang.c b/clang/test/Sema/typo-correction-no-hang.c
index 25ca89ca07b1a..da234a2c7373c 100644
--- a/clang/test/Sema/typo-correction-no-hang.c
+++ b/clang/test/Sema/typo-correction-no-hang.c
@@ -1,17 +1,16 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // PR50797
 struct a {
-  int xxx; // expected-note {{'xxx' declared here}}
+  int xxx;
 };
 
 int g_107;
 int g_108;
 int g_109;
 
-struct a g_999; // expected-note 4{{'g_999' declared here}}
+struct a g_999;
 
-void b(void) { (g_910.xxx = g_910.xxx); } //expected-error 2{{use of undeclared identifier 'g_910'; did you mean 'g_999'}}
+void b(void) { (g_910.xxx = g_910.xxx); } //expected-error 2{{use of undeclared identifier 'g_910'}}
 
-void c(void) { (g_910.xxx = g_910.xxx1); } //expected-error 2{{use of undeclared identifier 'g_910'; did you mean 'g_999'}} \
-                                             expected-error {{no member named 'xxx1' in 'struct a'; did you mean 'xxx'}}
+void c(void) { (g_910.xxx = g_910.xxx1); } //expected-error 2{{use of undeclared identifier 'g_910'}}
diff --git a/clang/test/Sema/typo-correction-no-hang.cpp b/clang/test/Sema/typo-correction-no-hang.cpp
index 04b002f1c39de..34b8486bed902 100644
--- a/clang/test/Sema/typo-correction-no-hang.cpp
+++ b/clang/test/Sema/typo-correction-no-hang.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // From `test/Sema/typo-correction.c` but for C++ since the behavior varies
 // between the two languages.
@@ -8,10 +8,12 @@ struct rdar38642201 {
 
 void rdar38642201_callee(int x, int y);
 void rdar38642201_caller() {
-  struct rdar38642201 structVar;
+  struct rdar38642201 structVar;      //expected-note 2{{'structVar' declared here}}
   rdar38642201_callee(
-      structVar1.fieldName1.member1,  //expected-error{{use of undeclared identifier 'structVar1'}}
-      structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}}
+      structVar1.fieldName1.member1,  //expected-error{{use of undeclared identifier 'structVar1'}} \
+                                        expected-error{{no member named 'fieldName1' in 'rdar38642201'}}
+      structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} \
+                                        expected-error{{no member named 'fieldName2' in 'rdar38642201'}}
 }
 
 // Similar reproducer.
@@ -20,7 +22,7 @@ class A {
   int minut() const = delete;
   int hour() const = delete;
 
-  int longit() const; //expected-note{{'longit' declared here}}
+  int longit() const;
   int latit() const;
 };
 
@@ -35,6 +37,6 @@ int Foo(const B &b) {
 }
 
 int Bar(const B &b) {
-  return b.depar().longitude() + //expected-error{{no member named 'longitude' in 'A'; did you mean 'longit'?}}
+  return b.depar().longitude() + //expected-error{{no member named 'longitude' in 'A'}}
          b.depar().latitude();   //expected-error{{no member named 'latitude' in 'A'}}
 }
diff --git a/clang/test/Sema/typo-correction-recursive.cpp b/clang/test/Sema/typo-correction-recursive.cpp
index b4282f8a84c5e..a7d7127564b75 100644
--- a/clang/test/Sema/typo-correction-recursive.cpp
+++ b/clang/test/Sema/typo-correction-recursive.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Check the following typo correction behavior:
 // - multiple typos in a single member call chain are all diagnosed
@@ -8,13 +8,13 @@
 class DeepClass
 {
 public:
-  void trigger() const;  // expected-note {{'trigger' declared here}}
+  void trigger() const;
 };
 
 class Y
 {
 public:
-  const DeepClass& getX() const { return m_deepInstance; }  // expected-note {{'getX' declared here}}
+  const DeepClass& getX() const { return m_deepInstance; }
 private:
   DeepClass m_deepInstance;
   int m_n;
@@ -23,7 +23,7 @@ class Y
 class Z
 {
 public:
-  const Y& getY0() const { return m_y0; }  // expected-note {{'getY0' declared here}}
+  const Y& getY0() const { return m_y0; }
   const Y& getActiveY() const { return m_y0; }
 
 private:
@@ -35,9 +35,9 @@ Z z_obj;
 
 void testMultipleCorrections()
 {
-  z_obj.getY2().  // expected-error {{no member named 'getY2' in 'Z'; did you mean 'getY0'}}
-      getM().     // expected-error {{no member named 'getM' in 'Y'; did you mean 'getX'}}
-      triggee();  // expected-error {{no member named 'triggee' in 'DeepClass'; did you mean 'trigger'}}
+  z_obj.getY2().  // expected-error {{no member named 'getY2' in 'Z'}}
+      getM().
+      triggee();
 }
 
 void testNoCorrections()
@@ -53,19 +53,19 @@ struct A {
   C get_me_a_C();
 };
 struct B {
-  D get_me_a_D();  // expected-note {{'get_me_a_D' declared here}}
+  D get_me_a_D();
 };
 class Scope {
 public:
   A make_an_A();
-  B make_a_B();  // expected-note {{'make_a_B' declared here}}
+  B make_a_B();
 };
 
 Scope scope_obj;
 
 int testDiscardedCorrections() {
-  return scope_obj.make_an_E().  // expected-error {{no member named 'make_an_E' in 'Scope'; did you mean 'make_a_B'}}
-      get_me_a_Z().value;        // expected-error {{no member named 'get_me_a_Z' in 'B'; did you mean 'get_me_a_D'}}
+  return scope_obj.make_an_E().  // expected-error {{no member named 'make_an_E' in 'Scope'}}
+      get_me_a_Z().value;
 }
 
 class AmbiguousHelper {
@@ -120,13 +120,13 @@ int testDeepAmbiguity() {
 }
 
 struct Dog {
-  int age;  //expected-note{{'age' declared here}}
-  int size; //expected-note{{'size' declared here}}
+  int age;
+  int size;
 };
 
 int from_dog_years(int DogYears, int DogSize);
 int get_dog_years() {
   struct Dog doggo;
-  return from_dog_years(doggo.agee,   //expected-error{{no member named 'agee' in 'Dog'; did you mean 'age'}}
-                        doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'; did you mean 'size'}}
+  return from_dog_years(doggo.agee,   //expected-error{{no member named 'agee' in 'Dog'}}
+                        doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'}}
 }
diff --git a/clang/test/Sema/typo-correction.c b/clang/test/Sema/typo-correction.c
index 5244f3f548406..510a67e725f9c 100644
--- a/clang/test/Sema/typo-correction.c
+++ b/clang/test/Sema/typo-correction.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 //
 // This file contains typo correction tests which hit different code paths in C
 // than in C++ and may exhibit different behavior as a result.
@@ -50,10 +50,12 @@ void fn1(void) {
   cabs(errij);  // expected-error {{use of undeclared identifier 'errij'}}
 }
 
-extern long afunction(int);
+extern long afunction(int); // expected-note {{'afunction' declared here}} \
+                               expected-note {{passing argument to parameter here}}
 void fn2(void) {
   f(THIS_IS_AN_ERROR,       // expected-error {{use of undeclared identifier 'THIS_IS_AN_ERROR'}}
-    afunction(afunction_)); // expected-error {{use of undeclared identifier 'afunction_'}}
+    afunction(afunction_)); // expected-error {{use of undeclared identifier 'afunction_'}} \
+                               expected-error {{incompatible pointer to integer conversion passing 'long (int)' to parameter of type 'int'}}
 }
 
 int d = X ? d : L; // expected-error 2 {{use of undeclared identifier}}
@@ -94,22 +96,24 @@ struct rdar38642201 {
 
 void rdar38642201_callee(int x, int y);
 void rdar38642201_caller(void) {
-  struct rdar38642201 structVar;
+  struct rdar38642201 structVar;     // expected-note 2{{'structVar' declared here}}
   rdar38642201_callee(
-      structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}}
-      structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}}
+      structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} \
+                                       expected-error{{no member named 'fieldName1' in 'struct rdar38642201'}}
+      structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} \
+                                        expected-error{{no member named 'fieldName2' in 'struct rdar38642201'}}
 }
 
 void PR40286_g(int x, int y);
 void PR40286_h(int x, int y, int z);
-void PR40286_1(int the_value) {
-  PR40286_g(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+void PR40286_1(int the_value) { // expected-note {{'the_value' declared here}}
+  PR40286_g(the_walue, 0); // expected-error {{use of undeclared identifier 'the_walue'}}
 }
-void PR40286_2(int the_value) {
-  PR40286_h(the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+void PR40286_2(int the_value) { // expected-note {{'the_value' declared here}}
+  PR40286_h(the_value, the_walue, 0); // expected-error {{use of undeclared identifier 'the_walue'}}
 }
-void PR40286_3(int the_value) {
-  PR40286_h(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+void PR40286_3(int the_value) { // expected-note {{'the_value' declared here}}
+  PR40286_h(the_walue, 0, 0); // expected-error {{use of undeclared identifier 'the_walue'}}
 }
 void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}}
   PR40286_h(the_value, the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'; did you mean 'the_value'?}}
diff --git a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp b/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
deleted file mode 100644
index b9fd221c7ece8..0000000000000
--- a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fdelayed-typo-correction -std=c++11 %s
-// Don't crash (PR13394). The crash was from delayed typo correction, which is
-// why we're enabling that flag for the test.
-
-namespace stretch_v1 {
-  struct closure_t {
-    const stretch_v1::ops_t* d_methods; // expected-error {{no type named 'ops_t' in namespace 'stretch_v1'}}
-  };
-}
-namespace gatekeeper_v1 {
-  namespace gatekeeper_factory_v1 {
-    struct closure_t { // expected-note {{'closure_t' declared here}} expected-note {{'gatekeeper_factory_v1::closure_t' declared here}}
-      gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}}
-    };
-  }
-  // FIXME: Typo correction should remove the 'gatekeeper_v1::' name specifier
-  gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'gatekeeper_factory_v1::closure_t'}}
-}
-
-namespace Foo {
-struct Base {
-  void Bar() {} // expected-note{{'Bar' declared here}}
-};
-}
-
-struct Derived : public Foo::Base {
-  void test() {
-    Foo::Bar(); // expected-error{{no member named 'Bar' in namespace 'Foo'; did you mean simply 'Bar'?}}
-  }
-};
diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp
index 6ba3b32e2e743..73457995603e5 100644
--- a/clang/test/SemaCXX/return.cpp
+++ b/clang/test/SemaCXX/return.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fdelayed-typo-correction -fsyntax-only -Wignored-qualifiers -verify
+// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
 
 int test1() {
   throw;
@@ -73,7 +73,7 @@ const int ret_array()[4]; // expected-error {{cannot return array}}
 
 namespace PR9328 {
   typedef char *PCHAR;
-  class Test
+  class Test 
   {
     const PCHAR GetName() { return 0; } // expected-warning{{'const' type qualifier on return type has no effect}}
   };
@@ -109,7 +109,7 @@ namespace return_has_expr {
 // pr17759
 namespace ctor_returns_void {
   void f() {}
-  struct S {
+  struct S { 
     S() { return f(); } // expected-error {{constructor 'S' must not return void expression}}
     ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
   };
@@ -130,5 +130,5 @@ void cxx_unresolved_expr() {
   // CXXUnresolvedConstructExpr, and the missing ')' gives it an invalid source
   // location for its rparen.  Check that emitting a diag on the range of the
   // expr doesn't assert.
-  return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{use of undeclared identifier 'undeclared'}}
+  return int(undeclared, 4; // expected-error {{use of undeclared identifier 'undeclared'}}
 }
diff --git a/clang/test/SemaCXX/typo-correction-crash.cpp b/clang/test/SemaCXX/typo-correction-crash.cpp
index 100d0f227a6c7..434b70e3c5097 100644
--- a/clang/test/SemaCXX/typo-correction-crash.cpp
+++ b/clang/test/SemaCXX/typo-correction-crash.cpp
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++17 -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
 auto check1() {
   return 1;
   return s; // expected-error {{use of undeclared identifier 's'}}
 }
 
-int test = 11; // expected-note 2 {{'test' declared here}}
+int test = 11; // expected-note 3 {{'test' declared here}}
 auto check2() {
   return "s";
-  return tes; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}}
+  return tes; // expected-error {{use of undeclared identifier 'tes'}}
               // expected-error at -1 {{deduced as 'int' here but deduced as 'const char *' in earlier}}
 }
 
@@ -16,9 +16,8 @@ template <class A> struct is_same<A,A> { static constexpr bool value = true; };
 
 auto L1 = [] { return s; }; // expected-error {{use of undeclared identifier 's'}}
 using T1 = decltype(L1());
-// FIXME: Suppress the 'undeclared identifier T1' diagnostic, the UsingDecl T1 is discarded because of an invalid L1().
-static_assert(is_same<T1, void>::value, "Return statement should be discarded"); // expected-error {{use of undeclared identifier 'T1'}}
-auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}}
+static_assert(is_same<T1, void>::value, "Return statement should be discarded");
+auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 'tes'}}
 using T2 = decltype(L2());
 static_assert(is_same<T2, int>::value, "Return statement was corrected");
 
@@ -32,13 +31,13 @@ FooRecord::NestedNamespace::type x; // expected-error {{no member named 'NestedN
 
 void cast_expr(int g) { +int(n)(g); } // expected-error {{undeclared identifier 'n'}}
 
-void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}}
+void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}} \
+                                                            expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
 
 namespace NoCrash {
 class S {
   void Function(int a) {
-    unknown1(unknown2, Function, unknown3); // expected-error 2{{use of undeclared identifier}} \
-                                               expected-error {{reference to non-static member function must be called}}
+    unknown1(unknown2, Function, unknown3); // expected-error 2{{use of undeclared identifier}}
   }
 };
 }
@@ -46,8 +45,6 @@ class S {
 namespace NoCrashOnCheckArgAlignment {
 template <typename a> void b(a &);
 void test() {
-  for (auto file_data :b(files_db_data)); // expected-error {{use of undeclared identifier 'files_db_data'; did you mean 'file_data'?}} \
-                                          // expected-note {{'file_data' declared here}} \
-                                          // expected-error {{cannot use type 'void' as a range}}
+  for (auto file_data :b(files_db_data)); // expected-error {{use of undeclared identifier 'files_db_data'}}
 }
 }
diff --git a/clang/test/SemaCXX/typo-correction-cxx11.cpp b/clang/test/SemaCXX/typo-correction-cxx11.cpp
index 594a5ec3d9038..9eb5f9c299629 100644
--- a/clang/test/SemaCXX/typo-correction-cxx11.cpp
+++ b/clang/test/SemaCXX/typo-correction-cxx11.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -std=c++11 -fdelayed-typo-correction -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
 namespace PR23186 {
-decltype(ned);  // expected-error-re {{use of undeclared identifier 'ned'{{$}}}}
+decltype(ned);  // expected-error {{use of undeclared identifier 'ned'}}
 // The code below was triggering an UNREACHABLE in ASTContext::getTypeInfoImpl
 // once the above code failed to recover properly after making the bogus
 // correction of 'ned' to 'new'.
@@ -19,8 +19,9 @@ struct S {
 namespace PR23140 {
 auto lneed = gned.*[] {};  // expected-error-re {{use of undeclared identifier 'gned'{{$}}}}
 
-void test(int aaa, int bbb, int thisvar) {  // expected-note {{'thisvar' declared here}}
-  int thatval = aaa * (bbb + thatvar);  // expected-error {{use of undeclared identifier 'thatvar'; did you mean 'thisvar'?}}
+void test(int aaa, int bbb, int thisvar) {
+  int thatval = aaa * (bbb + thatvar);  // expected-error {{use of undeclared identifier 'thatvar'; did you mean 'thatval'}} \
+                                           expected-note {{'thatval' declared here}}
 }
 }
 
@@ -54,7 +55,7 @@ void run(A *annotations) {
 
   auto &annotation = *annotations;
   auto new_it = new_annotations.find(5);
-  auto &new_anotation = new_it.second;  // expected-note {{'new_anotation' declared here}}
-  new_annotation->Swap(&annotation);  // expected-error {{use of undeclared identifier 'new_annotation'; did you mean 'new_anotation'?}}
+  auto &new_anotation = new_it.second;
+  new_annotation->Swap(&annotation);  // expected-error {{use of undeclared identifier 'new_annotation'}}
 }
 }
diff --git a/clang/test/SemaCXX/typo-correction-delayed.cpp b/clang/test/SemaCXX/typo-correction-delayed.cpp
deleted file mode 100644
index b6512cd3eec3c..0000000000000
--- a/clang/test/SemaCXX/typo-correction-delayed.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -Wno-c++11-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -std=c++98 -Wno-c++11-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify -std=c++11 %s
-
-struct A {};
-struct B {};
-struct D {
-  A fizbin;  // expected-note 2 {{declared here}}
-  A foobar;  // expected-note 2 {{declared here}}
-  B roxbin;  // expected-note 2 {{declared here}}
-  B toobad;  // expected-note 2 {{declared here}}
-  void BooHoo();
-  void FoxBox();
-};
-
-void something(A, B);
-void test() {
-  D obj;
-  something(obj.fixbin,   // expected-error {{did you mean 'fizbin'?}}
-            obj.toobat);  // expected-error {{did you mean 'toobad'?}}
-  something(obj.toobat,   // expected-error {{did you mean 'foobar'?}}
-            obj.fixbin);  // expected-error {{did you mean 'roxbin'?}}
-  something(obj.fixbin,   // expected-error {{did you mean 'fizbin'?}}
-            obj.fixbin);  // expected-error {{did you mean 'roxbin'?}}
-  something(obj.toobat,   // expected-error {{did you mean 'foobar'?}}
-            obj.toobat);  // expected-error {{did you mean 'toobad'?}}
-  // Both members could be corrected to methods, but that isn't valid.
-  something(obj.boohoo,   // expected-error-re {{no member named 'boohoo' in 'D'{{$}}}}
-            obj.foxbox);  // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}}
-  // The first argument has a usable correction but the second doesn't.
-  something(obj.boobar,   // expected-error-re {{no member named 'boobar' in 'D'{{$}}}}
-            obj.foxbox);  // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}}
-}
-
-// Ensure the delayed typo correction does the right thing when trying to
-// recover using a seemingly-valid correction for which a valid expression to
-// replace the TypoExpr cannot be created (but which does have a second
-// correction candidate that would be a valid and usable correction).
-class Foo {
-public:
-  template <> void testIt();  // expected-error {{no function template matches}}
-  void textIt();  // expected-note {{'textIt' declared here}}
-};
-void testMemberExpr(Foo *f) {
-  f->TestIt();  // expected-error {{no member named 'TestIt' in 'Foo'; did you mean 'textIt'?}}
-}
-
-void callee(double, double);
-void testNoCandidates() {
-  callee(xxxxxx,   // expected-error-re {{use of undeclared identifier 'xxxxxx'{{$}}}}
-         zzzzzz);  // expected-error-re {{use of undeclared identifier 'zzzzzz'{{$}}}}
-}
-
-class string {};
-struct Item {
-  void Nest();
-  string text();
-  Item* next();  // expected-note {{'next' declared here}}
-};
-void testExprFilter(Item *i) {
-  Item *j;
-  j = i->Next();  // expected-error {{no member named 'Next' in 'Item'; did you mean 'next'?}}
-}
-
-// Test that initializer expressions are handled correctly and that the type
-// being initialized is taken into account when choosing a correction.
-namespace initializerCorrections {
-struct Node {
-  string text() const;
-  // Node* Next() is not implemented yet
-};
-void f(Node *node) {
-  // text is only an edit distance of 1 from Next, but would trigger type
-  // conversion errors if used in this initialization expression.
-  Node *next = node->Next();  // expected-error-re {{no member named 'Next' in 'initializerCorrections::Node'{{$}}}}
-}
-
-struct LinkedNode {
-  LinkedNode* next();  // expected-note {{'next' declared here}}
-  string text() const;
-};
-void f(LinkedNode *node) {
-  // text and next are equidistant from Next, but only one results in a valid
-  // initialization expression.
-  LinkedNode *next = node->Next();  // expected-error {{no member named 'Next' in 'initializerCorrections::LinkedNode'; did you mean 'next'?}}
-}
-
-struct NestedNode {
-  NestedNode* Nest();
-  NestedNode* next();
-  string text() const;
-};
-void f(NestedNode *node) {
-  // There are two equidistant, usable corrections for Next: next and Nest
-  NestedNode *next = node->Next();  // expected-error-re {{no member named 'Next' in 'initializerCorrections::NestedNode'{{$}}}}
-}
-}
-
-namespace PR21669 {
-void f(int *i) {
-  // Check that arguments to a builtin with custom type checking are corrected
-  // properly, since calls to such builtins bypass much of the normal code path
-  // for building and checking the call.
-  __atomic_load(i, i, something_something);  // expected-error-re {{use of undeclared identifier 'something_something'{{$}}}}
-}
-}
-
-const int DefaultArg = 9;  // expected-note {{'DefaultArg' declared here}}
-template <int I = defaultArg> struct S {};  // expected-error {{use of undeclared identifier 'defaultArg'; did you mean 'DefaultArg'?}}
-S<1> s;
-
-namespace foo {}
-void test_paren_suffix() {
-  foo::bar({5, 6});  // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}}
-#if __cplusplus <= 199711L
-  // expected-error at -2 {{expected expression}}
-#endif
-}
-
-const int kNum = 10;  // expected-note {{'kNum' declared here}}
-class SomeClass {
-  int Kind;
-public:
-  explicit SomeClass() : Kind(kSum) {}  // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}}
-};
-
-// There used to be an issue with typo resolution inside overloads.
-struct AssertionResult { ~AssertionResult(); };
-AssertionResult Overload(const char *a);
-AssertionResult Overload(int a);
-void UseOverload() {
-  // expected-note at +1 {{'result' declared here}}
-  const char *result;
-  // expected-error at +1 {{use of undeclared identifier 'resulta'; did you mean 'result'?}}
-  Overload(resulta);
-}
-
-namespace PR21925 {
-struct X {
-  int get() { return 7; }  // expected-note {{'get' declared here}}
-};
-void test() {
-  X variable;  // expected-note {{'variable' declared here}}
-
-  // expected-error at +2 {{use of undeclared identifier 'variableX'; did you mean 'variable'?}}
-  // expected-error at +1 {{no member named 'getX' in 'PR21925::X'; did you mean 'get'?}}
-  int x = variableX.getX();
-}
-}
-
-namespace PR21905 {
-int (*a)() = (void)Z; // expected-error-re {{use of undeclared identifier 'Z'{{$}}}} \
-                      // expected-error {{cannot initialize a variable of type 'int (*)()' with an rvalue of type 'void'}}
-}
-
-namespace PR21947 {
-int blue;  // expected-note {{'blue' declared here}}
-__typeof blur y;  // expected-error {{use of undeclared identifier 'blur'; did you mean 'blue'?}}
-}
-
-namespace PR22092 {
-a = b ? : 0;  // expected-error {{a type specifier is required for all declarations}} \
-              // expected-error-re {{use of undeclared identifier 'b'{{$}}}}
-}
-
-extern long clock (void);
-struct Pointer {
-  void set_xpos(int);
-  void set_ypos(int);
-};
-void MovePointer(Pointer &Click, int x, int y) {  // expected-note 2 {{'Click' declared here}}
-  click.set_xpos(x);  // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}}
-  click.set_ypos(x);  // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}}
-}
-
-namespace PR22250 {
-// expected-error at +4 {{use of undeclared identifier 'size_t'; did you mean 'sizeof'?}}
-// expected-error-re at +3 {{use of undeclared identifier 'y'{{$}}}}
-// expected-error-re at +2 {{use of undeclared identifier 'z'{{$}}}}
-// expected-error at +1 {{expected ';' after top level declarator}}
-int getenv_s(size_t *y, char(&z)) {}
-}
-
-namespace PR22291 {
-template <unsigned I> void f() {
-  unsigned *prio_bits_array;  // expected-note {{'prio_bits_array' declared here}}
-  // expected-error at +1 {{use of undeclared identifier 'prio_op_array'; did you mean 'prio_bits_array'?}}
-  __atomic_store_n(prio_op_array + I, false, __ATOMIC_RELAXED);
-}
-}
-
-namespace PR22297 {
-double pow(double x, double y);
-struct TimeTicks {
-  static void Now();  // expected-note {{'Now' declared here}}
-};
-void f() {
-  TimeTicks::now();  // expected-error {{no member named 'now' in 'PR22297::TimeTicks'; did you mean 'Now'?}}
-}
-}
-
-namespace PR23005 {
-void f() { int a = Unknown::b(c); }  // expected-error {{use of undeclared identifier 'Unknown'}}
-// expected-error at -1 {{use of undeclared identifier 'c'}}
-}
-
-namespace PR23350 {
-int z = 1 ? N : ;  // expected-error {{expected expression}}
-// expected-error-re at -1 {{use of undeclared identifier 'N'{{$}}}}
-}
-
-// PR 23285. This test must be at the end of the file to avoid additional,
-// unwanted diagnostics.
-// expected-error-re at +2 {{use of undeclared identifier 'uintmax_t'{{$}}}}
-// expected-error at +1 {{expected ';' after top level declarator}}
-unsigned int a = 0(uintmax_t
diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp
index 5b00124576393..e4dadf83e0a08 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -1,9 +1,8 @@
-// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -fdelayed-typo-correction %s
-// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -fdelayed-typo-correction -std=c++20 %s
+// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions %s
+// RUN: %clang_cc1 -fspell-checking-limit=0 -verify -Wno-c++11-extensions -fcxx-exceptions -std=c++20 %s
 
 namespace PR21817{
 int a(-rsing[2]); // expected-error {{undeclared identifier 'rsing'; did you mean 'using'?}}
-                  // expected-error at -1 {{expected expression}}
 }
 
 struct errc {
@@ -43,14 +42,14 @@ inline error_condition make_error_condition(errc _e) {
 // refer to a base class or non-static data member.
 struct BaseType { };
 struct Derived : public BaseType { // expected-note {{base class 'BaseType' specified here}}
-  static int base_type; // expected-note {{'base_type' declared here}}
+  static int base_type;
   Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}}
 };
 
 // Test the improvement from passing a callback object to CorrectTypo in
 // the helper function LookupMemberExprInRecord.
 int get_type(struct Derived *st) {
-  return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}}
+  return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'}}
 }
 
 // In this example, somename should not be corrected to the cached correction
@@ -212,12 +211,11 @@ namespace PR13051 {
   };
 
   void foo(); // expected-note{{'foo' declared here}}
-  void g(void(*)()); // expected-note{{candidate function not viable}}
-  void g(bool(S<int>::*)() const); // expected-note{{candidate function not viable}}
+  void g(void(*)());
+  void g(bool(S<int>::*)() const);
 
   void test() {
-    g(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}} \
-                                 // expected-error{{no matching function for call to 'g'}}
+    g(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}}
     g(&S<int>::opeartor bool); // expected-error{{did you mean 'operator'?}}
     g(&S<int>::foo); // expected-error{{no member named 'foo' in 'PR13051::S<int>'; did you mean simply 'foo'?}}
   }
@@ -251,13 +249,13 @@ namespace b6956809_test1 {
 
   struct S1 {
     void method(A*);  // no note here
-    void method(B*);  // expected-note{{'method' declared here}}
+    void method(B*);
   };
 
   void test1() {
     B b;
     S1 s;
-    s.methodd(&b);  // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'; did you mean 'method'}}
+    s.methodd(&b);  // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'}}
   }
 
   struct S2 {
@@ -275,15 +273,15 @@ namespace b6956809_test1 {
 }
 
 namespace b6956809_test2 {
-  template<typename T> struct Err { typename T::error n; };  // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}}
+  template<typename T> struct Err { typename T::error n; };
   struct S {
-    template<typename T> typename Err<T>::type method(T);  // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}
-    template<typename T> int method(T *);  // expected-note{{'method' declared here}}
+    template<typename T> typename Err<T>::type method(T);
+    template<typename T> int method(T *);
   };
 
   void test() {
     S s;
-    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
+    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'}}
   }
 }
 
@@ -309,12 +307,12 @@ struct A {
   void CreateBar(float, float);
 };
 struct B : A {
-  using A::CreateFoo; // expected-note {{'CreateFoo' declared here}}
-  void CreateFoo(int, int);  // expected-note {{'CreateFoo' declared here}}
+  using A::CreateFoo;
+  void CreateFoo(int, int);
 };
 void f(B &x) {
-  x.Createfoo(0,0);  // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
-  x.Createfoo(0.f,0.f);  // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
+  x.Createfoo(0,0);  // expected-error {{no member named 'Createfoo' in 'PR13387::B'}}
+  x.Createfoo(0.f,0.f);  // expected-error {{no member named 'Createfoo' in 'PR13387::B'}}
 }
 }
 
@@ -649,12 +647,12 @@ class AddObservation { // expected-note {{declared here}}
 
 namespace testNonStaticMemberHandling {
 struct Foo {
-  bool usesMetadata;  // expected-note {{'usesMetadata' declared here}}
+  bool usesMetadata;
 };
 int test(Foo f) {
   if (UsesMetadata)  // expected-error-re {{use of undeclared identifier 'UsesMetadata'{{$}}}}
     return 5;
-  if (f.UsesMetadata)  // expected-error {{no member named 'UsesMetadata' in 'testNonStaticMemberHandling::Foo'; did you mean 'usesMetadata'?}}
+  if (f.UsesMetadata)  // expected-error {{no member named 'UsesMetadata' in 'testNonStaticMemberHandling::Foo'}}
     return 11;
   return 0;
 }
@@ -707,7 +705,7 @@ using C::D::Foofoo;  // expected-error {{no member named 'Foofoo' in namespace '
 int d = ? L : d; // expected-error {{expected expression}} expected-error {{undeclared identifier}}
 
 struct B0 {
-  int : 0 |         // expected-error {{invalid operands to binary expression}}
+  int : 0 |
       (struct B0)e; // expected-error {{use of undeclared identifier}}
 };
 
diff --git a/clang/test/SemaObjC/typo-correction-subscript.m b/clang/test/SemaObjC/typo-correction-subscript.m
index 70f60c855a90a..6c09127dbb8d6 100644
--- a/clang/test/SemaObjC/typo-correction-subscript.m
+++ b/clang/test/SemaObjC/typo-correction-subscript.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class %s -verify
+// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -Wno-objc-root-class %s -verify
 
 @class Dictionary;
 
@@ -7,8 +7,7 @@ @interface Test
 @implementation Test
 - (void)rdar47403222:(Dictionary *)opts {
   [self undeclaredMethod:undeclaredArg];
-  // expected-error at -1{{no visible @interface for 'Test' declares the selector 'undeclaredMethod:'}}
-  // expected-error at -2{{use of undeclared identifier 'undeclaredArg}}
+  // expected-error at -1{{use of undeclared identifier 'undeclaredArg}}
   opts[(__bridge id)undeclaredKey] = 0;
   // expected-error at -1{{use of undeclared identifier 'undeclaredKey'}}
 }

>From ab5412f8a5a6d356ef686d58376908a5289fc0d6 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 3 Jun 2025 17:33:15 -0400
Subject: [PATCH 04/11] [WIP] Remove more stuff

---
 clang/include/clang/Sema/Sema.h   |  15 +-
 clang/lib/Sema/SemaExpr.cpp       |  29 +--
 clang/lib/Sema/SemaExprCXX.cpp    | 334 ------------------------------
 clang/lib/Sema/SemaExprMember.cpp |  14 +-
 4 files changed, 9 insertions(+), 383 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7d78f0b1bec83..e12ad667822b6 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6696,10 +6696,6 @@ class Sema final : public SemaBase {
     /// this expression evaluation context.
     unsigned NumCleanupObjects;
 
-    /// The number of typos encountered during this expression evaluation
-    /// context (i.e. the number of TypoExprs created).
-    unsigned NumTypos;
-
     MaybeODRUseExprSet SavedMaybeODRUseExprs;
 
     /// The lambdas that are present within this context, if it
@@ -6796,7 +6792,7 @@ class Sema final : public SemaBase {
                                       Decl *ManglingContextDecl,
                                       ExpressionKind ExprContext)
         : Context(Context), ParentCleanup(ParentCleanup),
-          NumCleanupObjects(NumCleanupObjects), NumTypos(0),
+          NumCleanupObjects(NumCleanupObjects),
           ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext),
           InDiscardedStatement(false), InImmediateFunctionContext(false),
           InImmediateEscalatingFunctionContext(false) {}
@@ -7129,8 +7125,7 @@ class Sema final : public SemaBase {
                       CorrectionCandidateCallback &CCC,
                       TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
                       ArrayRef<Expr *> Args = {},
-                      DeclContext *LookupCtx = nullptr,
-                      TypoExpr **Out = nullptr);
+                      DeclContext *LookupCtx = nullptr);
 
   /// If \p D cannot be odr-used in the current expression evaluation context,
   /// return a reason explaining why. Otherwise, return NOUR_None.
@@ -9230,12 +9225,6 @@ class Sema final : public SemaBase {
   /// for C++ records.
   llvm::FoldingSet<SpecialMemberOverloadResultEntry> SpecialMemberCache;
 
-  /// Holds TypoExprs that are created from `createDelayedTypo`. This is used by
-  /// `TransformTypos` in order to keep track of any TypoExprs that are created
-  /// recursively during typo correction and wipe them away if the correction
-  /// fails.
-  llvm::SmallVector<TypoExpr *, 2> TypoExprs;
-
   enum class AcceptableKind { Visible, Reachable };
 
   // Members have to be NamespaceDecl* or TranslationUnitDecl*.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index b490cb2ce9224..ac28e5875f282 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2555,8 +2555,7 @@ bool Sema::DiagnoseDependentMemberLookup(const LookupResult &R) {
 bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
                                CorrectionCandidateCallback &CCC,
                                TemplateArgumentListInfo *ExplicitTemplateArgs,
-                               ArrayRef<Expr *> Args, DeclContext *LookupCtx,
-                               TypoExpr **Out) {
+                               ArrayRef<Expr *> Args, DeclContext *LookupCtx) {
   DeclarationName Name = R.getLookupName();
   SourceRange NameRange = R.getLookupNameInfo().getSourceRange();
 
@@ -2879,7 +2878,6 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
 
     // If this name wasn't predeclared and if this is not a function
     // call, diagnose the problem.
-    TypoExpr *TE = nullptr;
     DefaultFilterCCC DefaultValidator(II, SS.isValid() ? SS.getScopeRep()
                                                        : nullptr);
     DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
@@ -2895,29 +2893,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
     // a template name, but we happen to have always already looked up the name
     // before we get here if it must be a template name.
     if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr,
-                            {}, nullptr, &TE)) {
-      if (TE && KeywordReplacement) {
-        auto &State = getTypoExprState(TE);
-        auto BestTC = State.Consumer->getNextCorrection();
-        if (BestTC.isKeyword()) {
-          auto *II = BestTC.getCorrectionAsIdentifierInfo();
-          if (State.DiagHandler)
-            State.DiagHandler(BestTC);
-          KeywordReplacement->startToken();
-          KeywordReplacement->setKind(II->getTokenID());
-          KeywordReplacement->setIdentifierInfo(II);
-          KeywordReplacement->setLocation(BestTC.getCorrectionRange().getBegin());
-          // Clean up the state associated with the TypoExpr, since it has
-          // now been diagnosed (without a call to CorrectDelayedTyposInExpr).
-          clearDelayedTypo(TE);
-          // Signal that a correction to a keyword was performed by returning a
-          // valid-but-null ExprResult.
-          return (Expr*)nullptr;
-        }
-        State.Consumer->resetCorrectionStream();
-      }
-      return TE ? TE : ExprError();
-    }
+                            {}, nullptr))
+      return ExprError();
 
     assert(!R.empty() &&
            "DiagnoseEmptyLookup returned false but added no results");
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c901ab2ca3cfa..9b9baa377bc2f 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7683,340 +7683,6 @@ static ExprResult attemptRecovery(Sema &SemaRef,
                                           /*AcceptInvalidDecl*/ true);
 }
 
-namespace {
-class FindTypoExprs : public DynamicRecursiveASTVisitor {
-  llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
-
-public:
-  explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs)
-      : TypoExprs(TypoExprs) {}
-  bool VisitTypoExpr(TypoExpr *TE) override {
-    TypoExprs.insert(TE);
-    return true;
-  }
-};
-
-class TransformTypos : public TreeTransform<TransformTypos> {
-  typedef TreeTransform<TransformTypos> BaseTransform;
-
-  VarDecl *InitDecl; // A decl to avoid as a correction because it is in the
-                     // process of being initialized.
-  llvm::function_ref<ExprResult(Expr *)> ExprFilter;
-  llvm::SmallSetVector<TypoExpr *, 2> TypoExprs, AmbiguousTypoExprs;
-  llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache;
-  llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution;
-
-  /// Emit diagnostics for all of the TypoExprs encountered.
-  ///
-  /// If the TypoExprs were successfully corrected, then the diagnostics should
-  /// suggest the corrections. Otherwise the diagnostics will not suggest
-  /// anything (having been passed an empty TypoCorrection).
-  ///
-  /// If we've failed to correct due to ambiguous corrections, we need to
-  /// be sure to pass empty corrections and replacements. Otherwise it's
-  /// possible that the Consumer has a TypoCorrection that failed to ambiguity
-  /// and we don't want to report those diagnostics.
-  void EmitAllDiagnostics(bool IsAmbiguous) {
-    for (TypoExpr *TE : TypoExprs) {
-      auto &State = SemaRef.getTypoExprState(TE);
-      if (State.DiagHandler) {
-        TypoCorrection TC = IsAmbiguous
-            ? TypoCorrection() : State.Consumer->getCurrentCorrection();
-        ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE];
-
-        // Extract the NamedDecl from the transformed TypoExpr and add it to the
-        // TypoCorrection, replacing the existing decls. This ensures the right
-        // NamedDecl is used in diagnostics e.g. in the case where overload
-        // resolution was used to select one from several possible decls that
-        // had been stored in the TypoCorrection.
-        if (auto *ND = getDeclFromExpr(
-                Replacement.isInvalid() ? nullptr : Replacement.get()))
-          TC.setCorrectionDecl(ND);
-
-        State.DiagHandler(TC);
-      }
-      SemaRef.clearDelayedTypo(TE);
-    }
-  }
-
-  /// Try to advance the typo correction state of the first unfinished TypoExpr.
-  /// We allow advancement of the correction stream by removing it from the
-  /// TransformCache which allows `TransformTypoExpr` to advance during the
-  /// next transformation attempt.
-  ///
-  /// Any substitution attempts for the previous TypoExprs (which must have been
-  /// finished) will need to be retried since it's possible that they will now
-  /// be invalid given the latest advancement.
-  ///
-  /// We need to be sure that we're making progress - it's possible that the
-  /// tree is so malformed that the transform never makes it to the
-  /// `TransformTypoExpr`.
-  ///
-  /// Returns true if there are any untried correction combinations.
-  bool CheckAndAdvanceTypoExprCorrectionStreams() {
-    for (auto *TE : TypoExprs) {
-      auto &State = SemaRef.getTypoExprState(TE);
-      TransformCache.erase(TE);
-      if (!State.Consumer->hasMadeAnyCorrectionProgress())
-        return false;
-      if (!State.Consumer->finished())
-        return true;
-      State.Consumer->resetCorrectionStream();
-    }
-    return false;
-  }
-
-  NamedDecl *getDeclFromExpr(Expr *E) {
-    if (auto *OE = dyn_cast_or_null<OverloadExpr>(E))
-      E = OverloadResolution[OE];
-
-    if (!E)
-      return nullptr;
-    if (auto *DRE = dyn_cast<DeclRefExpr>(E))
-      return DRE->getFoundDecl();
-    if (auto *ME = dyn_cast<MemberExpr>(E))
-      return ME->getFoundDecl();
-    // FIXME: Add any other expr types that could be seen by the delayed typo
-    // correction TreeTransform for which the corresponding TypoCorrection could
-    // contain multiple decls.
-    return nullptr;
-  }
-
-  ExprResult TryTransform(Expr *E) {
-    Sema::SFINAETrap Trap(SemaRef);
-    ExprResult Res = TransformExpr(E);
-    if (Trap.hasErrorOccurred() || Res.isInvalid())
-      return ExprError();
-
-    return ExprFilter(Res.get());
-  }
-
-  // Since correcting typos may intoduce new TypoExprs, this function
-  // checks for new TypoExprs and recurses if it finds any. Note that it will
-  // only succeed if it is able to correct all typos in the given expression.
-  ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) {
-    if (Res.isInvalid()) {
-      return Res;
-    }
-    // Check to see if any new TypoExprs were created. If so, we need to recurse
-    // to check their validity.
-    Expr *FixedExpr = Res.get();
-
-    auto SavedTypoExprs = std::move(TypoExprs);
-    auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs);
-    TypoExprs.clear();
-    AmbiguousTypoExprs.clear();
-
-    FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr);
-    if (!TypoExprs.empty()) {
-      // Recurse to handle newly created TypoExprs. If we're not able to
-      // handle them, discard these TypoExprs.
-      ExprResult RecurResult =
-          RecursiveTransformLoop(FixedExpr, IsAmbiguous);
-      if (RecurResult.isInvalid()) {
-        Res = ExprError();
-        // Recursive corrections didn't work, wipe them away and don't add
-        // them to the TypoExprs set. Remove them from Sema's TypoExpr list
-        // since we don't want to clear them twice. Note: it's possible the
-        // TypoExprs were created recursively and thus won't be in our
-        // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`.
-        auto &SemaTypoExprs = SemaRef.TypoExprs;
-        for (auto *TE : TypoExprs) {
-          TransformCache.erase(TE);
-          SemaRef.clearDelayedTypo(TE);
-
-          auto SI = find(SemaTypoExprs, TE);
-          if (SI != SemaTypoExprs.end()) {
-            SemaTypoExprs.erase(SI);
-          }
-        }
-      } else {
-        // TypoExpr is valid: add newly created TypoExprs since we were
-        // able to correct them.
-        Res = RecurResult;
-        SavedTypoExprs.set_union(TypoExprs);
-      }
-    }
-
-    TypoExprs = std::move(SavedTypoExprs);
-    AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs);
-
-    return Res;
-  }
-
-  // Try to transform the given expression, looping through the correction
-  // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`.
-  //
-  // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to
-  // true and this method immediately will return an `ExprError`.
-  ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) {
-    ExprResult Res;
-    auto SavedTypoExprs = std::move(SemaRef.TypoExprs);
-    SemaRef.TypoExprs.clear();
-
-    while (true) {
-      Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
-
-      // Recursion encountered an ambiguous correction. This means that our
-      // correction itself is ambiguous, so stop now.
-      if (IsAmbiguous)
-        break;
-
-      // If the transform is still valid after checking for any new typos,
-      // it's good to go.
-      if (!Res.isInvalid())
-        break;
-
-      // The transform was invalid, see if we have any TypoExprs with untried
-      // correction candidates.
-      if (!CheckAndAdvanceTypoExprCorrectionStreams())
-        break;
-    }
-
-    // If we found a valid result, double check to make sure it's not ambiguous.
-    if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) {
-      auto SavedTransformCache =
-          llvm::SmallDenseMap<TypoExpr *, ExprResult, 2>(TransformCache);
-
-      // Ensure none of the TypoExprs have multiple typo correction candidates
-      // with the same edit length that pass all the checks and filters.
-      while (!AmbiguousTypoExprs.empty()) {
-        auto TE  = AmbiguousTypoExprs.back();
-
-        // TryTransform itself can create new Typos, adding them to the TypoExpr map
-        // and invalidating our TypoExprState, so always fetch it instead of storing.
-        SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition();
-
-        TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection();
-        TypoCorrection Next;
-        do {
-          // Fetch the next correction by erasing the typo from the cache and calling
-          // `TryTransform` which will iterate through corrections in
-          // `TransformTypoExpr`.
-          TransformCache.erase(TE);
-          ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
-
-          if (!AmbigRes.isInvalid() || IsAmbiguous) {
-            SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream();
-            SavedTransformCache.erase(TE);
-            Res = ExprError();
-            IsAmbiguous = true;
-            break;
-          }
-        } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) &&
-                 Next.getEditDistance(false) == TC.getEditDistance(false));
-
-        if (IsAmbiguous)
-          break;
-
-        AmbiguousTypoExprs.remove(TE);
-        SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition();
-        TransformCache[TE] = SavedTransformCache[TE];
-      }
-      TransformCache = std::move(SavedTransformCache);
-    }
-
-    // Wipe away any newly created TypoExprs that we don't know about. Since we
-    // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only
-    // possible if a `TypoExpr` is created during a transformation but then
-    // fails before we can discover it.
-    auto &SemaTypoExprs = SemaRef.TypoExprs;
-    for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) {
-      auto TE = *Iterator;
-      auto FI = find(TypoExprs, TE);
-      if (FI != TypoExprs.end()) {
-        Iterator++;
-        continue;
-      }
-      SemaRef.clearDelayedTypo(TE);
-      Iterator = SemaTypoExprs.erase(Iterator);
-    }
-    SemaRef.TypoExprs = std::move(SavedTypoExprs);
-
-    return Res;
-  }
-
-public:
-  TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref<ExprResult(Expr *)> Filter)
-      : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {}
-
-  ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
-                                   MultiExprArg Args,
-                                   SourceLocation RParenLoc,
-                                   Expr *ExecConfig = nullptr) {
-    auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args,
-                                                 RParenLoc, ExecConfig);
-    if (auto *OE = dyn_cast<OverloadExpr>(Callee)) {
-      if (Result.isUsable()) {
-        Expr *ResultCall = Result.get();
-        if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall))
-          ResultCall = BE->getSubExpr();
-        if (auto *CE = dyn_cast<CallExpr>(ResultCall))
-          OverloadResolution[OE] = CE->getCallee();
-      }
-    }
-    return Result;
-  }
-
-  ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); }
-
-  ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
-
-  ExprResult Transform(Expr *E) {
-    bool IsAmbiguous = false;
-    ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous);
-
-    if (!Res.isUsable())
-      FindTypoExprs(TypoExprs).TraverseStmt(E);
-
-    EmitAllDiagnostics(IsAmbiguous);
-
-    return Res;
-  }
-
-  ExprResult TransformTypoExpr(TypoExpr *E) {
-    // If the TypoExpr hasn't been seen before, record it. Otherwise, return the
-    // cached transformation result if there is one and the TypoExpr isn't the
-    // first one that was encountered.
-    auto &CacheEntry = TransformCache[E];
-    if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) {
-      return CacheEntry;
-    }
-
-    auto &State = SemaRef.getTypoExprState(E);
-    assert(State.Consumer && "Cannot transform a cleared TypoExpr");
-
-    // For the first TypoExpr and an uncached TypoExpr, find the next likely
-    // typo correction and return it.
-    while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
-      if (InitDecl && TC.getFoundDecl() == InitDecl)
-        continue;
-      // FIXME: If we would typo-correct to an invalid declaration, it's
-      // probably best to just suppress all errors from this typo correction.
-      ExprResult NE = State.RecoveryHandler ?
-          State.RecoveryHandler(SemaRef, E, TC) :
-          attemptRecovery(SemaRef, *State.Consumer, TC);
-      if (!NE.isInvalid()) {
-        // Check whether there may be a second viable correction with the same
-        // edit distance; if so, remember this TypoExpr may have an ambiguous
-        // correction so it can be more thoroughly vetted later.
-        TypoCorrection Next;
-        if ((Next = State.Consumer->peekNextCorrection()) &&
-            Next.getEditDistance(false) == TC.getEditDistance(false)) {
-          AmbiguousTypoExprs.insert(E);
-        } else {
-          AmbiguousTypoExprs.remove(E);
-        }
-        assert(!NE.isUnset() &&
-               "Typo was transformed into a valid-but-null ExprResult");
-        return CacheEntry = NE;
-      }
-    }
-    return CacheEntry = ExprError();
-  }
-};
-}
-
 ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
                                      bool DiscardedValue, bool IsConstexpr,
                                      bool IsTemplateArgument) {
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 100aeb7ebcdd3..5dca509d46fdb 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -654,8 +654,7 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
                                      Expr *BaseExpr, QualType RTy,
                                      SourceLocation OpLoc, bool IsArrow,
                                      CXXScopeSpec &SS, bool HasTemplateArgs,
-                                     SourceLocation TemplateKWLoc,
-                                     TypoExpr *&TE) {
+                                     SourceLocation TemplateKWLoc) {
   SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
   if (!RTy->isDependentType() &&
       !SemaRef.isThisOutsideMemberFunctionBody(RTy) &&
@@ -691,15 +690,11 @@ ExprResult Sema::BuildMemberReferenceExpr(
 
   // Implicit member accesses.
   if (!Base) {
-    TypoExpr *TE = nullptr;
     QualType RecordTy = BaseType;
     if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType();
     if (LookupMemberExprInRecord(*this, R, nullptr, RecordTy, OpLoc, IsArrow,
-                                 SS, TemplateArgs != nullptr, TemplateKWLoc,
-                                 TE))
+                                 SS, TemplateArgs != nullptr, TemplateKWLoc))
       return ExprError();
-    if (TE)
-      return TE;
 
   // Explicit member accesses.
   } else {
@@ -1294,16 +1289,15 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
 
   // Handle field access to simple records.
   if (BaseType->getAsRecordDecl()) {
-    TypoExpr *TE = nullptr;
     if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow,
-                                 SS, HasTemplateArgs, TemplateKWLoc, TE))
+                                 SS, HasTemplateArgs, TemplateKWLoc))
       return ExprError();
 
     // Returning valid-but-null is how we indicate to the caller that
     // the lookup result was filled in. If typo correction was attempted and
     // failed, the lookup result will have been cleared--that combined with the
     // valid-but-null ExprResult will trigger the appropriate diagnostics.
-    return ExprResult(TE);
+    return ExprResult{};
   } else if (BaseType->isDependentType()) {
     R.setNotFoundInCurrentInstantiation();
     return ExprEmpty();

>From 193452b6dae3f434a59c2ca139d7d23115b2010c Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 3 Jun 2025 18:01:27 -0400
Subject: [PATCH 05/11] [WIP] Remove TypoExpr

---
 clang/include/clang/AST/Expr.h                | 33 +------------------
 clang/include/clang/AST/RecursiveASTVisitor.h |  1 -
 clang/include/clang/Basic/StmtNodes.td        |  1 -
 clang/include/clang/Sema/Sema.h               | 21 ------------
 clang/include/clang/Sema/SemaInternal.h       | 14 --------
 clang/lib/AST/Expr.cpp                        |  1 -
 clang/lib/AST/ExprClassification.cpp          |  1 -
 clang/lib/AST/ExprConstant.cpp                |  1 -
 clang/lib/AST/ItaniumMangle.cpp               |  1 -
 clang/lib/AST/StmtPrinter.cpp                 |  5 ---
 clang/lib/AST/StmtProfile.cpp                 |  4 ---
 clang/lib/Sema/SemaExceptionSpec.cpp          |  1 -
 clang/lib/Sema/SemaLookup.cpp                 | 11 -------
 clang/lib/Sema/TreeTransform.h                |  6 ----
 clang/lib/Serialization/ASTReaderStmt.cpp     |  4 ---
 clang/lib/Serialization/ASTWriterStmt.cpp     |  6 ----
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  |  1 -
 clang/tools/libclang/CXCursor.cpp             |  1 -
 18 files changed, 1 insertion(+), 112 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 87bb9df9cef8f..7f69087509856 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -240,8 +240,7 @@ class Expr : public ValueStmt {
     return static_cast<bool>(getDependence() & ExprDependence::UnexpandedPack);
   }
 
-  /// Whether this expression contains subexpressions which had errors, e.g. a
-  /// TypoExpr.
+  /// Whether this expression contains subexpressions which had errors.
   bool containsErrors() const {
     return static_cast<bool>(getDependence() & ExprDependence::Error);
   }
@@ -6961,36 +6960,6 @@ class AtomicExpr : public Expr {
   }
 };
 
-/// TypoExpr - Internal placeholder for expressions where typo correction
-/// still needs to be performed and/or an error diagnostic emitted.
-class TypoExpr : public Expr {
-  // The location for the typo name.
-  SourceLocation TypoLoc;
-
-public:
-  TypoExpr(QualType T, SourceLocation TypoLoc)
-      : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) {
-    assert(T->isDependentType() && "TypoExpr given a non-dependent type");
-    setDependence(ExprDependence::TypeValueInstantiation |
-                  ExprDependence::Error);
-  }
-
-  child_range children() {
-    return child_range(child_iterator(), child_iterator());
-  }
-  const_child_range children() const {
-    return const_child_range(const_child_iterator(), const_child_iterator());
-  }
-
-  SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; }
-  SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == TypoExprClass;
-  }
-
-};
-
 /// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray',
 /// with a boolean differentiator.
 /// OpenMP 5.0 [2.1.5, Array Sections].
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index a11157c006f92..31d1e2e9d76c2 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2956,7 +2956,6 @@ DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
   }
 })
 DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
-DEF_TRAVERSE_STMT(TypoExpr, {})
 DEF_TRAVERSE_STMT(RecoveryExpr, {})
 DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
 
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 9526fa5808aa5..c9c173f5c7469 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -202,7 +202,6 @@ def ShuffleVectorExpr : StmtNode<Expr>;
 def ConvertVectorExpr : StmtNode<Expr>;
 def BlockExpr : StmtNode<Expr>;
 def OpaqueValueExpr : StmtNode<Expr>;
-def TypoExpr : StmtNode<Expr>;
 def RecoveryExpr : StmtNode<Expr>;
 def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
 def EmbedExpr : StmtNode<Expr>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e12ad667822b6..7607a939981aa 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9312,10 +9312,6 @@ class Sema final : public SemaBase {
                       bool VolatileArg, bool RValueThis, bool ConstThis,
                       bool VolatileThis);
 
-  typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
-  typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
-      TypoRecoveryCallback;
-
   RedeclarationKind forRedeclarationInCurContext() const;
 
   /// Look up a name, looking for a single declaration.  Return
@@ -9687,20 +9683,6 @@ class Sema final : public SemaBase {
                              SourceLocation DeclLoc, ArrayRef<Module *> Modules,
                              MissingImportKind MIK, bool Recover);
 
-  struct TypoExprState {
-    std::unique_ptr<TypoCorrectionConsumer> Consumer;
-    TypoDiagnosticGenerator DiagHandler;
-    TypoRecoveryCallback RecoveryHandler;
-    TypoExprState();
-    TypoExprState(TypoExprState &&other) noexcept;
-    TypoExprState &operator=(TypoExprState &&other) noexcept;
-  };
-
-  const TypoExprState &getTypoExprState(TypoExpr *TE) const;
-
-  /// Clears the state of the given TypoExpr.
-  void clearDelayedTypo(TypoExpr *TE);
-
   /// Called on #pragma clang __debug dump II
   void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II);
 
@@ -9732,9 +9714,6 @@ class Sema final : public SemaBase {
       DeclContext *MemberContext, bool EnteringContext,
       const ObjCObjectPointerType *OPT, bool ErrorRecovery);
 
-  /// The set of unhandled TypoExprs and their associated state.
-  llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos;
-
   /// Cache for module units which is usable for current module.
   llvm::DenseSet<const Module *> UsableModuleUnitsCache;
 
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 95874077050a9..4d0da1102bb59 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -314,20 +314,6 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
   bool SearchNamespaces;
 };
 
-inline Sema::TypoExprState::TypoExprState() {}
-
-inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) noexcept {
-  *this = std::move(other);
-}
-
-inline Sema::TypoExprState &Sema::TypoExprState::
-operator=(Sema::TypoExprState &&other) noexcept {
-  Consumer = std::move(other.Consumer);
-  DiagHandler = std::move(other.DiagHandler);
-  RecoveryHandler = std::move(other.RecoveryHandler);
-  return *this;
-}
-
 } // end namespace clang
 
 #endif
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 3993db84978a8..7899902881ca1 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3611,7 +3611,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
   case PackExpansionExprClass:
   case SubstNonTypeTemplateParmPackExprClass:
   case FunctionParmPackExprClass:
-  case TypoExprClass:
   case RecoveryExprClass:
   case CXXFoldExprClass:
     // Make a conservative assumption for dependent nodes.
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index 3f37d06cc8f3a..ad66335138a42 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -129,7 +129,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
     // FIXME: Is this wise? Should they get their own kind?
   case Expr::UnresolvedLookupExprClass:
   case Expr::UnresolvedMemberExprClass:
-  case Expr::TypoExprClass:
   case Expr::DependentCoawaitExprClass:
   case Expr::CXXDependentScopeMemberExprClass:
   case Expr::DependentScopeDeclRefExprClass:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b20e2690d0eee..55d45112204c6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17313,7 +17313,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::CXXDeleteExprClass:
   case Expr::CXXPseudoDestructorExprClass:
   case Expr::UnresolvedLookupExprClass:
-  case Expr::TypoExprClass:
   case Expr::RecoveryExprClass:
   case Expr::DependentScopeDeclRefExprClass:
   case Expr::CXXConstructExprClass:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index f7c620dc09df7..72a2d20fe35ff 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4994,7 +4994,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
   case Expr::ParenListExprClass:
   case Expr::MSPropertyRefExprClass:
   case Expr::MSPropertySubscriptExprClass:
-  case Expr::TypoExprClass: // This should no longer exist in the AST by now.
   case Expr::RecoveryExprClass:
   case Expr::ArraySectionExprClass:
   case Expr::OMPArrayShapingExprClass:
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 13c3bc0387890..28317911d825b 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2914,11 +2914,6 @@ void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
   PrintExpr(Node->getSourceExpr());
 }
 
-void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
-  // TODO: Print something reasonable for a TypoExpr, if necessary.
-  llvm_unreachable("Cannot print TypoExpr nodes");
-}
-
 void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
   OS << "<recovery-expr>(";
   const char *Sep = "";
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index f7d1655f67ed1..c666d966a6e58 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2361,10 +2361,6 @@ void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
   VisitExpr(E);
 }
 
-void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
-  VisitExpr(E);
-}
-
 void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
   VisitExpr(E);
 }
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index c83eab53891ca..b12b3f8e1126b 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1365,7 +1365,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
   case Expr::UnaryExprOrTypeTraitExprClass:
   case Expr::UnresolvedLookupExprClass:
   case Expr::UnresolvedMemberExprClass:
-  case Expr::TypoExprClass:
     // FIXME: Many of the above can throw.
     return CT_Cannot;
 
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 867034c932326..0478f38249553 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -5755,17 +5755,6 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,
     Diag(Correction.getCorrectionRange().getBegin(), PD);
 }
 
-const Sema::TypoExprState &Sema::getTypoExprState(TypoExpr *TE) const {
-  auto Entry = DelayedTypos.find(TE);
-  assert(Entry != DelayedTypos.end() &&
-         "Failed to get the state for a TypoExpr!");
-  return Entry->second;
-}
-
-void Sema::clearDelayedTypo(TypoExpr *TE) {
-  DelayedTypos.erase(TE);
-}
-
 void Sema::ActOnPragmaDump(Scope *S, SourceLocation IILoc, IdentifierInfo *II) {
   DeclarationNameInfo Name(II, IILoc);
   LookupResult R(*this, Name, LookupAnyName,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index bd839087c66ed..db10891f2f0e9 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -13121,12 +13121,6 @@ TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
   return E;
 }
 
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
-  return E;
-}
-
 template <typename Derived>
 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
   llvm::SmallVector<Expr *, 8> Children;
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index f327a7b355868..94da24a4c65a9 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2315,10 +2315,6 @@ void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   E->setIsUnique(Record.readInt());
 }
 
-void ASTStmtReader::VisitTypoExpr(TypoExpr *E) {
-  llvm_unreachable("Cannot read TypoExpr nodes");
-}
-
 void ASTStmtReader::VisitRecoveryExpr(RecoveryExpr *E) {
   VisitExpr(E);
   unsigned NumArgs = Record.readInt();
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 0401be33e8930..e1d7df546f3ac 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2315,12 +2315,6 @@ void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   Code = serialization::EXPR_OPAQUE_VALUE;
 }
 
-void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
-  VisitExpr(E);
-  // TODO: Figure out sane writer behavior for a TypoExpr, if necessary
-  llvm_unreachable("Cannot write TypoExpr nodes");
-}
-
 //===----------------------------------------------------------------------===//
 // CUDA Expressions and Statements.
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index b28deee41d1c5..c77ef26da568d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1732,7 +1732,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
     case Stmt::ExpressionTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:
     case Stmt::UnresolvedMemberExprClass:
-    case Stmt::TypoExprClass:
     case Stmt::RecoveryExprClass:
     case Stmt::CXXNoexceptExprClass:
     case Stmt::PackExpansionExprClass:
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 635d03a88d105..a6301daa672c3 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -598,7 +598,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
   case Stmt::SubstNonTypeTemplateParmPackExprClass:
   case Stmt::FunctionParmPackExprClass:
   case Stmt::UnresolvedLookupExprClass:
-  case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef
     K = CXCursor_DeclRefExpr;
     break;
 

>From b304523f1788a666c40537388598bc9bdd745e8e Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Wed, 4 Jun 2025 06:47:25 -0400
Subject: [PATCH 06/11] Remove the introduced feature flag

---
 clang/include/clang/Basic/LangOptions.def          |  6 ------
 clang/include/clang/Driver/Options.td              |  3 ---
 clang/test/FixIt/fixit-unicode.c                   |  4 ++--
 clang/test/FixIt/fixit.c                           |  4 ++--
 clang/test/FixIt/typo-location-bugs.cpp            |  4 ++--
 clang/test/Misc/serialized-diags.m                 |  2 +-
 .../Modules/crash-typo-correction-visibility.cpp   |  4 ++--
 clang/test/Modules/diagnose-missing-import.m       |  2 +-
 clang/test/Modules/suggest-include.cpp             |  2 +-
 clang/test/Parser/switch-recovery.cpp              |  2 +-
 clang/test/Parser/switch-typo-correction.cpp       |  2 +-
 clang/test/Sema/typo-correction-ambiguity.c        |  2 +-
 clang/test/SemaCXX/cxx11-crashes.cpp               |  2 +-
 ...issing-namespace-qualifier-typo-corrections.cpp |  2 +-
 clang/test/SemaCXX/typo-correction-blocks.c        |  2 +-
 clang/test/SemaObjCXX/typo-correction.mm           |  2 +-
 clang/test/SemaTemplate/concepts-recovery-expr.cpp |  2 +-
 .../test/SemaTemplate/dependent-typos-recovery.cpp |  2 +-
 clang/unittests/Sema/ExternalSemaSourceTest.cpp    | 14 --------------
 19 files changed, 20 insertions(+), 43 deletions(-)

diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 77e7c485e0a80..789761c1f3647 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -534,12 +534,6 @@ LANGOPT(BoundsSafety, 1, 0, "Bounds safety extension for C")
 
 LANGOPT(PreserveVec3Type, 1, 0, "Preserve 3-component vector type")
 
-COMPATIBLE_LANGOPT(DelayedTypoCorrection, 1, 0, "True if we want to allow "
-                   "delayed typo correction. This can improve typo correction "
-                   "behavior in C++, particularly around template "
-                   "instantiations, but comes at the expense of potentially "
-                   "crashing Clang.")
-
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 63f428f6d0b2e..b66cc15e87b9f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2025,9 +2025,6 @@ def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">,
   Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   HelpText<"Put crash-report files in <dir>">, MetaVarName<"<dir>">;
-def fdelayed_typo_correction : Flag<["-"], "fdelayed-typo-correction">, Group<f_clang_Group>,
-  HelpText<"Enable delayed typo correction">, Visibility<[CC1Option]>,
-  MarshallingInfoFlag<LangOpts<"DelayedTypoCorrection">>;
 def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
 defm cxx_exceptions: BoolFOption<"cxx-exceptions",
   LangOpts<"CXXExceptions">, DefaultFalse,
diff --git a/clang/test/FixIt/fixit-unicode.c b/clang/test/FixIt/fixit-unicode.c
index ef75e5408c573..87819cdfbea17 100644
--- a/clang/test/FixIt/fixit-unicode.c
+++ b/clang/test/FixIt/fixit-unicode.c
@@ -2,8 +2,8 @@
 // There's a set of additional checks for systems with proper support of UTF-8
 // on the standard output in fixit-unicode-with-utf8-output.c.
 
-// RUN: not %clang_cc1 -fsyntax-only -fdelayed-typo-correction -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck -strict-whitespace %s
-// RUN: not %clang_cc1 -fsyntax-only -fdelayed-typo-correction -fno-diagnostics-show-line-numbers -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -check-prefix=CHECK-MACHINE %s
+// RUN: not %clang_cc1 -fsyntax-only -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -fsyntax-only -fno-diagnostics-show-line-numbers -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -check-prefix=CHECK-MACHINE %s
 
 struct Foo {
   int bar;
diff --git a/clang/test/FixIt/fixit.c b/clang/test/FixIt/fixit.c
index 34c1129c7c0d4..0e86d454a0e10 100644
--- a/clang/test/FixIt/fixit.c
+++ b/clang/test/FixIt/fixit.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -fdelayed-typo-correction -verify -x c %s
+// RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -verify -x c %s
 // RUN: cp %s %t
-// RUN: not %clang_cc1 -pedantic -Wunused-label -fdelayed-typo-correction -fixit -x c %t
+// RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
 // RUN: %clang_cc1 -pedantic -Wunused-label -Wno-deprecated-non-prototype -Werror -x c %t
 // RUN: grep -v CHECK %t | FileCheck %t
 
diff --git a/clang/test/FixIt/typo-location-bugs.cpp b/clang/test/FixIt/typo-location-bugs.cpp
index c4f978fae2c41..fb60fd6d02093 100644
--- a/clang/test/FixIt/typo-location-bugs.cpp
+++ b/clang/test/FixIt/typo-location-bugs.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: cp %s %t
-// RUN: not %clang_cc1 -fdelayed-typo-correction -fixit -x c++ %t
+// RUN: not %clang_cc1 -fixit -x c++ %t
 // RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
 
 namespace dcl_fct_default_p10 {
diff --git a/clang/test/Misc/serialized-diags.m b/clang/test/Misc/serialized-diags.m
index 1d66958ea8e0e..71c983b883853 100644
--- a/clang/test/Misc/serialized-diags.m
+++ b/clang/test/Misc/serialized-diags.m
@@ -11,7 +11,7 @@ - (void) test2 {}
 @end
 
 // RUN: rm -f %t
-// RUN: not %clang -Wall -Xclang -fdelayed-typo-correction -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1
+// RUN: not %clang -Wall -fsyntax-only %s --serialize-diagnostics %t.diag > /dev/null 2>&1
 // RUN: c-index-test -read-diagnostics %t.diag > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
diff --git a/clang/test/Modules/crash-typo-correction-visibility.cpp b/clang/test/Modules/crash-typo-correction-visibility.cpp
index d52bd4443c242..9f0ed3b7b1320 100644
--- a/clang/test/Modules/crash-typo-correction-visibility.cpp
+++ b/clang/test/Modules/crash-typo-correction-visibility.cpp
@@ -1,6 +1,6 @@
 // RUN: mkdir -p %t
-// RUN: %clang_cc1 -x c++ -std=c++11 -fdelayed-typo-correction -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
-// RUN: %clang_cc1 -x c++ -std=c++11 -fdelayed-typo-correction -fmodules -fmodule-file=%t/module.pcm %s -verify
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/module.pcm %s -verify
 
 struct S {
   int member; // expected-note {{declared here}}
diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m
index c770de13520df..b34bc1a62b6bc 100644
--- a/clang/test/Modules/diagnose-missing-import.m
+++ b/clang/test/Modules/diagnose-missing-import.m
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/diagnose-missing-import \
-// RUN:   -Werror=implicit-function-declaration -fsyntax-only -fdelayed-typo-correction \
+// RUN:   -Werror=implicit-function-declaration -fsyntax-only \
 // RUN:   -fimplicit-module-maps -verify %s
 @import NCI;
 
diff --git a/clang/test/Modules/suggest-include.cpp b/clang/test/Modules/suggest-include.cpp
index ac59ca00ec566..1e53ef05d5f83 100644
--- a/clang/test/Modules/suggest-include.cpp
+++ b/clang/test/Modules/suggest-include.cpp
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -fdelayed-typo-correction -I%S/Inputs/suggest-include %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs/suggest-include %s -verify
 
 #include "empty.h" // import the module file
 
diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp
index 2216761afb2ca..084b9d982a2c0 100644
--- a/clang/test/Parser/switch-recovery.cpp
+++ b/clang/test/Parser/switch-recovery.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 struct A {};
 struct B {
diff --git a/clang/test/Parser/switch-typo-correction.cpp b/clang/test/Parser/switch-typo-correction.cpp
index 0744ce5f3598c..95d610b9cdd25 100644
--- a/clang/test/Parser/switch-typo-correction.cpp
+++ b/clang/test/Parser/switch-typo-correction.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 namespace c { double xxx; }
 namespace d { float xxx; }
diff --git a/clang/test/Sema/typo-correction-ambiguity.c b/clang/test/Sema/typo-correction-ambiguity.c
index 1086fed76e222..0fc18137710d4 100644
--- a/clang/test/Sema/typo-correction-ambiguity.c
+++ b/clang/test/Sema/typo-correction-ambiguity.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Check the following typo correction behavior in C:
 // - no typos are diagnosed when a call expression has ambiguous (multiple) corrections
diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp
index 669c6706e3c13..11bc42315421d 100644
--- a/clang/test/SemaCXX/cxx11-crashes.cpp
+++ b/clang/test/SemaCXX/cxx11-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fdelayed-typo-correction -verify %s -Wno-deprecated-builtins
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins
 
 namespace rdar12240916 {
 
diff --git a/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp b/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
index 0b346a4b8094e..9d05d64ab4062 100644
--- a/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
+++ b/clang/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fdelayed-typo-correction -Wno-c++11-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
 
 namespace fizbin { class Foobar {}; } // expected-note 2 {{'fizbin::Foobar' declared here}} \
                                       // expected-note {{'Foobar' declared here}}
diff --git a/clang/test/SemaCXX/typo-correction-blocks.c b/clang/test/SemaCXX/typo-correction-blocks.c
index 43ec498870f93..300a5be3969da 100644
--- a/clang/test/SemaCXX/typo-correction-blocks.c
+++ b/clang/test/SemaCXX/typo-correction-blocks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-macosx -fblocks -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -triple i386-apple-macosx -fblocks -fsyntax-only -verify %s
 
 extern int h(int *);
 extern void g(int, void (^)(void));
diff --git a/clang/test/SemaObjCXX/typo-correction.mm b/clang/test/SemaObjCXX/typo-correction.mm
index 3fc11bf91666d..38624e9cd350f 100644
--- a/clang/test/SemaObjCXX/typo-correction.mm
+++ b/clang/test/SemaObjCXX/typo-correction.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -fdelayed-typo-correction -Wno-objc-root-class
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-objc-root-class
 
 class ClassA {};
 
diff --git a/clang/test/SemaTemplate/concepts-recovery-expr.cpp b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
index 485598492757c..b338f3bc271bf 100644
--- a/clang/test/SemaTemplate/concepts-recovery-expr.cpp
+++ b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++20 -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -std=c++20 -verify %s
 
 // expected-error at +1{{use of undeclared identifier 'b'}}
 constexpr bool CausesRecoveryExpr = b;
diff --git a/clang/test/SemaTemplate/dependent-typos-recovery.cpp b/clang/test/SemaTemplate/dependent-typos-recovery.cpp
index c95921e8a4515..3f89ca1dbec95 100644
--- a/clang/test/SemaTemplate/dependent-typos-recovery.cpp
+++ b/clang/test/SemaTemplate/dependent-typos-recovery.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fdelayed-typo-correction -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // There should be no extra errors about missing 'template' keywords.
 struct B {
diff --git a/clang/unittests/Sema/ExternalSemaSourceTest.cpp b/clang/unittests/Sema/ExternalSemaSourceTest.cpp
index 4eb8f5193e04f..cc9dd4175af55 100644
--- a/clang/unittests/Sema/ExternalSemaSourceTest.cpp
+++ b/clang/unittests/Sema/ExternalSemaSourceTest.cpp
@@ -268,20 +268,6 @@ TEST(ExternalSemaSource, ExternalTypoCorrectionOrdering) {
   ASSERT_EQ(1, Watcher.SeenCount);
 }
 
-TEST(ExternalSemaSource, ExternalDelayedTypoCorrection) {
-  auto Installer = std::make_unique<ExternalSemaSourceInstaller>();
-  auto Provider = makeIntrusiveRefCnt<FunctionTypoProvider>("aaa", "bbb");
-  DiagnosticWatcher Watcher("aaa", "bbb");
-  Installer->PushSource(Provider.get());
-  Installer->PushWatcher(&Watcher);
-  std::vector<std::string> Args{"-std=c++11", "-fdelayed-typo-correction"};
-  ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
-      std::move(Installer), "namespace AAA { } void foo() { AAA::aaa(); }",
-      Args));
-  ASSERT_LE(0, Provider->CallCount);
-  ASSERT_EQ(1, Watcher.SeenCount);
-}
-
 // We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise
 // solve the problem.
 TEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) {

>From 0d191f1439aea208162b8e6f26b675a1b0bc12f4 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Mon, 9 Jun 2025 13:22:55 -0400
Subject: [PATCH 07/11] Remove typo related AST dump tests

It's possible these tests could be repaired but AST dump tests are
incredibly fragile to begin with. I think removing these tests is not
actively harmful.
---
 clang/test/AST/ast-dump-recovery.c   |  30 ----
 clang/test/AST/ast-dump-recovery.cpp | 213 ---------------------------
 clang/test/AST/ast-dump-recovery.m   |  32 ----
 3 files changed, 275 deletions(-)
 delete mode 100644 clang/test/AST/ast-dump-recovery.m

diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c
index dec5554c7d020..09a03fb9d6fdf 100644
--- a/clang/test/AST/ast-dump-recovery.c
+++ b/clang/test/AST/ast-dump-recovery.c
@@ -23,13 +23,6 @@ int postfix_inc = a++;
 // CHECK-NEXT:      `-IntegerLiteral {{.*}} 'int'
 int unary_address = &(a + 1);
 
-// CHECK:       VarDecl {{.*}} ternary 'int'
-// CHECK-NEXT:  `-ConditionalOperator {{.*}}
-// CHECK-NEXT:    |-DeclRefExpr {{.*}} 'a'
-// CHECK-NEXT:    |-RecoveryExpr {{.*}}
-// CHECK-NEXT:    `-DeclRefExpr {{.*}} 'a'
-int ternary = a ? undef : a;
-
 void test1() {
   // CHECK:     `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
@@ -91,12 +84,6 @@ void test3() {
   // CHECK-NEXT: |   `-DeclRefExpr {{.*}} '__builtin_classify_type'
   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
   (*__builtin_classify_type)(1);
-
-  extern void ext();
-  // CHECK:     CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ext'
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
-  ext(undef_var);
 }
 
 // Verify no crash.
@@ -110,23 +97,6 @@ void test4() {
   };
 }
 
-// Verify no crash
-void test5_GH62711() {
-  // CHECK:      VAArgExpr {{.*}} 'int' contains-errors
-  // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  if (__builtin_va_arg(undef, int) << 1);
-}
-
-void test6_GH50244() {
-  double array[16];
-  // CHECK:      UnaryExprOrTypeTraitExpr {{.*}} 'unsigned long' contains-errors sizeof
-  // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   |-DeclRefExpr {{.*}} 'int ()'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>'
-  sizeof array / sizeof foo(undef);
-}
-
 // No crash on DeclRefExpr that refers to ValueDecl with invalid initializers.
 void test7() {
   int b[] = {""()};
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index b0d00fd349548..a8e30f1759e9f 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -9,28 +9,6 @@ int some_func(int *);
 // CHECK-NEXT:    `-IntegerLiteral {{.*}} 123
 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
 int invalid_call = some_func(123);
-void test_invalid_call_1(int s) {
-  // CHECK:      CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:13>
-  // CHECK-NEXT: `-BinaryOperator {{.*}}
-  // CHECK-NEXT:   |-RecoveryExpr {{.*}}
-  // CHECK-NEXT:   `-IntegerLiteral {{.*}} <col:28> 'int' 1
-  some_func(undef1, undef2+1);
-
-  // CHECK:      BinaryOperator {{.*}} '<dependent type>' contains-errors '='
-  // CHECK-NEXT: |-DeclRefExpr {{.*}} 's'
-  // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
-  s = some_func(undef1);
-
-  // CHECK:     VarDecl {{.*}} var 'int'
-  // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
-  int var = some_func(undef1);
-}
 
 int some_func2(int a, int b);
 void test_invalid_call_2() {
@@ -63,22 +41,6 @@ int ambig_func(float);
 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
 int ambig_call = ambig_func(123);
 
-// CHECK:     VarDecl {{.*}} unresolved_call1
-// CHECK-NEXT:`-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-// CHECK-NEXT:  `-UnresolvedLookupExpr {{.*}} 'bar'
-// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
-int unresolved_call1 = bar();
-
-// CHECK:     VarDecl {{.*}} unresolved_call2
-// CHECK-NEXT:`-CallExpr {{.*}} contains-errors
-// CHECK-NEXT:  |-UnresolvedLookupExpr {{.*}} 'bar'
-// CHECK-NEXT:  |-RecoveryExpr {{.*}} contains-errors
-// CHECK-NEXT:  | `-UnresolvedLookupExpr {{.*}} 'baz'
-// CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
-// CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'qux'
-// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
-int unresolved_call2 = bar(baz(), qux());
-
 constexpr int a = 10;
 
 // CHECK:     VarDecl {{.*}} postfix_inc
@@ -177,11 +139,6 @@ void test2(Foo2 f) {
   f.overload(1);
 }
 
-// CHECK:     |-AlignedAttr {{.*}} alignas
-// CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors
-// CHECK-NEXT:|   `-UnresolvedLookupExpr {{.*}} 'invalid'
-struct alignas(invalid()) Aligned {};
-
 auto f();
 int f(double);
 // CHECK:      VarDecl {{.*}} unknown_type_call 'int'
@@ -203,16 +160,6 @@ void InvalidInitalizer(int x) {
   // CHECK-NEXT:  `-InitListExpr
   // CHECK-NEDT:   `-DeclRefExpr {{.*}} 'x'
   Bar a3{x};
-  // CHECK:     `-VarDecl {{.*}} a4 'Bar'
-  // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors
-  // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
-  // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
-  Bar a4(invalid());
-  // CHECK:     `-VarDecl {{.*}} a5 'Bar'
-  // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors
-  // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
-  // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
-  Bar a5{invalid()};
 
   // CHECK:     `-VarDecl {{.*}} b1 'Bar'
   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
@@ -231,51 +178,11 @@ void InvalidInitalizer(int x) {
   // CHECK-NEXT:    `-InitListExpr {{.*}} 'void'
   // CHECK-NEXT:      `-DeclRefExpr {{.*}} 'x' 'int'
   Bar b4 = Bar{x};
-  // CHECK:     `-VarDecl {{.*}} b5 'Bar'
-  // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
-  // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
-  Bar b5 = Bar(invalid());
-  // CHECK:     `-VarDecl {{.*}} b6 'Bar'
-  // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
-  // CHECK-NEXT:  `-InitListExpr {{.*}} contains-errors
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
-  // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
-  Bar b6 = Bar{invalid()};
 
   // CHECK:     RecoveryExpr {{.*}} 'Bar' contains-errors
   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
   Bar(1);
-
-  // CHECK:     `-VarDecl {{.*}} var1
-  // CHECK-NEXT: `-BinaryOperator {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 1
-  int var1 = undef + 1;
 }
-void InitializerForAuto() {
-  // CHECK:     `-VarDecl {{.*}} invalid a 'auto'
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
-  auto a = invalid();
-
-  // CHECK:     `-VarDecl {{.*}} invalid b 'auto'
-  // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
-  auto b = some_func(invalid());
-
-  decltype(ned);
-  // very bad initailizer: there is an unresolved typo expr internally, we just
-  // drop it.
-  // CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto'
-  auto unresolved_typo = gned.*[] {};
-}
-
-// Verified that the generated call operator is invalid.
-// CHECK: |-CXXMethodDecl {{.*}} invalid operator() 'auto () const -> auto'
-using Escape = decltype([] { return undef(); }());
 
 // CHECK:      VarDecl {{.*}} NoCrashOnInvalidInitList
 // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
@@ -301,56 +208,8 @@ void ValueCategory() {
   xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
 }
 
-void InvalidCondition() {
-  // CHECK:      IfStmt {{.*}}
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors
-  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7>
-  if (invalid()) {}
-
-  // CHECK:      WhileStmt {{.*}}
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors
-  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
-  while (invalid()) {}
-
-  // CHECK:      SwitchStmt {{.*}}
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
-  switch(invalid()) {
-    case 1:
-      break;
-  }
-  // FIXME: figure out why the type of ConditionalOperator is not int.
-  // CHECK:      ConditionalOperator {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
-  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
-  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
-  invalid() ? 1 : 2;
-}
-
 void CtorInitializer() {
   struct S{int m};
-  class MemberInit {
-    int x, y, z;
-    S s;
-    MemberInit() : x(invalid), y(invalid, invalid), z(invalid()), s(1,2) {}
-    // CHECK:      CXXConstructorDecl {{.*}} MemberInit 'void ()'
-    // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'x' 'int'
-    // CHECK-NEXT: | `-ParenListExpr
-    // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
-    // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'y' 'int'
-    // CHECK-NEXT: | `-ParenListExpr
-    // CHECK-NEXT: |   |-RecoveryExpr {{.*}} '<dependent type>'
-    // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
-    // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'z' 'int'
-    // CHECK-NEXT: | `-ParenListExpr
-    // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
-    // CHECK-NEXT: |     `-UnresolvedLookupExpr {{.*}} '<overloaded function type>'
-    // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 's' 'S'
-    // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' contains-errors
-    // CHECK-NEXT: |   |-IntegerLiteral {{.*}} 1
-    // CHECK-NEXT: |   `-IntegerLiteral {{.*}} 2
-  };
   class BaseInit : S {
     BaseInit(float) : S("no match") {}
     // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (float)'
@@ -358,13 +217,6 @@ void CtorInitializer() {
     // CHECK-NEXT: |-CXXCtorInitializer 'S'
     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S'
     // CHECK-NEXT: |   `-StringLiteral
-
-    BaseInit(double) : S(invalid) {}
-    // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (double)'
-    // CHECK-NEXT: |-ParmVarDecl
-    // CHECK-NEXT: |-CXXCtorInitializer 'S'
-    // CHECK-NEXT: | `-ParenListExpr
-    // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
   };
   class DelegatingInit {
     DelegatingInit(float) : DelegatingInit("no match") {}
@@ -373,13 +225,6 @@ void CtorInitializer() {
     // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'DelegatingInit'
     // CHECK-NEXT: |   `-StringLiteral
-
-    DelegatingInit(double) : DelegatingInit(invalid) {}
-    // CHECK:      CXXConstructorDecl {{.*}} DelegatingInit 'void (double)'
-    // CHECK-NEXT: |-ParmVarDecl
-    // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
-    // CHECK-NEXT: | `-ParenListExpr
-    // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
   };
 }
 
@@ -423,64 +268,6 @@ void returnInitListFromVoid() {
   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
 }
 
-void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
-  InvalidDecl + 1;
-  // CHECK:      BinaryOperator {{.*}}
-  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
-  // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'InvalidDecl' 'int'
-  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
-  InvalidDecl();
-  // CHECK:      CallExpr {{.*}}
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
-}
-
-void InitializerOfInvalidDecl() {
-  int ValidDecl;
-  Unkown InvalidDecl = ValidDecl;
-  // CHECK:      VarDecl {{.*}} invalid InvalidDecl
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
-
-  Unknown InvalidDeclWithInvalidInit = Invalid;
-  // CHECK:      VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-}
-
-void RecoverToAnInvalidDecl() {
-  Unknown* foo; // invalid decl
-  goo; // the typo was correct to the invalid foo.
-  // Verify that RecoveryExpr has an inner DeclRefExpr.
-  // CHECK:      RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
-  // CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo' 'int *'
-}
-
-void RecoveryToDoWhileStmtCond() {
-  // CHECK:       FunctionDecl {{.*}} RecoveryToDoWhileStmtCond
-  // CHECK:       `-DoStmt {{.*}}
-  // CHECK-NEXT:    |-CompoundStmt {{.*}}
-  // CHECK-NEXT:    `-BinaryOperator {{.*}} '<dependent type>' contains-errors '<'
-  // CHECK-NEXT:      |-BinaryOperator {{.*}} '<dependent type>' contains-errors '+'
-  // CHECK-NEXT:      | |-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
-  // CHECK-NEXT:      | `-IntegerLiteral {{.*}} 'int' 1
-  // CHECK-NEXT:      `-IntegerLiteral {{.*}} 'int' 10
-  do {} while (some_invalid_val + 1 < 10);
-}
-
-void RecoveryForStmtCond() {
-  // CHECK:FunctionDecl {{.*}} RecoveryForStmtCond
-  // CHECK-NEXT:`-CompoundStmt {{.*}}
-  // CHECK-NEXT:  `-ForStmt {{.*}}
-  // CHECK-NEXT:    |-DeclStmt {{.*}}
-  // CHECK-NEXT:    | `-VarDecl {{.*}}
-  // CHECK-NEXT:    |   `-IntegerLiteral {{.*}} <col:16> 'int' 0
-  // CHECK-NEXT:    |-<<<NULL>>>
-  // CHECK-NEXT:    |-RecoveryExpr {{.*}} 'bool' contains-errors
-  // CHECK-NEXT:    |-UnaryOperator {{.*}} 'int' lvalue prefix '++'
-  // CHECK-NEXT:    | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'i' 'int'
-  // CHECK-NEXT:    `-CompoundStmt {{.*}}
-  for (int i = 0; i < invalid; ++i) {}
-}
-
 // Fix crash issue https://github.com/llvm/llvm-project/issues/112560.
 // Make sure clang compiles the following code without crashing:
 
diff --git a/clang/test/AST/ast-dump-recovery.m b/clang/test/AST/ast-dump-recovery.m
deleted file mode 100644
index d47d2a438d5b1..0000000000000
--- a/clang/test/AST/ast-dump-recovery.m
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
-
- at interface Foo
-- (void)method:(int)n;
- at end
-
-void k(Foo *foo) {
-  // CHECK:       ObjCMessageExpr {{.*}} 'void' contains-errors
-  // CHECK-NEXT:  |-ImplicitCastExpr {{.*}} 'Foo *' <LValueToRValue>
-  // CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'foo'
-  // CHECK-NEXT:  `-RecoveryExpr {{.*}}
-  [foo method:undef];
-
-  // CHECK:      ImplicitCastExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
-  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'foo'
-  foo.undef;
-}
-
-// CHECK:      |-VarDecl {{.*}} 'int (^)()' cinit
-// CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type> (^)(void)' contains-errors lvalue
-// CHECK-NEXT: |   `-BlockExpr {{.*}} '<dependent type> (^)(void)'
-// CHECK-NEXT: |     `-BlockDecl {{.*}} invalid
-int (^gh63863)() = ^() {
-  return undef;
-};
-
-// CHECK:      `-BlockExpr {{.*}} 'int (^)(int, int)'
-// CHECK-NEXT:   `-BlockDecl {{.*}} invalid
-int (^gh64005)(int, int) = ^(int, undefined b) {
-   return 1;
-};

>From 22fc4d8f1e19d88c54e223d3759f86174d743470 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Mon, 9 Jun 2025 13:34:33 -0400
Subject: [PATCH 08/11] Update test

This test requires a RecoveryExpr and typos no longer cause a recovery
expression to be created. So the expression was changed to one which
does have a RecoveryExpr.
---
 clang/test/SemaTemplate/concepts-recovery-expr.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/SemaTemplate/concepts-recovery-expr.cpp b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
index b338f3bc271bf..6bed1790051f3 100644
--- a/clang/test/SemaTemplate/concepts-recovery-expr.cpp
+++ b/clang/test/SemaTemplate/concepts-recovery-expr.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -std=c++20 -verify %s
 
-// expected-error at +1{{use of undeclared identifier 'b'}}
-constexpr bool CausesRecoveryExpr = b;
+// expected-error at +1 {{invalid operands to binary expression ('const char[5]' and 'float')}}
+constexpr bool CausesRecoveryExpr = "test" + 1.0f;
 
 template<typename T>
 concept ReferencesCRE = CausesRecoveryExpr;

>From 4fc7a46195f8cf7449398d7f40fdec2b3cde1da8 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Mon, 9 Jun 2025 13:46:33 -0400
Subject: [PATCH 09/11] Now with whitespace added back

---
 clang/test/CXX/drs/cwg1xx.cpp         |  4 ++--
 clang/test/Parser/recovery.c          | 10 +++++-----
 clang/test/Parser/switch-recovery.cpp |  2 +-
 clang/test/SemaCXX/arrow-operator.cpp |  2 +-
 clang/test/SemaCXX/destructor.cpp     |  8 ++++----
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index 4051a0996c076..c9dce77b772dc 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -634,7 +634,7 @@ namespace example3 {
 struct Base {
 private:
   static const int i = 10; // #cwg138-ex3-Base-i
-
+  
 public:
   struct Data;
   // Elaborated type specifier is not the sole constituent of declaration,
@@ -648,7 +648,7 @@ struct Base {
   };
 };
 struct Data {
-  void f() {
+  void f() {  
     int i2 = Base::i;
     // expected-error at -1 {{'i' is a private member of 'cwg138::example3::Base'}}
     //   expected-note@#cwg138-ex3-Base-i {{declared private here}}
diff --git a/clang/test/Parser/recovery.c b/clang/test/Parser/recovery.c
index a84fe0e6ac525..0d86bd0608bf1 100644
--- a/clang/test/Parser/recovery.c
+++ b/clang/test/Parser/recovery.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -fblocks %s
 
 // PR2241
-float test2241[2] = {
+float test2241[2] = { 
   1e,            // expected-error {{exponent}}
   1ee0           // expected-error {{exponent}}
 };
@@ -21,17 +21,17 @@ static void f (char * (*g) (char **, int), char **p, ...) {
 
 void test(int a) {
   struct { int i; } x;
-
+  
   if (x.hello)   // expected-error {{no member named 'hello'}}
     test(0);
   else
     ;
-
+  
   if (x.hello == 0)   // expected-error {{no member named 'hello'}}
     test(0);
   else
     ;
-
+  
   if ((x.hello == 0))   // expected-error {{no member named 'hello'}}
     test(0);
   else
@@ -60,7 +60,7 @@ struct S A = {
 &BADIDENT, 0     /* expected-error {{use of undeclared identifier}} */
 };
 
-void test6248081(void) {
+void test6248081(void) { 
   [10]  // expected-error {{expected expression}}
 }
 
diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp
index 084b9d982a2c0..a0c33ce943fbe 100644
--- a/clang/test/Parser/switch-recovery.cpp
+++ b/clang/test/Parser/switch-recovery.cpp
@@ -7,7 +7,7 @@ struct B {
     default:
       return;
     }
-
+    
     switch (b) {
     case 17 // expected-error{{expected ':' after 'case'}}
       break;
diff --git a/clang/test/SemaCXX/arrow-operator.cpp b/clang/test/SemaCXX/arrow-operator.cpp
index 39a1932ca91e3..a789c4e36e4c9 100644
--- a/clang/test/SemaCXX/arrow-operator.cpp
+++ b/clang/test/SemaCXX/arrow-operator.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-struct T {
+struct T { 
   void f();
 };
 
diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp
index b9e0b17d510ab..f1ef3f311949e 100644
--- a/clang/test/SemaCXX/destructor.cpp
+++ b/clang/test/SemaCXX/destructor.cpp
@@ -58,7 +58,7 @@ struct D {
 
 struct D2 {
   void ~D2() { } //                          \
-  // expected-error{{destructor cannot have a return type}}
+  // expected-error{{destructor cannot have a return type}}  
 };
 
 
@@ -86,7 +86,7 @@ struct G {
 G::~G() { }
 
 struct H {
-  ~H(void) { }
+  ~H(void) { } 
 };
 
 struct X {};
@@ -103,7 +103,7 @@ namespace PR6421 {
     template<typename U>
     void foo(T t) // expected-error{{variable has incomplete type}}
     { }
-
+    
     void disconnect()
     {
       T* t;
@@ -364,7 +364,7 @@ struct __is_destructor_wellformed {
                        decltype(_Tp1().~_Tp1())>::type);
   template <typename _Tp1>
   static __two __test (...);
-
+              
   static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
 };
 

>From 83cc8d218582a536c33e6128707452c7bea445f0 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 10 Jun 2025 08:52:26 -0400
Subject: [PATCH 10/11] Update clangd test

---
 clang-tools-extra/clangd/unittests/HoverTests.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 69f6df46c87ce..775278ccf694b 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -974,7 +974,7 @@ class Foo final {})cpp";
          HI.Name = "abc";
          HI.Kind = index::SymbolKind::Variable;
          HI.NamespaceScope = "";
-         HI.Definition = "int abc = <recovery - expr>()";
+         HI.Definition = "int abc";
          HI.Type = "int";
          HI.AccessSpecifier = "public";
        }},

>From 5ec886e6246f70ba37b1dc14df85b6547a85d671 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 10 Jun 2025 08:55:37 -0400
Subject: [PATCH 11/11] Add release note

---
 clang/docs/ReleaseNotes.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db427451322a8..69340267e6c1a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -620,6 +620,14 @@ Improvements to Clang's diagnostics
 
 - Improved the FixIts for unused lambda captures.
 
+- Delayed typo correction was removed from the compiler; immediate typo
+  correction behavior remains the same. Delayed typo correction facilities were
+  fragile and unmaintained, and the removal closed the following issues:
+  #GH142457, #GH139913, #GH138850, #GH137867, #GH137860, #GH107840, #GH93308,
+  #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490,
+  #GH36703, #GH32903, #GH23312, #GH69874.
+
+
 Improvements to Clang's time-trace
 ----------------------------------
 



More information about the cfe-commits mailing list