tbaeder updated this revision to Diff 319820.
tbaeder added a comment.

Fixed the Lambda oddity as well.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95536/new/

https://reviews.llvm.org/D95536

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprMember.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
  clang/test/CXX/class.access/class.friend/p1.cpp
  clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr21xx.cpp
  clang/test/CXX/drs/dr3xx.cpp
  clang/test/CXX/drs/dr6xx.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/special/class.copy/p28-cxx11.cpp
  clang/test/CXX/special/class.dtor/p10-0x.cpp
  clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
  clang/test/CXX/temp/temp.res/temp.local/p3.cpp
  clang/test/CXX/temp/temp.res/temp.local/p9.cpp
  clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
  clang/test/Misc/diag-template.cpp
  clang/test/Modules/Inputs/redecl_namespaces_left.h
  clang/test/Modules/cxx-templates.cpp
  clang/test/Modules/module-private.cpp
  clang/test/Modules/redecl-namespaces.mm
  clang/test/OpenMP/target_map_messages.cpp
  clang/test/OpenMP/target_teams_map_messages.cpp
  clang/test/PCH/decl-attrs.cpp
  clang/test/Parser/recovery.c
  clang/test/Parser/recovery.cpp
  clang/test/Sema/MicrosoftExtensions.c
  clang/test/Sema/anonymous-struct-union.c
  clang/test/Sema/typo-correction-ambiguity.cpp
  clang/test/Sema/typo-correction-no-hang.cpp
  clang/test/Sema/typo-correction-recursive.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/anonymous-union.cpp
  clang/test/SemaCXX/attr-cleanup.cpp
  clang/test/SemaCXX/co_await-range-for.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/conversion-function.cpp
  clang/test/SemaCXX/coroutines.cpp
  clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
  clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
  clang/test/SemaCXX/friend.cpp
  clang/test/SemaCXX/invalid-member-expr.cpp
  clang/test/SemaCXX/member-operator-expr.cpp
  clang/test/SemaCXX/missing-members.cpp
  clang/test/SemaCXX/nested-name-spec.cpp
  clang/test/SemaCXX/pseudo-destructors.cpp
  clang/test/SemaCXX/qualified-id-lookup.cpp
  clang/test/SemaCXX/typo-correction-delayed.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaObjCXX/deduction.mm
  clang/test/SemaObjCXX/interface-return-type.mm
  clang/test/SemaTemplate/attributes.cpp
  clang/test/SemaTemplate/cxx1z-using-declaration.cpp
  clang/test/SemaTemplate/dependent-base-classes.cpp
  clang/test/SemaTemplate/instantiate-method.cpp
  clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
  clang/test/SemaTemplate/member-access-ambig.cpp
  clang/test/SemaTemplate/member-access-expr.cpp
  clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp

Index: clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
===================================================================
--- clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -200,7 +200,7 @@
 
 namespace PR16014 {
 
-struct A {
+struct A { // expected-note {{declared here}}
   int a;
   static int sa;
 };
@@ -226,7 +226,8 @@
 };
 
 template struct B<A>;
-template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
+template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}} \
+                       // expected-note 2 {{declared here}}
 
 template <typename T> struct D : T {
   struct Inner {
Index: clang/test/SemaTemplate/member-access-expr.cpp
===================================================================
--- clang/test/SemaTemplate/member-access-expr.cpp
+++ clang/test/SemaTemplate/member-access-expr.cpp
@@ -43,7 +43,7 @@
 
 }
 
-struct OtherBase { };
+struct OtherBase { }; // expected-note 2 {{declared here}}
 
 struct X1 : Base, OtherBase { 
   typedef OtherBase CrazyBase;
@@ -59,7 +59,7 @@
 }
 
 
-struct X2 {
+struct X2 { // expected-note {{declared here}}
   operator int() const;
 };
 
Index: clang/test/SemaTemplate/member-access-ambig.cpp
===================================================================
--- clang/test/SemaTemplate/member-access-ambig.cpp
+++ clang/test/SemaTemplate/member-access-ambig.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-comparison %s
 
 // PR8439
-class A
+class A // expected-note {{declared here}}
 {
 };
 
Index: clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
+++ clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
@@ -32,13 +32,13 @@
   }
 };
 
-class Q {
+class Q { // expected-note 2 {{declared here}}
 public:
   Q() {}
   ~Q() {}
 };
 
-enum Colors {red, green, blue};
+enum Colors {red, green, blue}; // expected-note {{declared here}}
 
 C<Q, int> dummy;
 C<Q, Colors> dummyColors;
Index: clang/test/SemaTemplate/instantiate-method.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-method.cpp
+++ clang/test/SemaTemplate/instantiate-method.cpp
@@ -184,7 +184,7 @@
 }
 
 namespace PR22040 {
-  template <typename T> struct Foobar {
+  template <typename T> struct Foobar { // expected-note 3 {{here}}
     template <> void bazqux(typename T::type) {}  // expected-error 2{{cannot be used prior to '::' because it has no members}}
   };
 
Index: clang/test/SemaTemplate/dependent-base-classes.cpp
===================================================================
--- clang/test/SemaTemplate/dependent-base-classes.cpp
+++ clang/test/SemaTemplate/dependent-base-classes.cpp
@@ -56,7 +56,7 @@
     int foo() {
       class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
       typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{no member named 'MemberTemplate' in 'NoDepBase<T>'}}
-      return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
+      return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}} expected-note@-4 {{here}}
     }
   };
 }
