Unify the codepaths for emitting deprecation warnings.  The test changes are just to account for us emitting notes more consistently.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161528 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f596ffc..22bff86 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4650,24 +4650,36 @@
   return false;
 }
 
+static void
+DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
+                         SourceLocation Loc,
+                         const ObjCInterfaceDecl *UnknownObjCClass) {
+  DeclarationName Name = D->getDeclName();
+  if (!Message.empty()) {
+    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
+    S.Diag(D->getLocation(),
+           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
+                                  : diag::note_previous_decl) << Name;
+  } else if (!UnknownObjCClass) {
+    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
+    S.Diag(D->getLocation(),
+           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
+                                  : diag::note_previous_decl) << Name;
+  } else {
+    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
+    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
+  }
+}
+
 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
                                          Decl *Ctx) {
   if (isDeclDeprecated(Ctx))
     return;
 
   DD.Triggered = true;
-  if (!DD.getDeprecationMessage().empty())
-    Diag(DD.Loc, diag::warn_deprecated_message)
-      << DD.getDeprecationDecl()->getDeclName()
-      << DD.getDeprecationMessage();
-  else if (DD.getUnknownObjCClass()) {
-    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message) 
-      << DD.getDeprecationDecl()->getDeclName();
-    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
-  }
-  else
-    Diag(DD.Loc, diag::warn_deprecated)
-      << DD.getDeprecationDecl()->getDeclName();
+  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
+                           DD.getDeprecationMessage(), DD.Loc,
+                           DD.getUnknownObjCClass());
 }
 
 void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
@@ -4684,23 +4696,5 @@
   // Otherwise, don't warn if our current context is deprecated.
   if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
     return;
-  if (!Message.empty()) {
-    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 
-                                             << Message;
-    Diag(D->getLocation(), 
-         isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 
-                                : diag::note_previous_decl) << D->getDeclName();
-  }
-  else {
-    if (!UnknownObjCClass) {
-      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
-      Diag(D->getLocation(), 
-           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 
-                                  : diag::note_previous_decl) << D->getDeclName();
-    }
-    else {
-      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
-      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
-    }
-  }
+  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass);
 }
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index fd0c543..7703999 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -54,8 +54,8 @@
 typedef enum E { e1 };
 
 
-enum __declspec(deprecated) E2 { i, j, k };
-__declspec(deprecated) enum E3 { a, b, c } e;
+enum __declspec(deprecated) E2 { i, j, k }; // expected-note {{declared here}}
+__declspec(deprecated) enum E3 { a, b, c } e; // expected-note {{declared here}}
 
 void deprecated_enum_test(void)
 {
@@ -94,7 +94,7 @@
 
 struct S7 {
 	int foo() { return 12; }
-	__declspec(property(get=foo) deprecated) int t;
+	__declspec(property(get=foo) deprecated) int t; // expected-note {{declared here}}
 };
 
 /* Technically, this is legal (though it does nothing) */
diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c
index 7c2782f..5d7330e 100644
--- a/test/Sema/MicrosoftExtensions.c
+++ b/test/Sema/MicrosoftExtensions.c
@@ -88,7 +88,7 @@
 } BB;
 
 __declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' declared here}}
-struct __declspec(deprecated) DS1 { int i; float f; };
+struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{declared here}}
 
 #define MY_TEXT		"This is also deprecated"
 __declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}}
diff --git a/test/Sema/attr-deprecated-message.c b/test/Sema/attr-deprecated-message.c
index 08b09f9..f48d13e 100644
--- a/test/Sema/attr-deprecated-message.c
+++ b/test/Sema/attr-deprecated-message.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 // rdar: // 6734520
 
-typedef int INT1 __attribute__((deprecated("Please avoid INT1")));
+typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); // expected-note 3 {{'INT1' declared here}}
 
 typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
 
@@ -12,10 +12,10 @@
 INT1 should_be_unavailable; // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 INT1a should_not_be_deprecated;
 
-INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); 
+INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); // expected-note {{'f1' declared here}}
 INT1 f2(void); // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 
-typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color")));
+typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); // expected-note {{'Color' declared here}}
  
 
 Color c1; // expected-warning {{'Color' is deprecated: Please avoid Color}}
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index 1c487d2..7984d56 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-int f() __attribute__((deprecated)); // expected-note {{declared here}}
+int f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
 void g() __attribute__((deprecated));
 void g(); // expected-note {{declared here}}
 
@@ -23,7 +23,7 @@
 }
 
 int old_fn() __attribute__ ((deprecated));
-int old_fn();
+int old_fn(); // expected-note {{declared here}}
 int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
 
 int old_fn() {
@@ -32,7 +32,7 @@
 
 
 struct foo {
-  int x __attribute__((deprecated)); // expected-note {{declared here}}
+  int x __attribute__((deprecated)); // expected-note 3 {{declared here}}
 };
 
 void test1(struct foo *F) {
@@ -41,11 +41,11 @@
   struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}}
 }
 
-typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 3 {{declared here}}
+typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 10 {{declared here}}
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
 struct __attribute__((deprecated, 
-                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{declared here}}
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 
@@ -102,7 +102,7 @@
         test19;
 
 // rdar://problem/8518751
-enum __attribute__((deprecated)) Test20 {
+enum __attribute__((deprecated)) Test20 { // expected-note {{declared here}}
   test20_a __attribute__((deprecated)), // expected-note {{declared here}}
   test20_b // expected-note {{declared here}}
 };
diff --git a/test/Sema/attr-unavailable-message.c b/test/Sema/attr-unavailable-message.c
index 745ef14..9710496 100644
--- a/test/Sema/attr-unavailable-message.c
+++ b/test/Sema/attr-unavailable-message.c
@@ -29,7 +29,7 @@
 
 // rdar://10201690
 enum foo {
-    a = 1,
+    a = 1, // expected-note {{declared here}}
     b __attribute__((deprecated())) = 2, // expected-note {{declared here}}
     c = 3
 }__attribute__((deprecated()));  
diff --git a/test/Sema/typeof-use-deprecated.c b/test/Sema/typeof-use-deprecated.c
index 238e501..1518c83 100644
--- a/test/Sema/typeof-use-deprecated.c
+++ b/test/Sema/typeof-use-deprecated.c
@@ -1,25 +1,25 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}}
+struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}} expected-note 2 {{'s' declared here}}
 
 typeof(x) y;  // expected-warning {{'s' is deprecated}}
 
-union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}}
+union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}} expected-note 2 {{'un' declared here}}
 
 typeof(     u) z; // expected-warning {{'un' is deprecated}}
 
-enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} 
+enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} expected-note 2 {{'E' declared here}}
 
 typeof( e) w; // expected-warning {{'E' is deprecated}}
 
-struct foo { int x; } __attribute__((deprecated));
-typedef struct foo bar __attribute__((deprecated));
+struct foo { int x; } __attribute__((deprecated)); // expected-note {{'foo' declared here}}
+typedef struct foo bar __attribute__((deprecated)); // expected-note {{'bar' declared here}}
 bar x1;	// expected-warning {{'bar' is deprecated}}
 
 int main() { typeof(x1) y; }	// expected-warning {{'foo' is deprecated}}
 
 struct gorf { int x; };
-typedef struct gorf T __attribute__((deprecated));
+typedef struct gorf T __attribute__((deprecated));  // expected-note {{'T' declared here}}
 T t;	// expected-warning {{'T' is deprecated}}
 void wee() { typeof(t) y; }
 
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index 2d9624e..f3d818a 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -163,7 +163,7 @@
 
 namespace test5 {
   struct A {
-    operator int() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+    operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
     operator long();
   };
   void test1(A a) {
diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m
index a2414c4..b2aecc2 100644
--- a/test/SemaObjC/protocol-attribute.m
+++ b/test/SemaObjC/protocol-attribute.m
@@ -6,7 +6,7 @@
 Class <FwProto> cFw = 0;  // expected-error {{'FwProto' is unavailable}}
 
 
-__attribute ((deprecated)) @protocol MyProto1 // expected-note 5 {{declared here}}
+__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{declared here}}
 @end
 
 @protocol Proto2  <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}