Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:27

0001 //===-- Types.h - API Notes Data Types --------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_APINOTES_TYPES_H
0010 #define LLVM_CLANG_APINOTES_TYPES_H
0011 
0012 #include "clang/Basic/Specifiers.h"
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/StringRef.h"
0015 #include <climits>
0016 #include <optional>
0017 #include <vector>
0018 
0019 namespace llvm {
0020 class raw_ostream;
0021 } // namespace llvm
0022 
0023 namespace clang {
0024 namespace api_notes {
0025 enum class RetainCountConventionKind {
0026   None,
0027   CFReturnsRetained,
0028   CFReturnsNotRetained,
0029   NSReturnsRetained,
0030   NSReturnsNotRetained,
0031 };
0032 
0033 /// The payload for an enum_extensibility attribute. This is a tri-state rather
0034 /// than just a boolean because the presence of the attribute indicates
0035 /// auditing.
0036 enum class EnumExtensibilityKind {
0037   None,
0038   Open,
0039   Closed,
0040 };
0041 
0042 /// The kind of a swift_wrapper/swift_newtype.
0043 enum class SwiftNewTypeKind {
0044   None,
0045   Struct,
0046   Enum,
0047 };
0048 
0049 /// Describes API notes data for any entity.
0050 ///
0051 /// This is used as the base of all API notes.
0052 class CommonEntityInfo {
0053 public:
0054   /// Message to use when this entity is unavailable.
0055   std::string UnavailableMsg;
0056 
0057   /// Whether this entity is marked unavailable.
0058   LLVM_PREFERRED_TYPE(bool)
0059   unsigned Unavailable : 1;
0060 
0061   /// Whether this entity is marked unavailable in Swift.
0062   LLVM_PREFERRED_TYPE(bool)
0063   unsigned UnavailableInSwift : 1;
0064 
0065 private:
0066   /// Whether SwiftPrivate was specified.
0067   LLVM_PREFERRED_TYPE(bool)
0068   unsigned SwiftPrivateSpecified : 1;
0069 
0070   /// Whether this entity is considered "private" to a Swift overlay.
0071   LLVM_PREFERRED_TYPE(bool)
0072   unsigned SwiftPrivate : 1;
0073 
0074 public:
0075   /// Swift name of this entity.
0076   std::string SwiftName;
0077 
0078   CommonEntityInfo()
0079       : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
0080         SwiftPrivate(0) {}
0081 
0082   std::optional<bool> isSwiftPrivate() const {
0083     return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
0084                                  : std::nullopt;
0085   }
0086 
0087   void setSwiftPrivate(std::optional<bool> Private) {
0088     SwiftPrivateSpecified = Private.has_value();
0089     SwiftPrivate = Private.value_or(0);
0090   }
0091 
0092   friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
0093 
0094   CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) {
0095     // Merge unavailability.
0096     if (RHS.Unavailable) {
0097       Unavailable = true;
0098       if (UnavailableMsg.empty())
0099         UnavailableMsg = RHS.UnavailableMsg;
0100     }
0101 
0102     if (RHS.UnavailableInSwift) {
0103       UnavailableInSwift = true;
0104       if (UnavailableMsg.empty())
0105         UnavailableMsg = RHS.UnavailableMsg;
0106     }
0107 
0108     if (!SwiftPrivateSpecified)
0109       setSwiftPrivate(RHS.isSwiftPrivate());
0110 
0111     if (SwiftName.empty())
0112       SwiftName = RHS.SwiftName;
0113 
0114     return *this;
0115   }
0116 
0117   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0118 };
0119 
0120 inline bool operator==(const CommonEntityInfo &LHS,
0121                        const CommonEntityInfo &RHS) {
0122   return LHS.UnavailableMsg == RHS.UnavailableMsg &&
0123          LHS.Unavailable == RHS.Unavailable &&
0124          LHS.UnavailableInSwift == RHS.UnavailableInSwift &&
0125          LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
0126          LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName;
0127 }
0128 
0129 inline bool operator!=(const CommonEntityInfo &LHS,
0130                        const CommonEntityInfo &RHS) {
0131   return !(LHS == RHS);
0132 }
0133 
0134 /// Describes API notes for types.
0135 class CommonTypeInfo : public CommonEntityInfo {
0136   /// The Swift type to which a given type is bridged.
0137   ///
0138   /// Reflects the swift_bridge attribute.
0139   std::optional<std::string> SwiftBridge;
0140 
0141   /// The NS error domain for this type.
0142   std::optional<std::string> NSErrorDomain;
0143 
0144 public:
0145   CommonTypeInfo() {}
0146 
0147   const std::optional<std::string> &getSwiftBridge() const {
0148     return SwiftBridge;
0149   }
0150 
0151   void setSwiftBridge(std::optional<std::string> SwiftType) {
0152     SwiftBridge = SwiftType;
0153   }
0154 
0155   const std::optional<std::string> &getNSErrorDomain() const {
0156     return NSErrorDomain;
0157   }
0158 
0159   void setNSErrorDomain(const std::optional<std::string> &Domain) {
0160     NSErrorDomain = Domain;
0161   }
0162 
0163   void setNSErrorDomain(const std::optional<llvm::StringRef> &Domain) {
0164     NSErrorDomain = Domain ? std::optional<std::string>(std::string(*Domain))
0165                            : std::nullopt;
0166   }
0167 
0168   friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
0169 
0170   CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
0171     // Merge inherited info.
0172     static_cast<CommonEntityInfo &>(*this) |= RHS;
0173 
0174     if (!SwiftBridge)
0175       setSwiftBridge(RHS.getSwiftBridge());
0176     if (!NSErrorDomain)
0177       setNSErrorDomain(RHS.getNSErrorDomain());
0178 
0179     return *this;
0180   }
0181 
0182   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0183 };
0184 
0185 inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
0186   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
0187          LHS.SwiftBridge == RHS.SwiftBridge &&
0188          LHS.NSErrorDomain == RHS.NSErrorDomain;
0189 }
0190 
0191 inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
0192   return !(LHS == RHS);
0193 }
0194 
0195 /// Describes API notes data for an Objective-C class or protocol or a C++
0196 /// namespace.
0197 class ContextInfo : public CommonTypeInfo {
0198   /// Whether this class has a default nullability.
0199   LLVM_PREFERRED_TYPE(bool)
0200   unsigned HasDefaultNullability : 1;
0201 
0202   /// The default nullability.
0203   LLVM_PREFERRED_TYPE(NullabilityKind)
0204   unsigned DefaultNullability : 2;
0205 
0206   /// Whether this class has designated initializers recorded.
0207   LLVM_PREFERRED_TYPE(bool)
0208   unsigned HasDesignatedInits : 1;
0209 
0210   LLVM_PREFERRED_TYPE(bool)
0211   unsigned SwiftImportAsNonGenericSpecified : 1;
0212   LLVM_PREFERRED_TYPE(bool)
0213   unsigned SwiftImportAsNonGeneric : 1;
0214 
0215   LLVM_PREFERRED_TYPE(bool)
0216   unsigned SwiftObjCMembersSpecified : 1;
0217   LLVM_PREFERRED_TYPE(bool)
0218   unsigned SwiftObjCMembers : 1;
0219 
0220 public:
0221   ContextInfo()
0222       : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0),
0223         SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false),
0224         SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {}
0225 
0226   /// Determine the default nullability for properties and methods of this
0227   /// class.
0228   ///
0229   /// Returns the default nullability, if implied, or std::nullopt if there is
0230   /// none.
0231   std::optional<NullabilityKind> getDefaultNullability() const {
0232     return HasDefaultNullability
0233                ? std::optional<NullabilityKind>(
0234                      static_cast<NullabilityKind>(DefaultNullability))
0235                : std::nullopt;
0236   }
0237 
0238   /// Set the default nullability for properties and methods of this class.
0239   void setDefaultNullability(NullabilityKind Kind) {
0240     HasDefaultNullability = true;
0241     DefaultNullability = static_cast<unsigned>(Kind);
0242   }
0243 
0244   bool hasDesignatedInits() const { return HasDesignatedInits; }
0245   void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; }
0246 
0247   std::optional<bool> getSwiftImportAsNonGeneric() const {
0248     return SwiftImportAsNonGenericSpecified
0249                ? std::optional<bool>(SwiftImportAsNonGeneric)
0250                : std::nullopt;
0251   }
0252   void setSwiftImportAsNonGeneric(std::optional<bool> Value) {
0253     SwiftImportAsNonGenericSpecified = Value.has_value();
0254     SwiftImportAsNonGeneric = Value.value_or(false);
0255   }
0256 
0257   std::optional<bool> getSwiftObjCMembers() const {
0258     return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers)
0259                                      : std::nullopt;
0260   }
0261   void setSwiftObjCMembers(std::optional<bool> Value) {
0262     SwiftObjCMembersSpecified = Value.has_value();
0263     SwiftObjCMembers = Value.value_or(false);
0264   }
0265 
0266   friend bool operator==(const ContextInfo &, const ContextInfo &);
0267 
0268   ContextInfo &operator|=(const ContextInfo &RHS) {
0269     // Merge inherited info.
0270     static_cast<CommonTypeInfo &>(*this) |= RHS;
0271 
0272     // Merge nullability.
0273     if (!getDefaultNullability())
0274       if (auto Nullability = RHS.getDefaultNullability())
0275         setDefaultNullability(*Nullability);
0276 
0277     if (!SwiftImportAsNonGenericSpecified)
0278       setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric());
0279 
0280     if (!SwiftObjCMembersSpecified)
0281       setSwiftObjCMembers(RHS.getSwiftObjCMembers());
0282 
0283     HasDesignatedInits |= RHS.HasDesignatedInits;
0284 
0285     return *this;
0286   }
0287 
0288   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
0289 };
0290 
0291 inline bool operator==(const ContextInfo &LHS, const ContextInfo &RHS) {
0292   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
0293          LHS.getDefaultNullability() == RHS.getDefaultNullability() &&
0294          LHS.HasDesignatedInits == RHS.HasDesignatedInits &&
0295          LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() &&
0296          LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers();
0297 }
0298 
0299 inline bool operator!=(const ContextInfo &LHS, const ContextInfo &RHS) {
0300   return !(LHS == RHS);
0301 }
0302 
0303 /// API notes for a variable/property.
0304 class VariableInfo : public CommonEntityInfo {
0305   /// Whether this property has been audited for nullability.
0306   LLVM_PREFERRED_TYPE(bool)
0307   unsigned NullabilityAudited : 1;
0308 
0309   /// The kind of nullability for this property. Only valid if the nullability
0310   /// has been audited.
0311   LLVM_PREFERRED_TYPE(NullabilityKind)
0312   unsigned Nullable : 2;
0313 
0314   /// The C type of the variable, as a string.
0315   std::string Type;
0316 
0317 public:
0318   VariableInfo() : NullabilityAudited(false), Nullable(0) {}
0319 
0320   std::optional<NullabilityKind> getNullability() const {
0321     return NullabilityAudited ? std::optional<NullabilityKind>(
0322                                     static_cast<NullabilityKind>(Nullable))
0323                               : std::nullopt;
0324   }
0325 
0326   void setNullabilityAudited(NullabilityKind kind) {
0327     NullabilityAudited = true;
0328     Nullable = static_cast<unsigned>(kind);
0329   }
0330 
0331   const std::string &getType() const { return Type; }
0332   void setType(const std::string &type) { Type = type; }
0333 
0334   friend bool operator==(const VariableInfo &, const VariableInfo &);
0335 
0336   VariableInfo &operator|=(const VariableInfo &RHS) {
0337     static_cast<CommonEntityInfo &>(*this) |= RHS;
0338 
0339     if (!NullabilityAudited && RHS.NullabilityAudited)
0340       setNullabilityAudited(*RHS.getNullability());
0341     if (Type.empty())
0342       Type = RHS.Type;
0343 
0344     return *this;
0345   }
0346 
0347   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0348 };
0349 
0350 inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) {
0351   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
0352          LHS.NullabilityAudited == RHS.NullabilityAudited &&
0353          LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type;
0354 }
0355 
0356 inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) {
0357   return !(LHS == RHS);
0358 }
0359 
0360 /// Describes API notes data for an Objective-C property.
0361 class ObjCPropertyInfo : public VariableInfo {
0362   LLVM_PREFERRED_TYPE(bool)
0363   unsigned SwiftImportAsAccessorsSpecified : 1;
0364   LLVM_PREFERRED_TYPE(bool)
0365   unsigned SwiftImportAsAccessors : 1;
0366 
0367 public:
0368   ObjCPropertyInfo()
0369       : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
0370 
0371   std::optional<bool> getSwiftImportAsAccessors() const {
0372     return SwiftImportAsAccessorsSpecified
0373                ? std::optional<bool>(SwiftImportAsAccessors)
0374                : std::nullopt;
0375   }
0376   void setSwiftImportAsAccessors(std::optional<bool> Value) {
0377     SwiftImportAsAccessorsSpecified = Value.has_value();
0378     SwiftImportAsAccessors = Value.value_or(false);
0379   }
0380 
0381   friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
0382 
0383   /// Merge class-wide information into the given property.
0384   ObjCPropertyInfo &operator|=(const ContextInfo &RHS) {
0385     static_cast<CommonEntityInfo &>(*this) |= RHS;
0386 
0387     // Merge nullability.
0388     if (!getNullability())
0389       if (auto Nullable = RHS.getDefaultNullability())
0390         setNullabilityAudited(*Nullable);
0391 
0392     return *this;
0393   }
0394 
0395   ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) {
0396     static_cast<VariableInfo &>(*this) |= RHS;
0397 
0398     if (!SwiftImportAsAccessorsSpecified)
0399       setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors());
0400 
0401     return *this;
0402   }
0403 
0404   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0405 };
0406 
0407 inline bool operator==(const ObjCPropertyInfo &LHS,
0408                        const ObjCPropertyInfo &RHS) {
0409   return static_cast<const VariableInfo &>(LHS) == RHS &&
0410          LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors();
0411 }
0412 
0413 inline bool operator!=(const ObjCPropertyInfo &LHS,
0414                        const ObjCPropertyInfo &RHS) {
0415   return !(LHS == RHS);
0416 }
0417 
0418 /// Describes a function or method parameter.
0419 class ParamInfo : public VariableInfo {
0420   /// Whether noescape was specified.
0421   LLVM_PREFERRED_TYPE(bool)
0422   unsigned NoEscapeSpecified : 1;
0423 
0424   /// Whether the this parameter has the 'noescape' attribute.
0425   LLVM_PREFERRED_TYPE(bool)
0426   unsigned NoEscape : 1;
0427 
0428   /// Whether lifetimebound was specified.
0429   LLVM_PREFERRED_TYPE(bool)
0430   unsigned LifetimeboundSpecified : 1;
0431 
0432   /// Whether the this parameter has the 'lifetimebound' attribute.
0433   LLVM_PREFERRED_TYPE(bool)
0434   unsigned Lifetimebound : 1;
0435 
0436   /// A biased RetainCountConventionKind, where 0 means "unspecified".
0437   ///
0438   /// Only relevant for out-parameters.
0439   unsigned RawRetainCountConvention : 3;
0440 
0441 public:
0442   ParamInfo()
0443       : NoEscapeSpecified(false), NoEscape(false),
0444         LifetimeboundSpecified(false), Lifetimebound(false),
0445         RawRetainCountConvention() {}
0446 
0447   std::optional<bool> isNoEscape() const {
0448     return NoEscapeSpecified ? std::optional<bool>(NoEscape) : std::nullopt;
0449   }
0450   void setNoEscape(std::optional<bool> Value) {
0451     NoEscapeSpecified = Value.has_value();
0452     NoEscape = Value.value_or(false);
0453   }
0454 
0455   std::optional<bool> isLifetimebound() const {
0456     return LifetimeboundSpecified ? std::optional<bool>(Lifetimebound)
0457                                   : std::nullopt;
0458   }
0459   void setLifetimebound(std::optional<bool> Value) {
0460     LifetimeboundSpecified = Value.has_value();
0461     Lifetimebound = Value.value_or(false);
0462   }
0463 
0464   std::optional<RetainCountConventionKind> getRetainCountConvention() const {
0465     if (!RawRetainCountConvention)
0466       return std::nullopt;
0467     return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
0468   }
0469   void
0470   setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
0471     RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
0472     assert(getRetainCountConvention() == Value && "bitfield too small");
0473   }
0474 
0475   ParamInfo &operator|=(const ParamInfo &RHS) {
0476     static_cast<VariableInfo &>(*this) |= RHS;
0477 
0478     if (!NoEscapeSpecified && RHS.NoEscapeSpecified) {
0479       NoEscapeSpecified = true;
0480       NoEscape = RHS.NoEscape;
0481     }
0482 
0483     if (!LifetimeboundSpecified && RHS.LifetimeboundSpecified) {
0484       LifetimeboundSpecified = true;
0485       Lifetimebound = RHS.Lifetimebound;
0486     }
0487 
0488     if (!RawRetainCountConvention)
0489       RawRetainCountConvention = RHS.RawRetainCountConvention;
0490 
0491     return *this;
0492   }
0493 
0494   friend bool operator==(const ParamInfo &, const ParamInfo &);
0495 
0496   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0497 };
0498 
0499 inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) {
0500   return static_cast<const VariableInfo &>(LHS) == RHS &&
0501          LHS.NoEscapeSpecified == RHS.NoEscapeSpecified &&
0502          LHS.NoEscape == RHS.NoEscape &&
0503          LHS.LifetimeboundSpecified == RHS.LifetimeboundSpecified &&
0504          LHS.Lifetimebound == RHS.Lifetimebound &&
0505          LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
0506 }
0507 
0508 inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
0509   return !(LHS == RHS);
0510 }
0511 
0512 /// API notes for a function or method.
0513 class FunctionInfo : public CommonEntityInfo {
0514 private:
0515   static constexpr const uint64_t NullabilityKindMask = 0x3;
0516   static constexpr const unsigned NullabilityKindSize = 2;
0517 
0518   static constexpr const unsigned ReturnInfoIndex = 0;
0519 
0520 public:
0521   // If yes, we consider all types to be non-nullable unless otherwise noted.
0522   // If this flag is not set, the pointer types are considered to have
0523   // unknown nullability.
0524 
0525   /// Whether the signature has been audited with respect to nullability.
0526   LLVM_PREFERRED_TYPE(bool)
0527   unsigned NullabilityAudited : 1;
0528 
0529   /// Number of types whose nullability is encoded with the NullabilityPayload.
0530   unsigned NumAdjustedNullable : 8;
0531 
0532   /// A biased RetainCountConventionKind, where 0 means "unspecified".
0533   unsigned RawRetainCountConvention : 3;
0534 
0535   // NullabilityKindSize bits are used to encode the nullability. The info
0536   // about the return type is stored at position 0, followed by the nullability
0537   // of the parameters.
0538 
0539   /// Stores the nullability of the return type and the parameters.
0540   uint64_t NullabilityPayload = 0;
0541 
0542   /// The result type of this function, as a C type.
0543   std::string ResultType;
0544 
0545   /// Ownership convention for return value
0546   std::string SwiftReturnOwnership;
0547 
0548   /// The function parameters.
0549   std::vector<ParamInfo> Params;
0550 
0551   FunctionInfo()
0552       : NullabilityAudited(false), NumAdjustedNullable(0),
0553         RawRetainCountConvention() {}
0554 
0555   static unsigned getMaxNullabilityIndex() {
0556     return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize);
0557   }
0558 
0559   void addTypeInfo(unsigned index, NullabilityKind kind) {
0560     assert(index <= getMaxNullabilityIndex());
0561     assert(static_cast<unsigned>(kind) < NullabilityKindMask);
0562 
0563     NullabilityAudited = true;
0564     if (NumAdjustedNullable < index + 1)
0565       NumAdjustedNullable = index + 1;
0566 
0567     // Mask the bits.
0568     NullabilityPayload &=
0569         ~(NullabilityKindMask << (index * NullabilityKindSize));
0570 
0571     // Set the value.
0572     unsigned kindValue = (static_cast<unsigned>(kind))
0573                          << (index * NullabilityKindSize);
0574     NullabilityPayload |= kindValue;
0575   }
0576 
0577   /// Adds the return type info.
0578   void addReturnTypeInfo(NullabilityKind kind) {
0579     addTypeInfo(ReturnInfoIndex, kind);
0580   }
0581 
0582   /// Adds the parameter type info.
0583   void addParamTypeInfo(unsigned index, NullabilityKind kind) {
0584     addTypeInfo(index + 1, kind);
0585   }
0586 
0587   NullabilityKind getParamTypeInfo(unsigned index) const {
0588     return getTypeInfo(index + 1);
0589   }
0590 
0591   NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); }
0592 
0593   std::optional<RetainCountConventionKind> getRetainCountConvention() const {
0594     if (!RawRetainCountConvention)
0595       return std::nullopt;
0596     return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
0597   }
0598   void
0599   setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
0600     RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
0601     assert(getRetainCountConvention() == Value && "bitfield too small");
0602   }
0603 
0604   friend bool operator==(const FunctionInfo &, const FunctionInfo &);
0605 
0606 private:
0607   NullabilityKind getTypeInfo(unsigned index) const {
0608     assert(NullabilityAudited &&
0609            "Checking the type adjustment on non-audited method.");
0610 
0611     // If we don't have info about this parameter, return the default.
0612     if (index > NumAdjustedNullable)
0613       return NullabilityKind::NonNull;
0614     auto nullability = NullabilityPayload >> (index * NullabilityKindSize);
0615     return static_cast<NullabilityKind>(nullability & NullabilityKindMask);
0616   }
0617 
0618 public:
0619   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0620 };
0621 
0622 inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
0623   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
0624          LHS.NullabilityAudited == RHS.NullabilityAudited &&
0625          LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
0626          LHS.NullabilityPayload == RHS.NullabilityPayload &&
0627          LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
0628          LHS.RawRetainCountConvention == RHS.RawRetainCountConvention &&
0629          LHS.SwiftReturnOwnership == RHS.SwiftReturnOwnership;
0630 }
0631 
0632 inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
0633   return !(LHS == RHS);
0634 }
0635 
0636 /// Describes API notes data for an Objective-C method.
0637 class ObjCMethodInfo : public FunctionInfo {
0638 public:
0639   /// Whether this is a designated initializer of its class.
0640   LLVM_PREFERRED_TYPE(bool)
0641   unsigned DesignatedInit : 1;
0642 
0643   /// Whether this is a required initializer.
0644   LLVM_PREFERRED_TYPE(bool)
0645   unsigned RequiredInit : 1;
0646 
0647   std::optional<ParamInfo> Self;
0648 
0649   ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {}
0650 
0651   friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);
0652 
0653   ObjCMethodInfo &operator|=(const ContextInfo &RHS) {
0654     // Merge Nullability.
0655     if (!NullabilityAudited) {
0656       if (auto Nullable = RHS.getDefaultNullability()) {
0657         NullabilityAudited = true;
0658         addTypeInfo(0, *Nullable);
0659       }
0660     }
0661     return *this;
0662   }
0663 
0664   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
0665 };
0666 
0667 inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
0668   return static_cast<const FunctionInfo &>(LHS) == RHS &&
0669          LHS.DesignatedInit == RHS.DesignatedInit &&
0670          LHS.RequiredInit == RHS.RequiredInit && LHS.Self == RHS.Self;
0671 }
0672 
0673 inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
0674   return !(LHS == RHS);
0675 }
0676 
0677 /// Describes API notes data for a global variable.
0678 class GlobalVariableInfo : public VariableInfo {
0679 public:
0680   GlobalVariableInfo() {}
0681 };
0682 
0683 /// Describes API notes data for a global function.
0684 class GlobalFunctionInfo : public FunctionInfo {
0685 public:
0686   GlobalFunctionInfo() {}
0687 };
0688 
0689 /// Describes API notes data for a C/C++ record field.
0690 class FieldInfo : public VariableInfo {
0691 public:
0692   FieldInfo() {}
0693 };
0694 
0695 /// Describes API notes data for a C++ method.
0696 class CXXMethodInfo : public FunctionInfo {
0697 public:
0698   CXXMethodInfo() {}
0699 
0700   std::optional<ParamInfo> This;
0701 
0702   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
0703 };
0704 
0705 inline bool operator==(const CXXMethodInfo &LHS, const CXXMethodInfo &RHS) {
0706   return static_cast<const FunctionInfo &>(LHS) == RHS && LHS.This == RHS.This;
0707 }
0708 
0709 inline bool operator!=(const CXXMethodInfo &LHS, const CXXMethodInfo &RHS) {
0710   return !(LHS == RHS);
0711 }
0712 
0713 /// Describes API notes data for an enumerator.
0714 class EnumConstantInfo : public CommonEntityInfo {
0715 public:
0716   EnumConstantInfo() {}
0717 };
0718 
0719 /// Describes API notes data for a tag.
0720 class TagInfo : public CommonTypeInfo {
0721   LLVM_PREFERRED_TYPE(bool)
0722   unsigned HasFlagEnum : 1;
0723   LLVM_PREFERRED_TYPE(bool)
0724   unsigned IsFlagEnum : 1;
0725 
0726   LLVM_PREFERRED_TYPE(bool)
0727   unsigned SwiftCopyableSpecified : 1;
0728   LLVM_PREFERRED_TYPE(bool)
0729   unsigned SwiftCopyable : 1;
0730 
0731   LLVM_PREFERRED_TYPE(bool)
0732   unsigned SwiftEscapableSpecified : 1;
0733   LLVM_PREFERRED_TYPE(bool)
0734   unsigned SwiftEscapable : 1;
0735 
0736 public:
0737   std::optional<std::string> SwiftImportAs;
0738   std::optional<std::string> SwiftRetainOp;
0739   std::optional<std::string> SwiftReleaseOp;
0740 
0741   /// The Swift protocol that this type should be automatically conformed to.
0742   std::optional<std::string> SwiftConformance;
0743 
0744   std::optional<EnumExtensibilityKind> EnumExtensibility;
0745 
0746   TagInfo()
0747       : HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
0748         SwiftCopyable(false), SwiftEscapableSpecified(false),
0749         SwiftEscapable(false) {}
0750 
0751   std::optional<bool> isFlagEnum() const {
0752     if (HasFlagEnum)
0753       return IsFlagEnum;
0754     return std::nullopt;
0755   }
0756   void setFlagEnum(std::optional<bool> Value) {
0757     HasFlagEnum = Value.has_value();
0758     IsFlagEnum = Value.value_or(false);
0759   }
0760 
0761   std::optional<bool> isSwiftCopyable() const {
0762     return SwiftCopyableSpecified ? std::optional<bool>(SwiftCopyable)
0763                                   : std::nullopt;
0764   }
0765   void setSwiftCopyable(std::optional<bool> Value) {
0766     SwiftCopyableSpecified = Value.has_value();
0767     SwiftCopyable = Value.value_or(false);
0768   }
0769 
0770   std::optional<bool> isSwiftEscapable() const {
0771     return SwiftEscapableSpecified ? std::optional<bool>(SwiftEscapable)
0772                                    : std::nullopt;
0773   }
0774 
0775   void setSwiftEscapable(std::optional<bool> Value) {
0776     SwiftEscapableSpecified = Value.has_value();
0777     SwiftEscapable = Value.value_or(false);
0778   }
0779 
0780   TagInfo &operator|=(const TagInfo &RHS) {
0781     static_cast<CommonTypeInfo &>(*this) |= RHS;
0782 
0783     if (!SwiftImportAs)
0784       SwiftImportAs = RHS.SwiftImportAs;
0785     if (!SwiftRetainOp)
0786       SwiftRetainOp = RHS.SwiftRetainOp;
0787     if (!SwiftReleaseOp)
0788       SwiftReleaseOp = RHS.SwiftReleaseOp;
0789 
0790     if (!SwiftConformance)
0791       SwiftConformance = RHS.SwiftConformance;
0792 
0793     if (!HasFlagEnum)
0794       setFlagEnum(RHS.isFlagEnum());
0795 
0796     if (!EnumExtensibility)
0797       EnumExtensibility = RHS.EnumExtensibility;
0798 
0799     if (!SwiftCopyableSpecified)
0800       setSwiftCopyable(RHS.isSwiftCopyable());
0801 
0802     if (!SwiftEscapableSpecified)
0803       setSwiftEscapable(RHS.isSwiftEscapable());
0804 
0805     return *this;
0806   }
0807 
0808   friend bool operator==(const TagInfo &, const TagInfo &);
0809 
0810   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
0811 };
0812 
0813 inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
0814   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
0815          LHS.SwiftImportAs == RHS.SwiftImportAs &&
0816          LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
0817          LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
0818          LHS.SwiftConformance == RHS.SwiftConformance &&
0819          LHS.isFlagEnum() == RHS.isFlagEnum() &&
0820          LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
0821          LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&
0822          LHS.EnumExtensibility == RHS.EnumExtensibility;
0823 }
0824 
0825 inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) {
0826   return !(LHS == RHS);
0827 }
0828 
0829 /// Describes API notes data for a typedef.
0830 class TypedefInfo : public CommonTypeInfo {
0831 public:
0832   std::optional<SwiftNewTypeKind> SwiftWrapper;
0833 
0834   TypedefInfo() {}
0835 
0836   TypedefInfo &operator|=(const TypedefInfo &RHS) {
0837     static_cast<CommonTypeInfo &>(*this) |= RHS;
0838     if (!SwiftWrapper)
0839       SwiftWrapper = RHS.SwiftWrapper;
0840     return *this;
0841   }
0842 
0843   friend bool operator==(const TypedefInfo &, const TypedefInfo &);
0844 
0845   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
0846 };
0847 
0848 inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) {
0849   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
0850          LHS.SwiftWrapper == RHS.SwiftWrapper;
0851 }
0852 
0853 inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) {
0854   return !(LHS == RHS);
0855 }
0856 
0857 /// The file extension used for the source representation of API notes.
0858 static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes";
0859 
0860 /// Opaque context ID used to refer to an Objective-C class or protocol or a C++
0861 /// namespace.
0862 class ContextID {
0863 public:
0864   unsigned Value;
0865 
0866   explicit ContextID(unsigned value) : Value(value) {}
0867 };
0868 
0869 enum class ContextKind : uint8_t {
0870   ObjCClass = 0,
0871   ObjCProtocol = 1,
0872   Namespace = 2,
0873   Tag = 3,
0874 };
0875 
0876 struct Context {
0877   ContextID id;
0878   ContextKind kind;
0879 
0880   Context(ContextID id, ContextKind kind) : id(id), kind(kind) {}
0881 };
0882 
0883 /// A temporary reference to an Objective-C selector, suitable for
0884 /// referencing selector data on the stack.
0885 ///
0886 /// Instances of this struct do not store references to any of the
0887 /// data they contain; it is up to the user to ensure that the data
0888 /// referenced by the identifier list persists.
0889 struct ObjCSelectorRef {
0890   unsigned NumArgs;
0891   llvm::ArrayRef<llvm::StringRef> Identifiers;
0892 };
0893 } // namespace api_notes
0894 } // namespace clang
0895 
0896 #endif