Index: clang/test/SemaTemplate/cxx1z-using-declaration.cpp
===================================================================
--- clang/test/SemaTemplate/cxx1z-using-declaration.cpp
+++ clang/test/SemaTemplate/cxx1z-using-declaration.cpp
@@ -16,7 +16,7 @@
 }
 
 // Test using non-type members from pack of base classes.
-template<typename ...T> struct A : T... {
+template<typename ...T> struct A : T... { // expected-note {{declared here}}
   using T::T ...; // expected-note 2{{inherited here}}
   using T::operator() ...;
   using T::operator T* ...;
@@ -158,7 +158,7 @@
 // Test partial substitution into class-scope pack.
 template<typename ...T> auto lambda1() {
   return [](auto x) {
-    struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}}
+    struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}} expected-note {{declared here}}
       using T::template X<decltype(x)>::f ...;
       using typename T::template X<decltype(x)>::type ...;
       void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}}
Index: clang/test/SemaTemplate/attributes.cpp
===================================================================
--- clang/test/SemaTemplate/attributes.cpp
+++ clang/test/SemaTemplate/attributes.cpp
@@ -77,7 +77,7 @@
   template<typename T> struct [[clang::preferred_name(X), clang::preferred_name(Y)]] C;
   template<typename T> struct [[clang::preferred_name(const X)]] C; // expected-error {{argument 'const preferred_name::X'}}
   template<typename T> struct [[clang::preferred_name(Z)]] C; // expected-error {{argument 'preferred_name::Z' (aka 'const C<double>')}}
-  template<typename T> struct C {};
+  template<typename T> struct C {}; // expected-note 3 {{declared here}}
 
   // CHECK: ClassTemplateDecl {{.*}} <line:[[@LINE-10]]:{{.*}} C
   // CHECK:   ClassTemplateSpecializationDecl {{.*}} struct C definition
@@ -113,7 +113,7 @@
   template<typename T> struct D;
   using DInt = D<int>;
   template<typename T> struct __attribute__((__preferred_name__(DInt))) D {};
