summaryrefslogtreecommitdiffstats
path: root/include/clang/Sema/AttributeList.h
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-23 00:50:03 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-23 00:50:03 +0000
commit0a0d2b179085a52c10402feebeb6db8b4d96a140 (patch)
treee97aeca336472a81235e8bd034f648b034094e81 /include/clang/Sema/AttributeList.h
parent9a8ad9b28d54a3adc4cb8061d564f99f80144e30 (diff)
Implement a new 'availability' attribute, that allows one to specify
which versions of an OS provide a certain facility. For example, void foo() __attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6))); says that the function "foo" was introduced in 10.2, deprecated in 10.4, and completely obsoleted in 10.6. This attribute ties in with the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that we want to deploy back to Mac OS X 10.1). There are several concrete behaviors that this attribute enables, as illustrated with the function foo() above: - If we choose a deployment target >= Mac OS X 10.4, uses of "foo" will result in a deprecation warning, as if we had placed attribute((deprecated)) on it (but with a better diagnostic) - If we choose a deployment target >= Mac OS X 10.6, uses of "foo" will result in an "unavailable" warning (in C)/error (in C++), as if we had placed attribute((unavailable)) on it - If we choose a deployment target prior to 10.2, foo() is weak-imported (if it is a kind of entity that can be weak imported), as if we had placed the weak_import attribute on it. Naturally, there can be multiple availability attributes on a declaration, for different platforms; only the current platform matters when checking availability attributes. The only platforms this attribute currently works for are "ios" and "macosx", since we already have -mxxxx-version-min flags for them and we have experience there with macro tricks translating down to the deprecated/unavailable/weak_import attributes. The end goal is to open this up to other platforms, and even extension to other "platforms" that are really libraries (say, through a #pragma clang define_system), but that hasn't yet been designed and we may want to shake out more issues with this narrower problem first. Addresses <rdar://problem/6690412>. As a drive-by bug-fix, if an entity is both deprecated and unavailable, we only emit the "unavailable" diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Sema/AttributeList.h')
-rw-r--r--include/clang/Sema/AttributeList.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 382e50494e..3657b44b02 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -18,6 +18,7 @@
#include "llvm/Support/Allocator.h"
#include "clang/Sema/Ownership.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/VersionTuple.h"
#include "clang/AST/Expr.h"
#include <cassert>
@@ -25,6 +26,23 @@ namespace clang {
class IdentifierInfo;
class Expr;
+/// \brief Represents information about a change in availability for
+/// an entity, which is part of the encoding of the 'availability'
+/// attribute.
+struct AvailabilityChange {
+ /// \brief The location of the keyword indicating the kind of change.
+ SourceLocation KeywordLoc;
+
+ /// \brief The version number at which the change occurred.
+ VersionTuple Version;
+
+ /// \brief The source range covering the version number.
+ SourceRange VersionRange;
+
+ /// \brief Determine whether this availability change is valid.
+ bool isValid() const { return !Version.empty(); }
+};
+
/// AttributeList - Represents GCC's __attribute__ declaration. There are
/// 4 forms of this construct...they are:
///
@@ -48,6 +66,11 @@ private:
AttributeList *Next;
bool DeclspecAttribute, CXX0XAttribute;
+ // For the 'availability' attribute.
+ AvailabilityChange AvailabilityIntroduced;
+ AvailabilityChange AvailabilityDeprecated;
+ AvailabilityChange AvailabilityObsoleted;
+
/// True if already diagnosed as invalid.
mutable bool Invalid;
@@ -61,6 +84,15 @@ private:
IdentifierInfo *ParmName, SourceLocation ParmLoc,
Expr **args, unsigned numargs,
bool declspec, bool cxx0x);
+
+ AttributeList(llvm::BumpPtrAllocator &Alloc,
+ IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ IdentifierInfo *ParmName, SourceLocation ParmLoc,
+ const AvailabilityChange &Introduced,
+ const AvailabilityChange &Deprecated,
+ const AvailabilityChange &Obsoleted,
+ bool declspec, bool cxx0x);
public:
class Factory {
llvm::BumpPtrAllocator Alloc;
@@ -78,6 +110,20 @@ public:
return Mem;
}
+ AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ IdentifierInfo *ParmName, SourceLocation ParmLoc,
+ const AvailabilityChange &Introduced,
+ const AvailabilityChange &Deprecated,
+ const AvailabilityChange &Obsoleted,
+ bool declspec = false, bool cxx0x = false) {
+ AttributeList *Mem = Alloc.Allocate<AttributeList>();
+ new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
+ ParmName, ParmLoc, Introduced, Deprecated,
+ Obsoleted, declspec, cxx0x);
+ return Mem;
+ }
+
AttributeList* CreateIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
SourceLocation TokLoc, int Arg) {
Expr* IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t)Arg),
@@ -96,6 +142,7 @@ public:
AT_always_inline,
AT_analyzer_noreturn,
AT_annotate,
+ AT_availability, // Clang-specific
AT_base_check,
AT_blocks,
AT_carries_dependency,
@@ -244,6 +291,21 @@ public:
arg_iterator arg_end() const {
return arg_iterator(Args, NumArgs);
}
+
+ const AvailabilityChange &getAvailabilityIntroduced() const {
+ assert(getKind() == AT_availability && "Not an availability attribute");
+ return AvailabilityIntroduced;
+ }
+
+ const AvailabilityChange &getAvailabilityDeprecated() const {
+ assert(getKind() == AT_availability && "Not an availability attribute");
+ return AvailabilityDeprecated;
+ }
+
+ const AvailabilityChange &getAvailabilityObsoleted() const {
+ assert(getKind() == AT_availability && "Not an availability attribute");
+ return AvailabilityObsoleted;
+ }
};
/// addAttributeLists - Add two AttributeLists together