]> granicus.if.org Git - clang/commitdiff
Use dotted format of version tuple for availability diagnostics
authorJan Korous <jkorous@apple.com>
Thu, 17 May 2018 11:51:49 +0000 (11:51 +0000)
committerJan Korous <jkorous@apple.com>
Thu, 17 May 2018 11:51:49 +0000 (11:51 +0000)
E. g. use "10.11" instead of "10_11".

We are maintaining backward compatibility by parsing underscore-delimited version tuples but no longer keep track of the separator and using dot format for output.

Differential Revision: https://reviews.llvm.org/D46747

rdar://problem/39845032

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@332598 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/VersionTuple.h
lib/AST/DeclBase.cpp
lib/Basic/VersionTuple.cpp
lib/Parse/ParseDecl.cpp
test/Misc/ast-print-objectivec.m
test/Sema/availability-guard-format.mm [new file with mode: 0644]
test/SemaObjC/attr-availability-1.m

index fad77f2d32b8e375aaee101f53da35d05a4d82c8..e7385b0b3bd33e6b1603d0ffde848bc19e0c9cdf 100644 (file)
@@ -24,9 +24,7 @@ namespace clang {
 
 /// Represents a version number in the form major[.minor[.subminor[.build]]].
 class VersionTuple {
-  unsigned Major : 31;
-
-  unsigned UsesUnderscores : 1;
+  unsigned Major : 32;
 
   unsigned Minor : 31;
   unsigned HasMinor : 1;
@@ -39,30 +37,25 @@ class VersionTuple {
 
 public:
   VersionTuple()
-      : Major(0), UsesUnderscores(false), Minor(0), HasMinor(false),
-        Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
+      : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
+        Build(0), HasBuild(false) {}
 
   explicit VersionTuple(unsigned Major)
-      : Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false),
-        Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
+      : Major(Major), Minor(0), HasMinor(false), Subminor(0),
+        HasSubminor(false), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor,
-                        bool UsesUnderscores = false)
-      : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-        HasMinor(true), Subminor(0), HasSubminor(false), Build(0),
-        HasBuild(false) {}
+  explicit VersionTuple(unsigned Major, unsigned Minor)
+      : Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
+        HasSubminor(false), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
-                        bool UsesUnderscores = false)
-      : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-        HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0),
-        HasBuild(false) {}
+  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
+      : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
+        HasSubminor(true), Build(0), HasBuild(false) {}
 
   explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
-                        unsigned Build, bool UsesUnderscores = false)
-      : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
-        HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build),
-        HasBuild(true) {}
+                        unsigned Build)
+      : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
+        HasSubminor(true), Build(Build), HasBuild(true) {}
 
   /// Determine whether this version information is empty
   /// (e.g., all version components are zero).
@@ -93,14 +86,6 @@ public:
       return None;
     return Build;
   }
-
-  bool usesUnderscores() const {
-    return UsesUnderscores;
-  }
-
-  void UseDotAsSeparator() {
-    UsesUnderscores = false;
-  }
   
   /// Determine if two version numbers are equivalent. If not
   /// provided, minor and subminor version numbers are considered to be zero.
index 5c8915774f589918324c019fb60e26d4661b62af..51518a7862680051d194fdf626cc0963e86e838a 100644 (file)
@@ -550,7 +550,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
       Message->clear();
       llvm::raw_string_ostream Out(*Message);
       VersionTuple VTI(A->getIntroduced());
-      VTI.UseDotAsSeparator();
       Out << "introduced in " << PrettyPlatformName << ' ' 
           << VTI << HintMessage;
     }
@@ -564,7 +563,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
       Message->clear();
       llvm::raw_string_ostream Out(*Message);
       VersionTuple VTO(A->getObsoleted());
-      VTO.UseDotAsSeparator();
       Out << "obsoleted in " << PrettyPlatformName << ' ' 
           << VTO << HintMessage;
     }