-  template struct D<int>;
+  template struct D<int>; // expected-note {{declared here}}
   int use_dint = D<int>().get(); // expected-error {{no member named 'get' in 'preferred_name::DInt'}}
 
   template<typename T> struct MemberTemplate {
Index: clang/test/SemaObjCXX/interface-return-type.mm
===================================================================
--- clang/test/SemaObjCXX/interface-return-type.mm
+++ clang/test/SemaObjCXX/interface-return-type.mm
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
 
 @class NSObject;
-template<typename T> struct C {
+template<typename T> struct C { // expected-note {{declared here}}
       static T f(); // expected-error {{interface type 'NSObject' cannot be returned by value; did you forget * in 'NSObject'?}}
 };
 int g() { NSObject *x = C<NSObject>::f(); }//expected-error {{no member named 'f' in 'C<NSObject>'}} expected-note {{in instantiation of template class 'C<NSObject>' requested here}}
Index: clang/test/SemaObjCXX/deduction.mm
===================================================================
--- clang/test/SemaObjCXX/deduction.mm
+++ clang/test/SemaObjCXX/deduction.mm
@@ -36,7 +36,7 @@
   template <typename T> struct RemovePointer<T*> {
     typedef T type;
   };
-  template <typename A, typename B> struct is_same {};
+  template <typename A, typename B> struct is_same {}; // expected-note 2 {{declared here}}
   template <typename A> struct is_same<A,A> {
     static void foo();
   };
Index: clang/test/SemaCXX/unknown-type-name.cpp
===================================================================
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -4,7 +4,7 @@
 
 // PR3990
 namespace N {
-  struct Wibble {
+  struct Wibble { // expected-note {{here}}
   };
 
   typedef Wibble foo;
Index: clang/test/SemaCXX/typo-correction.cpp
===================================================================
--- clang/test/SemaCXX/typo-correction.cpp
+++ clang/test/SemaCXX/typo-correction.cpp
@@ -259,7 +259,7 @@
     s.methodd(&b);  // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'; did you mean 'method'}}
   }
 
-  struct S2 {
+  struct S2 { // expected-note {{here}}
     S2();
     void method(A*) const;
    private:
Index: clang/test/SemaCXX/typo-correction-delayed.cpp
===================================================================
--- clang/test/SemaCXX/typo-correction-delayed.cpp
+++ clang/test/SemaCXX/typo-correction-delayed.cpp
@@ -4,7 +4,7 @@
 
 struct A {};
 struct B {};
-struct D {
+struct D { // expected-note 4 {{declared here}}
   A fizbin;  // expected-note 2 {{declared here}}
   A foobar;  // expected-note 2 {{declared here}}
   B roxbin;  // expected-note 2 {{declared here}}
@@ -65,7 +65,7 @@
 // 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 {
+struct Node { // expected-note {{declared here}}
   string text() const;
   // Node* Next() is not implemented yet
 };
@@ -85,7 +85,7 @@
   LinkedNode *next = node->Next();  // expected-error {{no member named 'Next' in 'initializerCorrections::LinkedNode'; did you mean 'next'?}}
 }
 
-struct NestedNode {
+struct NestedNode { // expected-note {{declared here}}
   NestedNode* Nest();
   NestedNode* next();
   string text() const;
@@ -111,7 +111,7 @@
 
 namespace foo {}
 void test_paren_suffix() {
-  foo::bar({5, 6});  // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}}
+  foo::bar({5, 6});  // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}} expected-note@-2 {{here}}
 #if __cplusplus <= 199711L
   // expected-error@-2 {{expected expression}}
 #endif
Index: clang/test/SemaCXX/qualified-id-lookup.cpp
===================================================================
--- clang/test/SemaCXX/qualified-id-lookup.cpp
+++ clang/test/SemaCXX/qualified-id-lookup.cpp
@@ -83,7 +83,7 @@
 }
 
 // PR clang/3291
-namespace a {  
+namespace a {
   namespace a {   // A1
     namespace a { // A2
       int i; // expected-note{{'a::a::a::i' declared here}}
@@ -94,9 +94,9 @@
 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::a::i = 4;
-  a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
+  a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}} expected-note@-10 {{here}}
 }
-  
+
 struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
   typedef int type;
 
Index: clang/test/SemaCXX/pseudo-destructors.cpp
===================================================================
--- clang/test/SemaCXX/pseudo-destructors.cpp
+++ clang/test/SemaCXX/pseudo-destructors.cpp
@@ -129,7 +129,7 @@
     template<typename T> void f(T *p) { p->~G(); } // expected-error {{no member named '~Y'}}
     void h1(Y *p) { p->~G(); }
     void h2(Y *p) { f(p); }
-    namespace N { struct G{}; }
+    namespace N { struct G{}; } // expected-note {{declared here}}
     void h3(N::G *p) { p->~G(); }
     void h4(N::G *p) { f(p); } // expected-note {{instantiation of}}
   }
@@ -151,7 +151,7 @@
     template<typename T> void f(T *p) { p->~G<int>(); } // expected-error {{no member named '~Y'}}
     void h1(Y<int> *p) { p->~G<int>(); }
     void h2(Y<int> *p) { f(p); }
-    namespace N { template<typename T> struct G {}; }
+    namespace N { template<typename T> struct G {}; } // expected-note {{declared here}}
     void h3(N::G<int> *p) { p->~G<int>(); }
     void h4(N::G<int> *p) { f(p); } // expected-note {{instantiation of}}
   }
Index: clang/test/SemaCXX/nested-name-spec.cpp
===================================================================
--- clang/test/SemaCXX/nested-name-spec.cpp
+++ 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;
@@ -54,7 +54,7 @@
 
 void f2() {
   A:: ; // expected-error {{expected unqualified-id}}
-  A::C::undef = 0; // expected-error {{no member named 'undef'}}
+  A::C::undef = 0; // expected-error {{no member named 'undef'}} expected-note@3 {{here}}
   ::A::C::cx = 0;
   int x = ::A::ax = A::C::cx;
   x = sizeof(A::C);
@@ -91,7 +91,7 @@
   N::x = 0; // expected-error {{'N' is not a class, namespace, or enumeration}}
   { int A;           A::ax = 0; }
   { typedef int A;   A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or enumeration}}
-  { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
+  { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}} expected-note@3 {{here}}
   { typedef A::C A;  A::cx = 0; }
 }
 
@@ -431,7 +431,7 @@
                                                 // expected-error{{'ENUMERATOR' is not a class, namespace, or enumeration}} \
 
   int x3 = ns::an_enumeration::X; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \
-                                  // expected-error{{no member named 'X'}}
+                                  // expected-error{{no member named 'X'}} expected-note@-10 {{here}}
 
   enum enumerator_2 {
     ENUMERATOR_2
@@ -439,7 +439,7 @@
 
   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-note@-5 {{here}}
 
 }
 
Index: clang/test/SemaCXX/missing-members.cpp
===================================================================
--- clang/test/SemaCXX/missing-members.cpp
+++ clang/test/SemaCXX/missing-members.cpp
@@ -8,7 +8,7 @@
 }
 
 void f() {
-  A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}}
+  A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}} expected-note@3 {{here}}
   A::B::C::i; // expected-error {{no member named 'i' in 'A::B::C'}}
   ::i; // expected-error {{no member named 'i' in the global namespace}}
 }
@@ -22,7 +22,8 @@
   // FIXME: The typo corrections below should be suppressed since A::B::C
   // doesn't have a member named D.
   B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \
-              // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}}
+              // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}} \
+              // expected-note@4 {{here}}
   ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}}
 }
 
@@ -33,12 +34,12 @@
 
 using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}}
 
-struct S : A::B::C { 
-  using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}}
-  
+struct S : A::B::C {
+  using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}} expected-note@4 {{here}}
+
 };
 
-struct S1 {};
+struct S1 {}; // expected-note {{declared here}}
 
 struct S2 : S1 {};
 
Index: clang/test/SemaCXX/member-operator-expr.cpp
===================================================================
--- clang/test/SemaCXX/member-operator-expr.cpp
+++ clang/test/SemaCXX/member-operator-expr.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-class X {
+class X { // expected-note 4 {{declared here}}
 public:
   int operator++();
   operator int();
@@ -31,4 +31,4 @@
 namespace pr13157 {
   class A { public: void operator()(int x, int y = 2, ...) {} };
   void f() { A()(1); }
-}
\ No newline at end of file
+}
Index: clang/test/SemaCXX/invalid-member-expr.cpp
===================================================================
--- clang/test/SemaCXX/invalid-member-expr.cpp
+++ clang/test/SemaCXX/invalid-member-expr.cpp
@@ -39,7 +39,7 @@
 #endif
   }
 
