xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/Availability.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- Availability.h - Classes for availability --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This files defines some classes that implement availability checking.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_AVAILABILITY_H
140b57cec5SDimitry Andric #define LLVM_CLANG_AST_AVAILABILITY_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
17*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallString.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/Support/VersionTuple.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace clang {
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric /// One specifier in an @available expression.
240b57cec5SDimitry Andric ///
250b57cec5SDimitry Andric /// \code
260b57cec5SDimitry Andric ///   @available(macos 10.10, *)
270b57cec5SDimitry Andric /// \endcode
280b57cec5SDimitry Andric ///
290b57cec5SDimitry Andric /// Here, 'macos 10.10' and '*' both map to an instance of this type.
300b57cec5SDimitry Andric ///
310b57cec5SDimitry Andric class AvailabilitySpec {
320b57cec5SDimitry Andric   /// Represents the version that this specifier requires. If the host OS
330b57cec5SDimitry Andric   /// version is greater than or equal to Version, the @available will evaluate
340b57cec5SDimitry Andric   /// to true.
350b57cec5SDimitry Andric   VersionTuple Version;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   /// Name of the platform that Version corresponds to.
380b57cec5SDimitry Andric   StringRef Platform;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   SourceLocation BeginLoc, EndLoc;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric public:
AvailabilitySpec(VersionTuple Version,StringRef Platform,SourceLocation BeginLoc,SourceLocation EndLoc)430b57cec5SDimitry Andric   AvailabilitySpec(VersionTuple Version, StringRef Platform,
440b57cec5SDimitry Andric                    SourceLocation BeginLoc, SourceLocation EndLoc)
450b57cec5SDimitry Andric       : Version(Version), Platform(Platform), BeginLoc(BeginLoc),
460b57cec5SDimitry Andric         EndLoc(EndLoc) {}
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   /// This constructor is used when representing the '*' case.
AvailabilitySpec(SourceLocation StarLoc)490b57cec5SDimitry Andric   AvailabilitySpec(SourceLocation StarLoc)
500b57cec5SDimitry Andric       : BeginLoc(StarLoc), EndLoc(StarLoc) {}
510b57cec5SDimitry Andric 
getVersion()520b57cec5SDimitry Andric   VersionTuple getVersion() const { return Version; }
getPlatform()530b57cec5SDimitry Andric   StringRef getPlatform() const { return Platform; }
getBeginLoc()540b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return BeginLoc; }
getEndLoc()550b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return EndLoc; }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   /// Returns true when this represents the '*' case.
isOtherPlatformSpec()580b57cec5SDimitry Andric   bool isOtherPlatformSpec() const { return Version.empty(); }
590b57cec5SDimitry Andric };
600b57cec5SDimitry Andric 
61*0fca6ea1SDimitry Andric class Decl;
62*0fca6ea1SDimitry Andric 
63*0fca6ea1SDimitry Andric /// Storage of availability attributes for a declaration.
64*0fca6ea1SDimitry Andric struct AvailabilityInfo {
65*0fca6ea1SDimitry Andric   /// The domain is the platform for which this availability info applies to.
66*0fca6ea1SDimitry Andric   llvm::SmallString<32> Domain;
67*0fca6ea1SDimitry Andric   VersionTuple Introduced;
68*0fca6ea1SDimitry Andric   VersionTuple Deprecated;
69*0fca6ea1SDimitry Andric   VersionTuple Obsoleted;
70*0fca6ea1SDimitry Andric   bool Unavailable = false;
71*0fca6ea1SDimitry Andric   bool UnconditionallyDeprecated = false;
72*0fca6ea1SDimitry Andric   bool UnconditionallyUnavailable = false;
73*0fca6ea1SDimitry Andric 
74*0fca6ea1SDimitry Andric   AvailabilityInfo() = default;
75*0fca6ea1SDimitry Andric 
76*0fca6ea1SDimitry Andric   /// Determine if this AvailabilityInfo represents the default availability.
isDefaultAvailabilityInfo77*0fca6ea1SDimitry Andric   bool isDefault() const { return *this == AvailabilityInfo(); }
78*0fca6ea1SDimitry Andric 
79*0fca6ea1SDimitry Andric   /// Check if the symbol has been obsoleted.
isObsoletedAvailabilityInfo80*0fca6ea1SDimitry Andric   bool isObsoleted() const { return !Obsoleted.empty(); }
81*0fca6ea1SDimitry Andric 
82*0fca6ea1SDimitry Andric   /// Check if the symbol is unavailable unconditionally or
83*0fca6ea1SDimitry Andric   /// on the active platform and os version.
isUnavailableAvailabilityInfo84*0fca6ea1SDimitry Andric   bool isUnavailable() const {
85*0fca6ea1SDimitry Andric     return Unavailable || isUnconditionallyUnavailable();
86*0fca6ea1SDimitry Andric   }
87*0fca6ea1SDimitry Andric 
88*0fca6ea1SDimitry Andric   /// Check if the symbol is unconditionally deprecated.
89*0fca6ea1SDimitry Andric   ///
90*0fca6ea1SDimitry Andric   /// i.e. \code __attribute__((deprecated)) \endcode
isUnconditionallyDeprecatedAvailabilityInfo91*0fca6ea1SDimitry Andric   bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; }
92*0fca6ea1SDimitry Andric 
93*0fca6ea1SDimitry Andric   /// Check if the symbol is unconditionally unavailable.
94*0fca6ea1SDimitry Andric   ///
95*0fca6ea1SDimitry Andric   /// i.e. \code __attribute__((unavailable)) \endcode
isUnconditionallyUnavailableAvailabilityInfo96*0fca6ea1SDimitry Andric   bool isUnconditionallyUnavailable() const {
97*0fca6ea1SDimitry Andric     return UnconditionallyUnavailable;
98*0fca6ea1SDimitry Andric   }
99*0fca6ea1SDimitry Andric 
AvailabilityInfoAvailabilityInfo100*0fca6ea1SDimitry Andric   AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
101*0fca6ea1SDimitry Andric                    VersionTuple O, bool U, bool UD, bool UU)
102*0fca6ea1SDimitry Andric       : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
103*0fca6ea1SDimitry Andric         Unavailable(U), UnconditionallyDeprecated(UD),
104*0fca6ea1SDimitry Andric         UnconditionallyUnavailable(UU) {}
105*0fca6ea1SDimitry Andric 
106*0fca6ea1SDimitry Andric   friend bool operator==(const AvailabilityInfo &Lhs,
107*0fca6ea1SDimitry Andric                          const AvailabilityInfo &Rhs);
108*0fca6ea1SDimitry Andric 
109*0fca6ea1SDimitry Andric public:
110*0fca6ea1SDimitry Andric   static AvailabilityInfo createFromDecl(const Decl *Decl);
111*0fca6ea1SDimitry Andric };
112*0fca6ea1SDimitry Andric 
113*0fca6ea1SDimitry Andric inline bool operator==(const AvailabilityInfo &Lhs,
114*0fca6ea1SDimitry Andric                        const AvailabilityInfo &Rhs) {
115*0fca6ea1SDimitry Andric   return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted,
116*0fca6ea1SDimitry Andric                   Lhs.Unavailable, Lhs.UnconditionallyDeprecated,
117*0fca6ea1SDimitry Andric                   Lhs.UnconditionallyUnavailable) ==
118*0fca6ea1SDimitry Andric          std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted,
119*0fca6ea1SDimitry Andric                   Rhs.Unavailable, Rhs.UnconditionallyDeprecated,
120*0fca6ea1SDimitry Andric                   Rhs.UnconditionallyUnavailable);
121*0fca6ea1SDimitry Andric }
122*0fca6ea1SDimitry Andric 
1230b57cec5SDimitry Andric } // end namespace clang
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric #endif
126