@@ -578,7 +576,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
       Message->clear();
       llvm::raw_string_ostream Out(*Message);
       VersionTuple VTD(A->getDeprecated());
-      VTD.UseDotAsSeparator();
       Out << "first deprecated in " << PrettyPlatformName << ' '
           << VTD << HintMessage;
     }
index 9c73fd98a174c55d52c7f2b04a4e44ac69addc09..7a9176a808e8c8d04667f47fffc24eb3b1d83e0c 100644 (file)
@@ -29,11 +29,11 @@ raw_ostream& clang::operator<<(raw_ostream &Out,
                                      const VersionTuple &V) {
   Out << V.getMajor();
   if (Optional<unsigned> Minor = V.getMinor())
-    Out << (V.usesUnderscores() ? '_' : '.') << *Minor;
+    Out << '.' << *Minor;
   if (Optional<unsigned> Subminor = V.getSubminor())
-    Out << (V.usesUnderscores() ? '_' : '.') << *Subminor;
+    Out << '.' << *Subminor;
   if (Optional<unsigned> Build = V.getBuild())
-    Out << (V.usesUnderscores() ? '_' : '.') << *Build;
+    Out << '.' << *Build;
   return Out;
 }
 
index 385d0fb3e7e8676f486331da07e903cd53606e2e..456214f0668fdd79f1f310f4179017d8f062fb2a 100644 (file)
@@ -762,8 +762,10 @@ static bool VersionNumberSeparator(const char Separator) {
 ///
 /// version:
 ///   simple-integer
-///   simple-integer ',' simple-integer
-///   simple-integer ',' simple-integer ',' simple-integer
+///   simple-integer '.' simple-integer
+///   simple-integer '_' simple-integer
+///   simple-integer '.' simple-integer '.' simple-integer
+///   simple-integer '_' simple-integer '_' simple-integer
 VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
   Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
 
@@ -841,7 +843,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
       return VersionTuple();
     }
 
-    return VersionTuple(Major, Minor, (AfterMajorSeparator == '_'));
+    return VersionTuple(Major, Minor);
   }
 
   const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
@@ -872,7 +874,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
     return VersionTuple();
   }
   ConsumeToken();
-  return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_'));
+  return VersionTuple(Major, Minor, Subminor);
 }
 
 /// Parse the contents of the "availability" attribute.
index cb5aacc06a4962d5970d724b28f6852ae6a79222..eb1b4696105396e15a6f772f23b9e5d0f3aec72e 100644 (file)
@@ -30,7 +30,7 @@
 // CHECK: @end
 
 // CHECK: @interface I(CAT)
-// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
+// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
 // CHECK: @end
 
 // CHECK: @implementation I
diff --git a/test/Sema/availability-guard-format.mm b/test/Sema/availability-guard-format.mm
new file mode 100644 (file)
index 0000000..910de49
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
+
+// Testing that even for source code using '_' as a delimiter in availability version tuple '.' is actually used in diagnostic output as a delimiter.
+
+@interface foo
+- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
+@end
+
+int main() {
+    [foo method_bar]; // \
+    // expected-warning {{'method_bar' is only available on macOS 10.12 or newer}} \
+    // expected-note {{enclose 'method_bar' in an @available check to silence this warning}} \
+    // CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
+    return 0;
+}
index d3d40003785309db98cc2bbb523e6d0b719e2bf7..cd7968fc7294da25d22bd12f23f24fb8684df293 100644 (file)
 // rdar://11475360
 @interface B : A
 - (void)method; // NOTE: we expect 'method' to *not* inherit availability.
-- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10_4 vs. 10_3)}}
+- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
 - (void)overridden2 __attribute__((availability(macosx,introduced=10_2)));
 - (void)overridden3 __attribute__((availability(macosx,deprecated=10_4)));
-- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10_3 vs. 10_2)}}
+- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
 - (void)overridden5 __attribute__((availability(macosx,introduced=10_3)));
 - (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
 @end