1 //===--- Availability.h - Classes for availability --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This files defines some classes that implement availability checking. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_AVAILABILITY_H 14 #define LLVM_CLANG_AST_AVAILABILITY_H 15 16 #include "clang/Basic/SourceLocation.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Support/VersionTuple.h" 20 21 namespace clang { 22 23 /// One specifier in an @available expression. 24 /// 25 /// \code 26 /// @available(macos 10.10, *) 27 /// \endcode 28 /// 29 /// Here, 'macos 10.10' and '*' both map to an instance of this type. 30 /// 31 class AvailabilitySpec { 32 /// Represents the version that this specifier requires. If the host OS 33 /// version is greater than or equal to Version, the @available will evaluate 34 /// to true. 35 VersionTuple Version; 36 37 /// Name of the platform that Version corresponds to. 38 StringRef Platform; 39 40 SourceLocation BeginLoc, EndLoc; 41 42 public: 43 AvailabilitySpec(VersionTuple Version, StringRef Platform, 44 SourceLocation BeginLoc, SourceLocation EndLoc) 45 : Version(Version), Platform(Platform), BeginLoc(BeginLoc), 46 EndLoc(EndLoc) {} 47 48 /// This constructor is used when representing the '*' case. 49 AvailabilitySpec(SourceLocation StarLoc) 50 : BeginLoc(StarLoc), EndLoc(StarLoc) {} 51 52 VersionTuple getVersion() const { return Version; } 53 StringRef getPlatform() const { return Platform; } 54 SourceLocation getBeginLoc() const { return BeginLoc; } 55 SourceLocation getEndLoc() const { return EndLoc; } 56 57 /// Returns true when this represents the '*' case. 58 bool isOtherPlatformSpec() const { return Version.empty(); } 59 }; 60 61 class Decl; 62 63 /// Storage of availability attributes for a declaration. 64 struct AvailabilityInfo { 65 /// The domain is the platform for which this availability info applies to. 66 llvm::SmallString<32> Domain; 67 VersionTuple Introduced; 68 VersionTuple Deprecated; 69 VersionTuple Obsoleted; 70 bool Unavailable = false; 71 bool UnconditionallyDeprecated = false; 72 bool UnconditionallyUnavailable = false; 73 74 AvailabilityInfo() = default; 75 76 /// Determine if this AvailabilityInfo represents the default availability. 77 bool isDefault() const { return *this == AvailabilityInfo(); } 78 79 /// Check if the symbol has been obsoleted. 80 bool isObsoleted() const { return !Obsoleted.empty(); } 81 82 /// Check if the symbol is unavailable unconditionally or 83 /// on the active platform and os version. 84 bool isUnavailable() const { 85 return Unavailable || isUnconditionallyUnavailable(); 86 } 87 88 /// Check if the symbol is unconditionally deprecated. 89 /// 90 /// i.e. \code __attribute__((deprecated)) \endcode 91 bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; } 92 93 /// Check if the symbol is unconditionally unavailable. 94 /// 95 /// i.e. \code __attribute__((unavailable)) \endcode 96 bool isUnconditionallyUnavailable() const { 97 return UnconditionallyUnavailable; 98 } 99 100 /// Augments the existing information with additional constraints provided by 101 /// \c Other. 102 void mergeWith(AvailabilityInfo Other); 103 104 AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D, 105 VersionTuple O, bool U, bool UD, bool UU) 106 : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O), 107 Unavailable(U), UnconditionallyDeprecated(UD), 108 UnconditionallyUnavailable(UU) {} 109 110 friend bool operator==(const AvailabilityInfo &Lhs, 111 const AvailabilityInfo &Rhs); 112 113 public: 114 static AvailabilityInfo createFromDecl(const Decl *Decl); 115 }; 116 117 inline bool operator==(const AvailabilityInfo &Lhs, 118 const AvailabilityInfo &Rhs) { 119 return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted, 120 Lhs.Unavailable, Lhs.UnconditionallyDeprecated, 121 Lhs.UnconditionallyUnavailable) == 122 std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted, 123 Rhs.Unavailable, Rhs.UnconditionallyDeprecated, 124 Rhs.UnconditionallyUnavailable); 125 } 126 127 } // end namespace clang 128 129 #endif 130