[cfe-commits] r128329 - in /cfe/trunk: include/clang/Basic/Attr.td include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h include/clang/Sema/AttributeList.h lib/AST/DeclBase.cpp lib/Parse/ParseDecl.cpp lib/Parse/Parser.cpp lib/Sema/SemaDeclAttr.cpp test/Parser/attr-availability.c test/Sema/attr-availability-macosx.c

Douglas Gregor dgregor at apple.com
Fri Mar 25 20:35:55 PDT 2011


Author: dgregor
Date: Fri Mar 25 22:35:55 2011
New Revision: 128329

URL: http://llvm.org/viewvc/llvm-project?rev=128329&view=rev
Log:
Extend the new 'availability' attribute with support for an
'unavailable' argument, which specifies that the declaration to which
the attribute appertains is unavailable on that platform.

Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Parser/attr-availability.c
    cfe/trunk/test/Sema/attr-availability-macosx.c

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Fri Mar 25 22:35:55 2011
@@ -46,6 +46,7 @@
   string Name = name;
 }
 
+class BoolArgument<string name> : Argument<name>;
 class IdentifierArgument<string name> : Argument<name>;
 class IntArgument<string name> : Argument<name>;
 class StringArgument<string name> : Argument<name>;
@@ -140,7 +141,8 @@
 def Availability : InheritableAttr {
   let Spellings = ["availability"];
   let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
-              VersionArgument<"deprecated">, VersionArgument<"obsoleted">];
+              VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
+              BoolArgument<"unavailable">];
   let AdditionalMembers =
 [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
     return llvm::StringSwitch<llvm::StringRef>(Platform)

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Mar 25 22:35:55 2011
@@ -445,6 +445,8 @@
   "'obsoleted'">;
 def err_availability_redundant : Error<
   "redundant %0 availability change; only the last specified change will "        "be used">;
+def warn_availability_and_unavailable : Warning<
+  "'unavailable' availability overrides all other availability information">;
 
 // Language specific pragmas
 // - Generic warnings

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Mar 25 22:35:55 2011
@@ -121,6 +121,9 @@
   /// \brief Identifier for "obsoleted".
   IdentifierInfo *Ident_obsoleted;
 
+  /// \brief Identifier for "unavailable".
+  IdentifierInfo *Ident_unavailable;
+
   /// C++0x contextual keywords. 
   mutable IdentifierInfo *Ident_final;
   mutable IdentifierInfo *Ident_override;

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Fri Mar 25 22:35:55 2011
@@ -62,20 +62,24 @@
 
   /// The number of expression arguments this attribute has.
   /// The expressions themselves are stored after the object.
-  unsigned NumArgs;
+  unsigned NumArgs : 16;
 
   /// True if Microsoft style: declspec(foo).
-  bool DeclspecAttribute;
+  unsigned DeclspecAttribute : 1;
 
   /// True if C++0x-style: [[foo]].
-  bool CXX0XAttribute;
+  unsigned CXX0XAttribute : 1;
 
   /// True if already diagnosed as invalid.
-  mutable bool Invalid;
+  mutable unsigned Invalid : 1;
 
   /// True if this has the extra information associated with an
   /// availability attribute.
-  bool IsAvailability;
+  unsigned IsAvailability : 1;
+
+  /// \brief The location of the 'unavailable' keyword in an
+  /// availability attribute.
+  SourceLocation UnavailableLoc;
 
   /// The next attribute in the current position.
   AttributeList *NextInPosition;
@@ -127,11 +131,13 @@
                 const AvailabilityChange &introduced,
                 const AvailabilityChange &deprecated,
                 const AvailabilityChange &obsoleted,
+                SourceLocation unavailable,
                 bool declspec, bool cxx0x)
     : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
       AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
       NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
-      Invalid(false), IsAvailability(true), NextInPosition(0), NextInPool(0) {
+      Invalid(false), IsAvailability(true), UnavailableLoc(unavailable),
+      NextInPosition(0), NextInPool(0) {
     new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
     new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
     new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
@@ -315,6 +321,11 @@
     assert(getKind() == AT_availability && "Not an availability attribute");
     return getAvailabilitySlot(ObsoletedSlot);
   }
+
+  SourceLocation getUnavailableLoc() const {
+    assert(getKind() == AT_availability && "Not an availability attribute");
+    return UnavailableLoc;
+  }
 };
 
 /// A factory, from which one makes pools, from which one creates
@@ -435,12 +446,14 @@
                         const AvailabilityChange &introduced,
                         const AvailabilityChange &deprecated,
                         const AvailabilityChange &obsoleted,
+                        SourceLocation unavailable,
                         bool declspec = false, bool cxx0x = false) {
     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
     return add(new (memory) AttributeList(attrName, attrLoc,
                                           scopeName, scopeLoc,
                                           parmName, parmLoc,
                                           introduced, deprecated, obsoleted,
+                                          unavailable,
                                           declspec, cxx0x));
   }
 
@@ -557,10 +570,12 @@
                         const AvailabilityChange &introduced,
                         const AvailabilityChange &deprecated,
                         const AvailabilityChange &obsoleted,
+                        SourceLocation unavailable,
                         bool declspec = false, bool cxx0x = false) {
     AttributeList *attr =
       pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc,
-                  introduced, deprecated, obsoleted, declspec, cxx0x);
+                  introduced, deprecated, obsoleted, unavailable,
+                  declspec, cxx0x);
     add(attr);
     return attr;
   }

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Mar 25 22:35:55 2011
@@ -268,6 +268,17 @@
   if (A->getPlatform()->getName() != TargetPlatform)
     return AR_Available;
 
