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: AvailabilitySpec(VersionTuple Version,StringRef Platform,SourceLocation BeginLoc,SourceLocation EndLoc)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. AvailabilitySpec(SourceLocation StarLoc)49 AvailabilitySpec(SourceLocation StarLoc) 50 : BeginLoc(StarLoc), EndLoc(StarLoc) {} 51 getVersion()52 VersionTuple getVersion() const { return Version; } getPlatform()53 StringRef getPlatform() const { return Platform; } getBeginLoc()54 SourceLocation getBeginLoc() const { return BeginLoc; } getEndLoc()55 SourceLocation getEndLoc() const { return EndLoc; } 56 57 /// Returns true when this represents the '*' case. isOtherPlatformSpec()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. isDefaultAvailabilityInfo77 bool isDefault() const { return *this == AvailabilityInfo(); } 78 79 /// Check if the symbol has been obsoleted. isObsoletedAvailabilityInfo80 bool isObsoleted() const { return !Obsoleted.empty(); } 81 82 /// Check if the symbol is unavailable unconditionally or 83 /// on the active platform and os version. isUnavailableAvailabilityInfo84 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 isUnconditionallyDeprecatedAvailabilityInfo91 bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; } 92 93 /// Check if the symbol is unconditionally unavailable. 94 /// 95 /// i.e. \code __attribute__((unavailable)) \endcode isUnconditionallyUnavailableAvailabilityInfo96 bool isUnconditionallyUnavailable() const { 97 return UnconditionallyUnavailable; 98 } 99 AvailabilityInfoAvailabilityInfo100 AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D, 101 VersionTuple O, bool U, bool UD, bool UU) 102 : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O), 103 Unavailable(U), UnconditionallyDeprecated(UD), 104 UnconditionallyUnavailable(UU) {} 105 106 friend bool operator==(const AvailabilityInfo &Lhs, 107 const AvailabilityInfo &Rhs); 108 109 public: 110 static AvailabilityInfo createFromDecl(const Decl *Decl); 111 }; 112 113 inline bool operator==(const AvailabilityInfo &Lhs, 114 const AvailabilityInfo &Rhs) { 115 return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted, 116 Lhs.Unavailable, Lhs.UnconditionallyDeprecated, 117 Lhs.UnconditionallyUnavailable) == 118 std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted, 119 Rhs.Unavailable, Rhs.UnconditionallyDeprecated, 120 Rhs.UnconditionallyUnavailable); 121 } 122 123 } // end namespace clang 124 125 #endif 126