arphaman created this revision.

The fixit is given only if the `API_AVAILABLE` macro is defined.


Repository:
  rL LLVM

https://reviews.llvm.org/D35726

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/FixIt/fixit-availability.c
  test/FixIt/fixit-availability.mm


Index: test/FixIt/fixit-availability.mm
===================================================================
--- test/FixIt/fixit-availability.mm
+++ test/FixIt/fixit-availability.mm
@@ -109,3 +109,21 @@
   anotherFunction(y);
   anotherFunction(x);
 }
+
+#define API_AVAILABLE(X) __attribute__((availability(macos, 
introduced=10.12))) // dummy macro
+
+API_AVAILABLE(macos(10.12))
+@interface NewClass
+@end
+
+@interface OldButOfferFixit
+@property(copy) NewClass *prop;
+// CHECK: 
fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"API_AVAILABLE(macos(10.12))\n"
+@end
+
+// Avoid a fixit for declarations that already have an attribute:
+__attribute__((availability(macos, introduced=10.11)))
+@interface WithoutFixit
+@property(copy) NewClass *prop;
+// CHECK-NOT: API_AVAILABLE
+@end
Index: test/FixIt/fixit-availability.c
===================================================================
--- test/FixIt/fixit-availability.c
+++ test/FixIt/fixit-availability.c
@@ -8,3 +8,11 @@
 // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if 
(__builtin_available(macOS 10.12, *)) {\n      "
 // CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n   
   // Fallback on earlier versions\n  }"
 }
+
+__attribute__((availability(macos, introduced=10.12)))
+struct New { };
+
+struct NoFixit {
+  struct New field;
+};
+// CHECK-NOT: API_AVAILABLE
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7221,8 +7221,27 @@
               << /*Anonymous*/1 << TD->getKindName();
           return;
         }
-      S.Diag(Enclosing->getLocation(), diag::note_partial_availability_silence)
-          << /*Named*/0 << Enclosing;
+      auto FixitNoteDiag = S.Diag(Enclosing->getLocation(),
+                                  diag::note_partial_availability_silence)
+                           << /*Named*/ 0 << Enclosing;
+      // Don't offer a fixit for declarations with availability attributes.
+      if (Enclosing->hasAttr<AvailabilityAttr>())
+        return;
+      for (const auto &M : S.getPreprocessor().macros()) {
+        if (M.first->getName() != "API_AVAILABLE")
+          continue;
+        std::string PlatformName =
+            AvailabilityAttr::getPlatformNameSourceSpelling(
+                S.getASTContext().getTargetInfo().getPlatformName())
+                .lower();
+        std::string Introduced =
+            ReferringDecl->getVersionIntroduced().getAsString();
+        FixitNoteDiag << FixItHint::CreateInsertion(
+            Enclosing->getLocStart(), (llvm::Twine("API_AVAILABLE(") +
+                                       PlatformName + "(" + Introduced + 
"))\n")
+                                          .str());
+        break;
+      }
     }
 }
 


Index: test/FixIt/fixit-availability.mm
===================================================================
--- test/FixIt/fixit-availability.mm
+++ test/FixIt/fixit-availability.mm
@@ -109,3 +109,21 @@
   anotherFunction(y);
   anotherFunction(x);
 }
+
+#define API_AVAILABLE(X) __attribute__((availability(macos, introduced=10.12))) // dummy macro
+
+API_AVAILABLE(macos(10.12))
+@interface NewClass
+@end
+
+@interface OldButOfferFixit
+@property(copy) NewClass *prop;
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"API_AVAILABLE(macos(10.12))\n"
+@end
+
+// Avoid a fixit for declarations that already have an attribute:
+__attribute__((availability(macos, introduced=10.11)))
+@interface WithoutFixit
+@property(copy) NewClass *prop;
+// CHECK-NOT: API_AVAILABLE
+@end
Index: test/FixIt/fixit-availability.c
===================================================================
--- test/FixIt/fixit-availability.c
+++ test/FixIt/fixit-availability.c
@@ -8,3 +8,11 @@
 // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macOS 10.12, *)) {\n      "
 // CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
 }
+
+__attribute__((availability(macos, introduced=10.12)))
+struct New { };
+
+struct NoFixit {
+  struct New field;
+};
+// CHECK-NOT: API_AVAILABLE
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7221,8 +7221,27 @@
               << /*Anonymous*/1 << TD->getKindName();
           return;
         }
-      S.Diag(Enclosing->getLocation(), diag::note_partial_availability_silence)
-          << /*Named*/0 << Enclosing;
+      auto FixitNoteDiag = S.Diag(Enclosing->getLocation(),
+                                  diag::note_partial_availability_silence)
+                           << /*Named*/ 0 << Enclosing;
+      // Don't offer a fixit for declarations with availability attributes.
+      if (Enclosing->hasAttr<AvailabilityAttr>())
+        return;
+      for (const auto &M : S.getPreprocessor().macros()) {
+        if (M.first->getName() != "API_AVAILABLE")
+          continue;
+        std::string PlatformName =
+            AvailabilityAttr::getPlatformNameSourceSpelling(
+                S.getASTContext().getTargetInfo().getPlatformName())
+                .lower();
+        std::string Introduced =
+            ReferringDecl->getVersionIntroduced().getAsString();
+        FixitNoteDiag << FixItHint::CreateInsertion(
+            Enclosing->getLocStart(), (llvm::Twine("API_AVAILABLE(") +
+                                       PlatformName + "(" + Introduced + "))\n")
+                                          .str());
+        break;
+      }
     }
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to