+  // Make sure that this declaration has not been marked 'unavailable'.
+  if (A->getUnavailable()) {
+    if (Message) {
+      Message->clear();
+      llvm::raw_string_ostream Out(*Message);
+      Out << "not available on " << PrettyPlatformName;
+    }
+
+    return AR_Unavailable;
+  }
+
   // Make sure that this declaration has already been introduced.
   if (!A->getIntroduced().empty() && 
       TargetMinVersion < A->getIntroduced()) {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Mar 25 22:35:55 2011
@@ -484,6 +484,7 @@
 ///   'introduced' '=' version
 ///   'deprecated' '=' version
 ///   'removed' = version
+///   'unavailable'
 void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
                                         SourceLocation AvailabilityLoc,
                                         ParsedAttributes &attrs,
@@ -521,9 +522,11 @@
     Ident_introduced = PP.getIdentifierInfo("introduced");
     Ident_deprecated = PP.getIdentifierInfo("deprecated");
     Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
+    Ident_unavailable = PP.getIdentifierInfo("unavailable");
   }
 
   // Parse the set of introductions/deprecations/removals.
+  SourceLocation UnavailableLoc;
   do {
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_availability_expected_change);
@@ -533,6 +536,20 @@
     IdentifierInfo *Keyword = Tok.getIdentifierInfo();
     SourceLocation KeywordLoc = ConsumeToken();
 
+    if (Keyword == Ident_unavailable) {
+      if (UnavailableLoc.isValid()) {
+        Diag(KeywordLoc, diag::err_availability_redundant)
+          << Keyword << SourceRange(UnavailableLoc);
+      } 
+      UnavailableLoc = KeywordLoc;
+
+      if (Tok.isNot(tok::comma))
+        break;
+
+      ConsumeToken();
+      continue;
+    } 
+
     if (Tok.isNot(tok::equal)) {
       Diag(Tok, diag::err_expected_equal_after)
         << Keyword;
@@ -589,13 +606,33 @@
   if (endLoc)
     *endLoc = RParenLoc;
 
+  // The 'unavailable' availability cannot be combined with any other
+  // availability changes. Make sure that hasn't happened.
+  if (UnavailableLoc.isValid()) {
+    bool Complained = false;
+    for (unsigned Index = Introduced; Index != Unknown; ++Index) {
+      if (Changes[Index].KeywordLoc.isValid()) {
+        if (!Complained) {
+          Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
+            << SourceRange(Changes[Index].KeywordLoc,
+                           Changes[Index].VersionRange.getEnd());
+          Complained = true;
+        }
+
+        // Clear out the availability.
+        Changes[Index] = AvailabilityChange();
+      }
+    }
+  }
+
   // Record this attribute
-  attrs.addNew(&Availability, AvailabilityLoc,
+  attrs.addNew(&Availability, AvailabilityLoc, 
                0, SourceLocation(),
                Platform, PlatformLoc,
                Changes[Introduced],
                Changes[Deprecated],
-               Changes[Obsoleted], false, false);
+               Changes[Obsoleted], 
+               UnavailableLoc, false, false);
 }
 
 void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Fri Mar 25 22:35:55 2011
@@ -426,6 +426,7 @@
   Ident_introduced = 0;
   Ident_deprecated = 0;
   Ident_obsoleted = 0;
+  Ident_unavailable = 0;
 }
 
 /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Mar 25 22:35:55 2011
@@ -1091,6 +1091,7 @@
   AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
   AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
   AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
+  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
 
   // Ensure that Introduced < Deprecated < Obsoleted (although not all
   // of these steps are needed).
@@ -1122,7 +1123,8 @@
                                                 Platform,
                                                 Introduced.Version,
                                                 Deprecated.Version,
-                                                Obsoleted.Version));
+                                                Obsoleted.Version,
+                                                IsUnavailable));
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {

Modified: cfe/trunk/test/Parser/attr-availability.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/attr-availability.c?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/test/Parser/attr-availability.c (original)
+++ cfe/trunk/test/Parser/attr-availability.c Fri Mar 25 22:35:55 2011
@@ -7,3 +7,9 @@
 
 void f3() __attribute__((availability(ios,deprecated=10.4.7,introduced=10,obsoleted=10.6,introduced=10.2))); // expected-error{{redundant 'introduced' availability change; only the last specified change will be used}}
 
+void f4() __attribute__((availability(macosx,introduced=10.5), availability(ios,unavailable)));
+
+void f5() __attribute__((availability(macosx,introduced=10.5), availability(ios,unavailable, unavailable))); // expected-error{{redundant 'unavailable' availability change; only the last specified change will be used}}
+
+void f6() __attribute__((availability(macosx,unavailable,introduced=10.5))); // expected-warning{{warning: 'unavailable' availability overrides all other availability information}}
+

Modified: cfe/trunk/test/Sema/attr-availability-macosx.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-availability-macosx.c?rev=128329&r1=128328&r2=128329&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-availability-macosx.c (original)
+++ cfe/trunk/test/Sema/attr-availability-macosx.c Fri Mar 25 22:35:55 2011
@@ -5,6 +5,7 @@
 void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5)));
 void f3(int) __attribute__((availability(macosx,introduced=10.6)));
 void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}}
+void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{function has been explicitly marked unavailable here}}
 
 void test() {
   f0(0);
@@ -12,4 +13,5 @@
   f2(0); // expected-warning{{'f2' is deprecated: first deprecated in Mac OS X 10.5}}
   f3(0);
   f4(0); // expected-error{{f4' is unavailable: obsoleted in Mac OS X 10.5}}
+  f5(0); // expected-error{{'f5' is unavailable: not available on Mac OS X}}
 }





More information about the cfe-commits mailing list