-  struct string {
+  struct string { // expected-note {{declared here}}
     class iterator {};
   };
 
Index: clang/test/SemaCXX/friend.cpp
===================================================================
--- clang/test/SemaCXX/friend.cpp
+++ clang/test/SemaCXX/friend.cpp
@@ -206,7 +206,7 @@
     ::test10::f10_a();
     ::test10::f10_b();
     ::test10::f10_c();
-    ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
+    ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} expected-note@169 {{here}}
 
     f10_a(x);
     f10_b(x);
@@ -216,7 +216,7 @@
     ::test10::f10_a(x);
     ::test10::f10_b(x);
     ::test10::f10_c(x);
-    ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
+    ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} expected-note@169 {{here}}
   }
 
   struct Y : X {
Index: clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
===================================================================
--- clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -398,7 +398,7 @@
 
 #ifndef PRECXX11
 namespace template_vars_in_template {
-template <int> struct TakesInt {};
+template <int> struct TakesInt {}; // expected-note {{declared here}}
 
 template <class T2>
 struct S {
Index: clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
===================================================================
--- clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -10,7 +10,7 @@
 auto h() -> auto *;
 auto *h();
 
-struct Conv1 {
+struct Conv1 { // expected-note {{declared here}}
   operator auto(); // expected-note {{declared here}}
 } conv1;
 int conv1a = conv1; // expected-error {{function 'operator auto' with deduced return type cannot be used before it is defined}}
@@ -62,7 +62,7 @@
   operator auto() { return 0; }
   operator auto *() { return this; }
 };
-struct JustTemplateOp {
+struct JustTemplateOp { // expected-note 2 {{declared here}}
   template <typename T> operator T();
   template <typename T> operator T *();
 };
Index: clang/test/SemaCXX/coroutines.cpp
===================================================================
--- clang/test/SemaCXX/coroutines.cpp
+++ clang/test/SemaCXX/coroutines.cpp
@@ -103,7 +103,7 @@
 
 template <>
 struct std::experimental::coroutine_traits<double, int> {
-  struct promise_type {};
+  struct promise_type {}; // expected-note 2 {{declared here}}
 };
 double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
   co_yield 0; // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}}
@@ -125,9 +125,9 @@
 
 struct yielded_thing { const char *p; short a, b; };
 
-struct not_awaitable {};
+struct not_awaitable {}; // expected-note 3 {{declared here}}
 
-struct promise {
+struct promise { // expected-note {{declared here}}
   void get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend() noexcept;
@@ -138,7 +138,7 @@
   void unhandled_exception();
 };
 
-struct promise_void {
+struct promise_void { // expected-note {{declared here}}
   void get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend() noexcept;
@@ -422,7 +422,7 @@
   awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
   template void await_template(indirectly_awaitable);
 
-  struct not_awaitable {};
+  struct not_awaitable {}; // expected-note {{declared here}}
   template void await_template(not_awaitable); // expected-note {{instantiation}}
 
   template<typename T> void await_template_2(T t) {
@@ -433,7 +433,7 @@
   template void await_template_2(outer);
 
   struct transform_awaitable {};
-  struct transformed {};
+  struct transformed {}; // expected-note 4 {{declared here}}
 
   struct transform_promise {
     typedef transform_awaitable await_arg;
@@ -566,7 +566,7 @@
   }
 }
 
-struct bad_promise_1 {
+struct bad_promise_1 { // expected-note {{declared here}}
   suspend_always initial_suspend();
   suspend_always final_suspend() noexcept;
   void unhandled_exception();
@@ -1425,11 +1425,11 @@
   co_yield 42; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 }
 
-struct missing_await_ready {
+struct missing_await_ready { // expected-note {{declared here}}
   void await_suspend(std::experimental::coroutine_handle<>);
   void await_resume();
 };
-struct missing_await_suspend {
+struct missing_await_suspend { // expected-note {{declared here}}
   bool await_ready();
   void await_resume();
 };
Index: clang/test/SemaCXX/conversion-function.cpp
===================================================================
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -459,7 +459,7 @@
   } a;
   A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
   A::E e = a;
-  bool k1 = e == A::e; // expected-error {{no member named 'e'}}
+  bool k1 = e == A::e; // expected-error {{no member named 'e'}} expected-note@-10 {{here}}
   bool k2 = e.n == 0;
 }
 
Index: clang/test/SemaCXX/constructor-initializer.cpp
===================================================================
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -245,7 +245,7 @@
 #endif
   // expected-note@-5 {{candidate constructor (the implicit default constructor) not viable}}
 
-  class B : public A {
+  class B : public A { // expected-note {{declared here}}
   public:
     B(const String& s, int e=0) // expected-error {{unknown type name}} 
       : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
Index: clang/test/SemaCXX/co_await-range-for.cpp
===================================================================
--- clang/test/SemaCXX/co_await-range-for.cpp
+++ clang/test/SemaCXX/co_await-range-for.cpp
@@ -17,7 +17,7 @@
 template <class Iter> struct IncTag { IncTag() = delete; };
 
 template <class Iter, bool Delete = false>
-struct CoawaitTag { CoawaitTag() = delete; };
+struct CoawaitTag { CoawaitTag() = delete; }; // expected-note {{declared here}}
 
 template <class T>
 struct Iter {
Index: clang/test/SemaCXX/attr-cleanup.cpp
===================================================================
--- clang/test/SemaCXX/attr-cleanup.cpp
+++ clang/test/SemaCXX/attr-cleanup.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-gcc-compat
 
-namespace N {
+namespace N { // expected-note {{here}}
   void c1(int *a) {}
 }
 
Index: clang/test/SemaCXX/anonymous-union.cpp
===================================================================
--- clang/test/SemaCXX/anonymous-union.cpp
+++ clang/test/SemaCXX/anonymous-union.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
-struct X {
+struct X { // expected-note {{declared here}}
   union {
     float f3;
     double d2;
Index: clang/test/SemaCXX/MicrosoftExtensions.cpp
===================================================================
--- clang/test/SemaCXX/MicrosoftExtensions.cpp
+++ clang/test/SemaCXX/MicrosoftExtensions.cpp
@@ -246,7 +246,7 @@
   C::C(); // expected-warning{{extra qualification on member 'C'}}
 };
 
-struct StructWithProperty {
+struct StructWithProperty { // expected-note 2 {{declared here}}
   __declspec(property(get=GetV)) int V1;
   __declspec(property(put=SetV)) int V2;
   __declspec(property(get=GetV, put=SetV_NotExist)) int V3;
Index: clang/test/Sema/typo-correction-recursive.cpp
===================================================================
--- clang/test/Sema/typo-correction-recursive.cpp
+++ clang/test/Sema/typo-correction-recursive.cpp
@@ -20,7 +20,7 @@
   int m_n;
 };
 
-class Z
+class Z // expected-note {{here}}
 {
 public:
   const Y& getY0() const { return m_y0; }  // expected-note {{'getY0' declared here}}
@@ -73,7 +73,7 @@
   int helpMe();
   int helpBe();
 };
-class Ambiguous {
+class Ambiguous { // expected-note 2 {{here}}
 public:
   int calculateA();
   int calculateB();
@@ -94,7 +94,7 @@
 }
 
 
-class DeepAmbiguityHelper {
+class DeepAmbiguityHelper { // expected-note {{here}}
 public:
   DeepAmbiguityHelper& help1();
   DeepAmbiguityHelper& help2();
Index: clang/test/Sema/typo-correction-no-hang.cpp
===================================================================
--- clang/test/Sema/typo-correction-no-hang.cpp
+++ clang/test/Sema/typo-correction-no-hang.cpp
@@ -15,7 +15,7 @@
 }
 
 // Similar reproducer.
-class A {
+class A { // expected-note 1 {{here}}
 public:
   int minut() const = delete;
   int hour() const = delete;
@@ -24,7 +24,7 @@
   int latit() const;
 };
 
-class B {
+class B { // expected-note 2 {{here}}
 public:
   A depar() const { return A(); }
 };
Index: clang/test/Sema/typo-correction-ambiguity.cpp
===================================================================
--- clang/test/Sema/typo-correction-ambiguity.cpp
+++ clang/test/Sema/typo-correction-ambiguity.cpp
@@ -13,7 +13,7 @@
 
 void testAmbiguousNoSuggestions()
 {
-  AmbiguousCorrection::method_Ace(); // expected-error {{no member named 'method_Ace' in namespace 'AmbiguousCorrection'}}
+  AmbiguousCorrection::method_Ace(); // expected-error {{no member named 'method_Ace' in namespace 'AmbiguousCorrection'}} expected-note@7 {{here}}
 }
 
 namespace MultipleCorrectionsButNotAmbiguous
Index: clang/test/Sema/anonymous-struct-union.c
===================================================================
--- clang/test/Sema/anonymous-struct-union.c
+++ clang/test/Sema/anonymous-struct-union.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-struct X {
+struct X { // expected-note {{here}}
   union {
     float f3;
     double d2;
Index: clang/test/Sema/MicrosoftExtensions.c
===================================================================
--- clang/test/Sema/MicrosoftExtensions.c
+++ clang/test/Sema/MicrosoftExtensions.c
@@ -62,7 +62,7 @@
   long f;
 } NESTED6;
 
-struct test {
+struct test { // expected-note 2 {{here}}
   int c;
   struct nested2;   // expected-warning {{anonymous structs are a Microsoft extension}}
   NESTED6;   // expected-warning {{anonymous unions are a Microsoft extension}}
Index: clang/test/Parser/recovery.cpp
===================================================================
--- clang/test/Parser/recovery.cpp
+++ clang/test/Parser/recovery.cpp
@@ -36,7 +36,8 @@
 5int m = { l }, n = m; // expected-error {{unqualified-id}}
 
 namespace MissingBrace {
-  struct S { // expected-error {{missing '}' at end of definition of 'MissingBrace::S'}}
+  struct S { // expected-error {{missing '}' at end of definition of 'MissingBrace::S'}} \
+             // expected-note {{declared here}}
     int f();
   // };
 
Index: clang/test/Parser/recovery.c
===================================================================
--- clang/test/Parser/recovery.c
+++ clang/test/Parser/recovery.c
@@ -21,7 +21,7 @@
 
 // rdar://6094870
 void test(int a) {
-  struct { int i; } x;
+  struct { int i; } x; // expected-note 3 {{declared here}}
   
   if (x.hello)   // expected-error {{no member named 'hello'}}
     test(0);
Index: clang/test/PCH/decl-attrs.cpp
===================================================================
--- clang/test/PCH/decl-attrs.cpp
+++ clang/test/PCH/decl-attrs.cpp
@@ -31,8 +31,10 @@
 
   template<typename T> T forget(T t) { return t; }
   void f() {
-    forget(y).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Y'}}
-    forget(z).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Z'}}
+    forget(y).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Y'}} \
+                     // expected-note@11 {{declared here}}
+    forget(z).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Z'}} \
+                     // expected-note@11 {{declared here}}
   }
 }
 
Index: clang/test/OpenMP/target_teams_map_messages.cpp
===================================================================
--- clang/test/OpenMP/target_teams_map_messages.cpp
+++ clang/test/OpenMP/target_teams_map_messages.cpp
@@ -89,7 +89,7 @@
   }
 };
 
-struct SB {
+struct SB { // expected-note {{declared here}}
   unsigned A;
   unsigned B;
   float Arr[100];
Index: clang/test/OpenMP/target_map_messages.cpp
===================================================================
--- clang/test/OpenMP/target_map_messages.cpp
+++ clang/test/OpenMP/target_map_messages.cpp
@@ -189,7 +189,7 @@
   }
 };
 
-struct SB {
+struct SB { // expected-note {{declared here}}
   unsigned A;
   unsigned B;
   float Arr[100];
Index: clang/test/Modules/redecl-namespaces.mm
===================================================================
--- clang/test/Modules/redecl-namespaces.mm
+++ clang/test/Modules/redecl-namespaces.mm
@@ -4,7 +4,8 @@
 void test() {
   A::i;
   A::j;
-  A::k;  // expected-error {{no member named 'k' in namespace 'A'}}
+  A::k;  // expected-error {{no member named 'k' in namespace 'A'}} \
+         // expected-note@redecl_namespaces_left.h:1 {{here}}
 }
 
 // RUN: rm -rf %t
Index: clang/test/Modules/module-private.cpp
===================================================================
--- clang/test/Modules/module-private.cpp
+++ clang/test/Modules/module-private.cpp
@@ -21,8 +21,10 @@
   vector<int> vec; // expected-error{{no template named 'vector'}}
 
   VisibleStruct vs;
-  vs.field = 0; // expected-error{{no member named 'field' in 'VisibleStruct'}}
-  vs.setField(1); // expected-error{{no member named 'setField' in 'VisibleStruct'}}
+  vs.field = 0; // expected-error{{no member named 'field' in 'VisibleStruct'}} \
+                // expected-note@module_private_right.h:10 {{declared here}}
+  vs.setField(1); // expected-error{{no member named 'setField' in 'VisibleStruct'}} \
+                  // expected-note@module_private_right.h:10 {{declared here}}
 
   return hidden_var; // expected-error{{use of undeclared identifier 'hidden_var'}}
 }
Index: clang/test/Modules/cxx-templates.cpp
===================================================================
--- clang/test/Modules/cxx-templates.cpp
+++ clang/test/Modules/cxx-templates.cpp
@@ -85,6 +85,7 @@
   // expected-error@Inputs/cxx-templates-a.h:19 {{definition of 'DefinedInBImpl' must be imported}}
   // expected-note@Inputs/cxx-templates-b-impl.h:1 +{{definition here is not reachable}}
   // expected-error@Inputs/cxx-templates-a.h:19 +{{}}
+  // expected-note@Inputs/cxx-templates-b-impl.h:1 {{declared here}}
   // expected-error@Inputs/cxx-templates-a.h:20 +{{}}
   PerformDelayedLookup(defined_in_b_impl); // expected-note {{in instantiation of}}
 
Index: clang/test/Modules/Inputs/redecl_namespaces_left.h
===================================================================
--- clang/test/Modules/Inputs/redecl_namespaces_left.h
+++ clang/test/Modules/Inputs/redecl_namespaces_left.h
@@ -1,3 +1,3 @@
-namespace A {
+namespace A { // expected-note {{here}}
   int i;
 }
Index: clang/test/Misc/diag-template.cpp
===================================================================
--- clang/test/Misc/diag-template.cpp
+++ clang/test/Misc/diag-template.cpp
@@ -3,7 +3,7 @@
 namespace default_args {
   template<typename T> struct char_traits;
   template<typename T> struct allocator;
-  template<typename T, typename = char_traits<T>, typename = allocator<T>> struct basic_string {};
+  template<typename T, typename = char_traits<T>, typename = allocator<T>> struct basic_string {}; // expected-note 2 {{declared here}}
 
   typedef basic_string<char> string;
 
@@ -15,7 +15,7 @@
   }
 
   template<typename T> struct default_delete {};
-  template<class T, class Deleter = default_delete<T>> class unique_ptr {
+  template<class T, class Deleter = default_delete<T>> class unique_ptr { // expected-note {{declared here}}
   public:
     void f() { T::error(); } // expected-error {{no member named 'error' in 'default_args::basic_string<char>'}}
   };
@@ -29,7 +29,7 @@
   template<int A, int B = A> struct Z { int error[B]; }; // expected-error {{negative size}}
   Z<-1> z; // expected-note {{in instantiation of template class 'default_args::Z<-1>' requested here}}
 
-  template<template<typename> class A = allocator, template<typename> class B = A> struct Q {};
+  template<template<typename> class A = allocator, template<typename> class B = A> struct Q {}; // expected-note 6 {{declared here}}
   void test3() {
     f(Q<>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}}
     f(Q<allocator>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}}
Index: clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
===================================================================
--- clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
+++ clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
@@ -2,7 +2,7 @@
 
 template<typename T>
 struct X {
-  template<typename U> struct Inner { };
+  template<typename U> struct Inner { }; // expected-note {{declared here}}
   
   template<typename U> void f(T, U) { }
 };
Index: clang/test/CXX/temp/temp.res/temp.local/p9.cpp
===================================================================
--- clang/test/CXX/temp/temp.res/temp.local/p9.cpp
+++ clang/test/CXX/temp/temp.res/temp.local/p9.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 struct A { 
-  struct B { void f(); }; 
+  struct B { void f(); }; // expected-note {{declared here}}
   int a; 
   int Y;
 };
Index: clang/test/CXX/temp/temp.res/temp.local/p3.cpp
===================================================================
--- clang/test/CXX/temp/temp.res/temp.local/p3.cpp
+++ clang/test/CXX/temp/temp.res/temp.local/p3.cpp
@@ -6,7 +6,7 @@
   static void f();
 }; 
 
-struct X0 { };
+struct X0 { }; // expected-note {{declared here}}
 
 template <class T> struct Derived: Base<int>, Base<char> {
   typename Derived::Base b;	// expected-error{{member 'Base' found in multiple base classes of different types}}
Index: clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
===================================================================
--- clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
+++ clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
-template<typename T> struct A {
+template<typename T> struct A { // expected-note {{here}}
   enum E : T; // expected-note {{here}}
   E v;
   E f() { return A::e1; } // expected-error {{no member named 'e1' in 'A<T>'}}
@@ -74,7 +74,7 @@
 void fc1() { c1 = decltype(c1)::e5; }
 C<long>::E c2 = C<long>::E::e5;
 
-template<> enum class C<int>::E : int { e6 };
+template<> enum class C<int>::E : int { e6 }; // expected-note {{here}}
 template<typename T> enum class C<T>::E : T { e0 };
 C<int>::E c3 = C<int>::E::e6;
 C<int>::E c4 = C<int>::E::e0; // expected-error {{no member named 'e0' in 'C<int>::E'}}
Index: clang/test/CXX/special/class.dtor/p10-0x.cpp
===================================================================
--- clang/test/CXX/special/class.dtor/p10-0x.cpp
+++ clang/test/CXX/special/class.dtor/p10-0x.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 // PR10127/N3031
-struct A { ~A(); };
+struct A { ~A(); }; // expected-note 2 {{declared here}}
 struct B {};
 template<typename T>
 void b(const T *x, const A *y) {
Index: clang/test/CXX/special/class.copy/p28-cxx11.cpp
===================================================================
--- clang/test/CXX/special/class.copy/p28-cxx11.cpp
+++ clang/test/CXX/special/class.copy/p28-cxx11.cpp
@@ -5,7 +5,7 @@
 // called by a defaulted assignment operator, and the selected operator might
 // not be a copy or move assignment (it might be a specialization of a templated
 // 'operator=', for instance).
-struct A {
+struct A { // expected-note {{declared here}}
   A &operator=(const A &);
 
   template<typename T>
Index: clang/test/CXX/module/module.interface/p2.cpp
===================================================================
--- clang/test/CXX/module/module.interface/p2.cpp
+++ clang/test/CXX/module/module.interface/p2.cpp
@@ -69,22 +69,22 @@
 
 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 {{no member named 'f' in namespace 'A'}} expected-note@23 {{here}}
   A::g();
-  A::h(); // expected-error {{no member named 'h' in namespace 'A'}}
+  A::h(); // expected-error {{no member named 'h' in namespace 'A'}} expected-note@23 {{here}}
   using namespace A::inner; // expected-error {{expected namespace name}}
 
   // 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 {{no member named 'f' in namespace 'B'}} expected-note@29 {{here}}
   f(); // expected-error {{undeclared identifier 'f'}}
 
   // namespace C is not exported
   using namespace C; // expected-error {{expected namespace name}}
 
   // namespace D is exported, but D::f is not
-  D::f(); // expected-error {{no member named 'f' in namespace 'D'}}
+  D::f(); // expected-error {{no member named 'f' in namespace 'D'}} expected-note@37 {{here}}
 }
 
 int use_header() { return foo + bar::baz(); }
Index: clang/test/CXX/drs/dr6xx.cpp
===================================================================
--- clang/test/CXX/drs/dr6xx.cpp
+++ clang/test/CXX/drs/dr6xx.cpp
@@ -419,7 +419,7 @@
 
 #if __cplusplus >= 201103L
 namespace dr643 { // dr643: yes
-  struct A {
+  struct A { // expected-note 2 {{declared here}}
     int x;
     auto f() -> decltype(this->x);
     auto f(A &a) -> decltype(a.x);
Index: clang/test/CXX/drs/dr3xx.cpp
===================================================================
--- clang/test/CXX/drs/dr3xx.cpp
+++ clang/test/CXX/drs/dr3xx.cpp
@@ -102,7 +102,7 @@
     b->~B(); // expected-error {{does not match}}
   }
 
-  template<typename T> struct X {};
+  template<typename T> struct X {}; // expected-note {{declared here}}
   void i(X<int>* x) {
     struct X {};
     x->~X<int>();
@@ -119,7 +119,7 @@
     y->~T1<int>();
     y->~T2<int>();
   }
-  struct Z {
+  struct Z { // expected-note {{Z' declared here}}
     template<typename T> using T2 = T;
   };
   void k(Z *z) {
@@ -130,7 +130,7 @@
 
   // FIXME: This is valid.
   namespace Q {
-    template<typename A> struct R {};
+    template<typename A> struct R {}; // expected-note {{declared here}}
   }
   template<typename A> using R = Q::R<int>;
   void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}}
Index: clang/test/CXX/drs/dr21xx.cpp
===================================================================
--- clang/test/CXX/drs/dr21xx.cpp
+++ clang/test/CXX/drs/dr21xx.cpp
@@ -38,11 +38,11 @@
   template<typename T> struct B {
     static const int n = 1;
     int f() {
-      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}}
+      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}} expected-note@-4 {{here}}
     }
     int g() {
       static const int n = 2;
-      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}}
+      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}} expected-note@-8 {{here}}
     }
   };
   template<int N> struct Y<N> {
Index: clang/test/CXX/drs/dr1xx.cpp
===================================================================
--- clang/test/CXX/drs/dr1xx.cpp
+++ clang/test/CXX/drs/dr1xx.cpp
@@ -483,9 +483,9 @@
   template<typename T> struct S { int n; };
   struct A : S<int> {
     template<typename T> void f();
-    template<typename T> struct S {};
+    template<typename T> struct S {}; // expected-note {{declared here}}
   } a;
-  struct B : S<int> {} b;
+  struct B : S<int> {} b; // expected-note {{B' declared here}}
   void g() {
     a.f<int>();
     (void)a.S<int>::n; // expected-error {{no member named 'n'}}
Index: clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
===================================================================
--- clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
+++ clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
@@ -85,7 +85,7 @@
   template <class T> struct B : A<T> {
   };
 
-  template <class T> struct C {
+  template <class T> struct C { // expected-note {{declared here}}
   };
 
   int test() {
Index: clang/test/CXX/class.access/class.friend/p1.cpp
===================================================================
--- clang/test/CXX/class.access/class.friend/p1.cpp
+++ clang/test/CXX/class.access/class.friend/p1.cpp
@@ -13,7 +13,7 @@
 struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
 S* g() { return 0; } // expected-note 2 {{'g' declared here}}
 
-struct X {
+struct X { // expected-note {{declared here}}
   friend struct S;
   friend S* g();
 };
@@ -31,7 +31,7 @@
 // Test that we recurse through namespaces to find already declared names, but
 // new names are declared within the enclosing namespace.
 namespace N {
-  struct X {
+  struct X { // expected-note 2 {{declared here}}
     friend struct S;
     friend S* g();
 
Index: clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
===================================================================
--- clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
+++ clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
@@ -86,7 +86,7 @@
 
   template<typename T> T *end(T*);
 
-  class X { };
+  class X { }; // expected-note {{X' declared here}}
   template <typename T>
   void Foo2() {
     T it1;
Index: clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp
===================================================================
--- clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp
+++ clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp
@@ -55,7 +55,7 @@
 
   template<typename T> T *end(T*);
 
-  class X { };
+  class X { }; // expected-note {{X' declared here}}
   template <typename T>
   void Foo2() {
     T it1;
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -713,6 +713,7 @@
                                        << SS.getRange());
         } else {
           SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange;
+          SemaRef.reportDeclForUnknownMember(DC);
         }
       },
       [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
@@ -1024,6 +1025,8 @@
     Diag(R.getNameLoc(), diag::err_no_member)
       << MemberName << DC
       << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
+    reportDeclForUnknownMember(DC);
+
     return ExprError();
   }
 
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -2110,10 +2110,12 @@
   if (!TC) {
     // Emit a special diagnostic for failed member lookups.
     // FIXME: computing the declaration context might fail here (?)
-    if (Ctx)
+    if (Ctx) {
       SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
                                                  << SS.getRange();
-    else
+
+      SemaRef.reportDeclForUnknownMember(Ctx);
+    } else
       SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
     return;
   }
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -2544,3 +2544,18 @@
   return checkOpenCLDisabledTypeOrDecl(&D, E.getBeginLoc(), FnName,
                                        OpenCLDeclExtMap, 1, D.getSourceRange());
 }
+
+void Sema::reportDeclForUnknownMember(const DeclContext *Ctx) {
+  // Don't report the global scope decl
+  if (isa<TranslationUnitDecl>(Ctx))
+    return;
+
+  // Lambdas already report their declaration location themselves
+  if (isa<CXXRecordDecl>(Ctx) && cast<CXXRecordDecl>(Ctx)->isLambda())
+    return;
+
+  if (const Decl *D = dyn_cast<Decl>(Ctx)) {
+    Diag(D->getLocation(), diag::note_entity_declared_at)
+        << Ctx << D->getLocation();
+  }
+}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -9792,6 +9792,9 @@
 
   bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
 
+  /// Report a Note for an unknown member of the given decl context
+  void reportDeclForUnknownMember(const DeclContext *Ctx);
+
   /// Check whether the given new method is a valid override of the
   /// given overridden method, and set any properties that should be inherited.
   void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to