Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- Types.h - API Notes Data Types --------------------------*- 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. #ifndef LLVM_CLANG_APINOTES_TYPES_H
  10. #define LLVM_CLANG_APINOTES_TYPES_H
  11.  
  12. #include "clang/Basic/Specifiers.h"
  13. #include "llvm/ADT/StringRef.h"
  14. #include <climits>
  15. #include <optional>
  16. #include <vector>
  17.  
  18. namespace llvm {
  19. class raw_ostream;
  20. } // namespace llvm
  21.  
  22. namespace clang {
  23. namespace api_notes {
  24. enum class RetainCountConventionKind {
  25.   None,
  26.   CFReturnsRetained,
  27.   CFReturnsNotRetained,
  28.   NSReturnsRetained,
  29.   NSReturnsNotRetained,
  30. };
  31.  
  32. /// The payload for an enum_extensibility attribute. This is a tri-state rather
  33. /// than just a boolean because the presence of the attribute indicates
  34. /// auditing.
  35. enum class EnumExtensibilityKind {
  36.   None,
  37.   Open,
  38.   Closed,
  39. };
  40.  
  41. /// The kind of a swift_wrapper/swift_newtype.
  42. enum class SwiftNewTypeKind {
  43.   None,
  44.   Struct,
  45.   Enum,
  46. };
  47.  
  48. /// Describes API notes data for any entity.
  49. ///
  50. /// This is used as the base of all API notes.
  51. class CommonEntityInfo {
  52. public:
  53.   /// Message to use when this entity is unavailable.
  54.   std::string UnavailableMsg;
  55.  
  56.   /// Whether this entity is marked unavailable.
  57.   unsigned Unavailable : 1;
  58.  
  59.   /// Whether this entity is marked unavailable in Swift.
  60.   unsigned UnavailableInSwift : 1;
  61.  
  62. private:
  63.   /// Whether SwiftPrivate was specified.
  64.   unsigned SwiftPrivateSpecified : 1;
  65.  
  66.   /// Whether this entity is considered "private" to a Swift overlay.
  67.   unsigned SwiftPrivate : 1;
  68.  
  69. public:
  70.   /// Swift name of this entity.
  71.   std::string SwiftName;
  72.  
  73.   CommonEntityInfo()
  74.       : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
  75.         SwiftPrivate(0) {}
  76.  
  77.   std::optional<bool> isSwiftPrivate() const {
  78.     return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
  79.                                  : std::nullopt;
  80.   }
  81.  
  82.   void setSwiftPrivate(std::optional<bool> Private) {
  83.     SwiftPrivateSpecified = Private.has_value();
  84.     SwiftPrivate = Private.value_or(0);
  85.   }
  86.  
  87.   friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
  88.  
  89.   CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) {
  90.     // Merge unavailability.
  91.     if (RHS.Unavailable) {
  92.       Unavailable = true;
  93.       if (UnavailableMsg.empty())
  94.         UnavailableMsg = RHS.UnavailableMsg;
  95.     }
  96.  
  97.     if (RHS.UnavailableInSwift) {
  98.       UnavailableInSwift = true;
  99.       if (UnavailableMsg.empty())
  100.         UnavailableMsg = RHS.UnavailableMsg;
  101.     }
  102.  
  103.     if (!SwiftPrivateSpecified)
  104.       setSwiftPrivate(RHS.isSwiftPrivate());
  105.  
  106.     if (SwiftName.empty())
  107.       SwiftName = RHS.SwiftName;
  108.  
  109.     return *this;
  110.   }
  111.  
  112.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  113. };
  114.  
  115. inline bool operator==(const CommonEntityInfo &LHS,
  116.                        const CommonEntityInfo &RHS) {
  117.   return LHS.UnavailableMsg == RHS.UnavailableMsg &&
  118.          LHS.Unavailable == RHS.Unavailable &&
  119.          LHS.UnavailableInSwift == RHS.UnavailableInSwift &&
  120.          LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
  121.          LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName;
  122. }
  123.  
  124. inline bool operator!=(const CommonEntityInfo &LHS,
  125.                        const CommonEntityInfo &RHS) {
  126.   return !(LHS == RHS);
  127. }
  128.  
  129. /// Describes API notes for types.
  130. class CommonTypeInfo : public CommonEntityInfo {
  131.   /// The Swift type to which a given type is bridged.
  132.   ///
  133.   /// Reflects the swift_bridge attribute.
  134.   std::optional<std::string> SwiftBridge;
  135.  
  136.   /// The NS error domain for this type.
  137.   std::optional<std::string> NSErrorDomain;
  138.  
  139. public:
  140.   CommonTypeInfo() {}
  141.  
  142.   const std::optional<std::string> &getSwiftBridge() const {
  143.     return SwiftBridge;
  144.   }
  145.  
  146.   void setSwiftBridge(const std::optional<std::string> &SwiftType) {
  147.     SwiftBridge = SwiftType;
  148.   }
  149.  
  150.   void setSwiftBridge(const std::optional<llvm::StringRef> &SwiftType) {
  151.     SwiftBridge = SwiftType
  152.                       ? std::optional<std::string>(std::string(*SwiftType))
  153.                       : std::nullopt;
  154.   }
  155.  
  156.   const std::optional<std::string> &getNSErrorDomain() const {
  157.     return NSErrorDomain;
  158.   }
  159.  
  160.   void setNSErrorDomain(const std::optional<std::string> &Domain) {
  161.     NSErrorDomain = Domain;
  162.   }
  163.  
  164.   void setNSErrorDomain(const std::optional<llvm::StringRef> &Domain) {
  165.     NSErrorDomain = Domain ? std::optional<std::string>(std::string(*Domain))
  166.                            : std::nullopt;
  167.   }
  168.  
  169.   friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
  170.  
  171.   CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
  172.     // Merge inherited info.
  173.     static_cast<CommonEntityInfo &>(*this) |= RHS;
  174.  
  175.     if (!SwiftBridge)
  176.       setSwiftBridge(RHS.getSwiftBridge());
  177.     if (!NSErrorDomain)
  178.       setNSErrorDomain(RHS.getNSErrorDomain());
  179.  
  180.     return *this;
  181.   }
  182.  
  183.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  184. };
  185.  
  186. inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
  187.   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
  188.          LHS.SwiftBridge == RHS.SwiftBridge &&
  189.          LHS.NSErrorDomain == RHS.NSErrorDomain;
  190. }
  191.  
  192. inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
  193.   return !(LHS == RHS);
  194. }
  195.  
  196. /// Describes API notes data for an Objective-C class or protocol.
  197. class ObjCContextInfo : public CommonTypeInfo {
  198.   /// Whether this class has a default nullability.
  199.   unsigned HasDefaultNullability : 1;
  200.  
  201.   /// The default nullability.
  202.   unsigned DefaultNullability : 2;
  203.  
  204.   /// Whether this class has designated initializers recorded.
  205.   unsigned HasDesignatedInits : 1;
  206.  
  207.   unsigned SwiftImportAsNonGenericSpecified : 1;
  208.   unsigned SwiftImportAsNonGeneric : 1;
  209.  
  210.   unsigned SwiftObjCMembersSpecified : 1;
  211.   unsigned SwiftObjCMembers : 1;
  212.  
  213. public:
  214.   ObjCContextInfo()
  215.       : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0),
  216.         SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false),
  217.         SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {}
  218.  
  219.   /// Determine the default nullability for properties and methods of this
  220.   /// class.
  221.   ///
  222.   /// Returns the default nullability, if implied, or std::nullopt if there is
  223.   /// none.
  224.   std::optional<NullabilityKind> getDefaultNullability() const {
  225.     return HasDefaultNullability
  226.                ? std::optional<NullabilityKind>(
  227.                      static_cast<NullabilityKind>(DefaultNullability))
  228.                : std::nullopt;
  229.   }
  230.  
  231.   /// Set the default nullability for properties and methods of this class.
  232.   void setDefaultNullability(NullabilityKind Kind) {
  233.     HasDefaultNullability = true;
  234.     DefaultNullability = static_cast<unsigned>(Kind);
  235.   }
  236.  
  237.   bool hasDesignatedInits() const { return HasDesignatedInits; }
  238.   void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; }
  239.  
  240.   std::optional<bool> getSwiftImportAsNonGeneric() const {
  241.     return SwiftImportAsNonGenericSpecified
  242.                ? std::optional<bool>(SwiftImportAsNonGeneric)
  243.                : std::nullopt;
  244.   }
  245.   void setSwiftImportAsNonGeneric(std::optional<bool> Value) {
  246.     SwiftImportAsNonGenericSpecified = Value.has_value();
  247.     SwiftImportAsNonGeneric = Value.value_or(false);
  248.   }
  249.  
  250.   std::optional<bool> getSwiftObjCMembers() const {
  251.     return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers)
  252.                                      : std::nullopt;
  253.   }
  254.   void setSwiftObjCMembers(std::optional<bool> Value) {
  255.     SwiftObjCMembersSpecified = Value.has_value();
  256.     SwiftObjCMembers = Value.value_or(false);
  257.   }
  258.  
  259.   /// Strip off any information within the class information structure that is
  260.   /// module-local, such as 'audited' flags.
  261.   void stripModuleLocalInfo() {
  262.     HasDefaultNullability = false;
  263.     DefaultNullability = 0;
  264.   }
  265.  
  266.   friend bool operator==(const ObjCContextInfo &, const ObjCContextInfo &);
  267.  
  268.   ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) {
  269.     // Merge inherited info.
  270.     static_cast<CommonTypeInfo &>(*this) |= RHS;
  271.  
  272.     // Merge nullability.
  273.     if (!getDefaultNullability())
  274.       if (auto Nullability = RHS.getDefaultNullability())
  275.         setDefaultNullability(*Nullability);
  276.  
  277.     if (!SwiftImportAsNonGenericSpecified)
  278.       setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric());
  279.  
  280.     if (!SwiftObjCMembersSpecified)
  281.       setSwiftObjCMembers(RHS.getSwiftObjCMembers());
  282.  
  283.     HasDesignatedInits |= RHS.HasDesignatedInits;
  284.  
  285.     return *this;
  286.   }
  287.  
  288.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
  289. };
  290.  
  291. inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
  292.   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
  293.          LHS.getDefaultNullability() == RHS.getDefaultNullability() &&
  294.          LHS.HasDesignatedInits == RHS.HasDesignatedInits &&
  295.          LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() &&
  296.          LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers();
  297. }
  298.  
  299. inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
  300.   return !(LHS == RHS);
  301. }
  302.  
  303. /// API notes for a variable/property.
  304. class VariableInfo : public CommonEntityInfo {
  305.   /// Whether this property has been audited for nullability.
  306.   unsigned NullabilityAudited : 1;
  307.  
  308.   /// The kind of nullability for this property. Only valid if the nullability
  309.   /// has been audited.
  310.   unsigned Nullable : 2;
  311.  
  312.   /// The C type of the variable, as a string.
  313.   std::string Type;
  314.  
  315. public:
  316.   VariableInfo() : NullabilityAudited(false), Nullable(0) {}
  317.  
  318.   std::optional<NullabilityKind> getNullability() const {
  319.     return NullabilityAudited ? std::optional<NullabilityKind>(
  320.                                     static_cast<NullabilityKind>(Nullable))
  321.                               : std::nullopt;
  322.   }
  323.  
  324.   void setNullabilityAudited(NullabilityKind kind) {
  325.     NullabilityAudited = true;
  326.     Nullable = static_cast<unsigned>(kind);
  327.   }
  328.  
  329.   const std::string &getType() const { return Type; }
  330.   void setType(const std::string &type) { Type = type; }
  331.  
  332.   friend bool operator==(const VariableInfo &, const VariableInfo &);
  333.  
  334.   VariableInfo &operator|=(const VariableInfo &RHS) {
  335.     static_cast<CommonEntityInfo &>(*this) |= RHS;
  336.  
  337.     if (!NullabilityAudited && RHS.NullabilityAudited)
  338.       setNullabilityAudited(*RHS.getNullability());
  339.     if (Type.empty())
  340.       Type = RHS.Type;
  341.  
  342.     return *this;
  343.   }
  344.  
  345.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  346. };
  347.  
  348. inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) {
  349.   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
  350.          LHS.NullabilityAudited == RHS.NullabilityAudited &&
  351.          LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type;
  352. }
  353.  
  354. inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) {
  355.   return !(LHS == RHS);
  356. }
  357.  
  358. /// Describes API notes data for an Objective-C property.
  359. class ObjCPropertyInfo : public VariableInfo {
  360.   unsigned SwiftImportAsAccessorsSpecified : 1;
  361.   unsigned SwiftImportAsAccessors : 1;
  362.  
  363. public:
  364.   ObjCPropertyInfo()
  365.       : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
  366.  
  367.   std::optional<bool> getSwiftImportAsAccessors() const {
  368.     return SwiftImportAsAccessorsSpecified
  369.                ? std::optional<bool>(SwiftImportAsAccessors)
  370.                : std::nullopt;
  371.   }
  372.   void setSwiftImportAsAccessors(std::optional<bool> Value) {
  373.     SwiftImportAsAccessorsSpecified = Value.has_value();
  374.     SwiftImportAsAccessors = Value.value_or(false);
  375.   }
  376.  
  377.   friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
  378.  
  379.   /// Merge class-wide information into the given property.
  380.   ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) {
  381.     static_cast<CommonEntityInfo &>(*this) |= RHS;
  382.  
  383.     // Merge nullability.
  384.     if (!getNullability())
  385.       if (auto Nullable = RHS.getDefaultNullability())
  386.         setNullabilityAudited(*Nullable);
  387.  
  388.     return *this;
  389.   }
  390.  
  391.   ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) {
  392.     static_cast<VariableInfo &>(*this) |= RHS;
  393.  
  394.     if (!SwiftImportAsAccessorsSpecified)
  395.       setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors());
  396.  
  397.     return *this;
  398.   }
  399.  
  400.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  401. };
  402.  
  403. inline bool operator==(const ObjCPropertyInfo &LHS,
  404.                        const ObjCPropertyInfo &RHS) {
  405.   return static_cast<const VariableInfo &>(LHS) == RHS &&
  406.          LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors();
  407. }
  408.  
  409. inline bool operator!=(const ObjCPropertyInfo &LHS,
  410.                        const ObjCPropertyInfo &RHS) {
  411.   return !(LHS == RHS);
  412. }
  413.  
  414. /// Describes a function or method parameter.
  415. class ParamInfo : public VariableInfo {
  416.   /// Whether noescape was specified.
  417.   unsigned NoEscapeSpecified : 1;
  418.  
  419.   /// Whether the this parameter has the 'noescape' attribute.
  420.   unsigned NoEscape : 1;
  421.  
  422.   /// A biased RetainCountConventionKind, where 0 means "unspecified".
  423.   ///
  424.   /// Only relevant for out-parameters.
  425.   unsigned RawRetainCountConvention : 3;
  426.  
  427. public:
  428.   ParamInfo()
  429.       : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {}
  430.  
  431.   std::optional<bool> isNoEscape() const {
  432.     if (!NoEscapeSpecified)
  433.       return std::nullopt;
  434.     return NoEscape;
  435.   }
  436.   void setNoEscape(std::optional<bool> Value) {
  437.     NoEscapeSpecified = Value.has_value();
  438.     NoEscape = Value.value_or(false);
  439.   }
  440.  
  441.   std::optional<RetainCountConventionKind> getRetainCountConvention() const {
  442.     if (!RawRetainCountConvention)
  443.       return std::nullopt;
  444.     return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
  445.   }
  446.   void
  447.   setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
  448.     RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
  449.     assert(getRetainCountConvention() == Value && "bitfield too small");
  450.   }
  451.  
  452.   ParamInfo &operator|=(const ParamInfo &RHS) {
  453.     static_cast<VariableInfo &>(*this) |= RHS;
  454.  
  455.     if (!NoEscapeSpecified && RHS.NoEscapeSpecified) {
  456.       NoEscapeSpecified = true;
  457.       NoEscape = RHS.NoEscape;
  458.     }
  459.  
  460.     if (!RawRetainCountConvention)
  461.       RawRetainCountConvention = RHS.RawRetainCountConvention;
  462.  
  463.     return *this;
  464.   }
  465.  
  466.   friend bool operator==(const ParamInfo &, const ParamInfo &);
  467.  
  468.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  469. };
  470.  
  471. inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) {
  472.   return static_cast<const VariableInfo &>(LHS) == RHS &&
  473.          LHS.NoEscapeSpecified == RHS.NoEscapeSpecified &&
  474.          LHS.NoEscape == RHS.NoEscape &&
  475.          LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
  476. }
  477.  
  478. inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
  479.   return !(LHS == RHS);
  480. }
  481.  
  482. /// API notes for a function or method.
  483. class FunctionInfo : public CommonEntityInfo {
  484. private:
  485.   static constexpr const uint64_t NullabilityKindMask = 0x3;
  486.   static constexpr const unsigned NullabilityKindSize = 2;
  487.  
  488.   static constexpr const unsigned ReturnInfoIndex = 0;
  489.  
  490. public:
  491.   // If yes, we consider all types to be non-nullable unless otherwise noted.
  492.   // If this flag is not set, the pointer types are considered to have
  493.   // unknown nullability.
  494.  
  495.   /// Whether the signature has been audited with respect to nullability.
  496.   unsigned NullabilityAudited : 1;
  497.  
  498.   /// Number of types whose nullability is encoded with the NullabilityPayload.
  499.   unsigned NumAdjustedNullable : 8;
  500.  
  501.   /// A biased RetainCountConventionKind, where 0 means "unspecified".
  502.   unsigned RawRetainCountConvention : 3;
  503.  
  504.   // NullabilityKindSize bits are used to encode the nullability. The info
  505.   // about the return type is stored at position 0, followed by the nullability
  506.   // of the parameters.
  507.  
  508.   /// Stores the nullability of the return type and the parameters.
  509.   uint64_t NullabilityPayload = 0;
  510.  
  511.   /// The result type of this function, as a C type.
  512.   std::string ResultType;
  513.  
  514.   /// The function parameters.
  515.   std::vector<ParamInfo> Params;
  516.  
  517.   FunctionInfo()
  518.       : NullabilityAudited(false), NumAdjustedNullable(0),
  519.         RawRetainCountConvention() {}
  520.  
  521.   static unsigned getMaxNullabilityIndex() {
  522.     return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize);
  523.   }
  524.  
  525.   void addTypeInfo(unsigned index, NullabilityKind kind) {
  526.     assert(index <= getMaxNullabilityIndex());
  527.     assert(static_cast<unsigned>(kind) < NullabilityKindMask);
  528.  
  529.     NullabilityAudited = true;
  530.     if (NumAdjustedNullable < index + 1)
  531.       NumAdjustedNullable = index + 1;
  532.  
  533.     // Mask the bits.
  534.     NullabilityPayload &=
  535.         ~(NullabilityKindMask << (index * NullabilityKindSize));
  536.  
  537.     // Set the value.
  538.     unsigned kindValue = (static_cast<unsigned>(kind))
  539.                          << (index * NullabilityKindSize);
  540.     NullabilityPayload |= kindValue;
  541.   }
  542.  
  543.   /// Adds the return type info.
  544.   void addReturnTypeInfo(NullabilityKind kind) {
  545.     addTypeInfo(ReturnInfoIndex, kind);
  546.   }
  547.  
  548.   /// Adds the parameter type info.
  549.   void addParamTypeInfo(unsigned index, NullabilityKind kind) {
  550.     addTypeInfo(index + 1, kind);
  551.   }
  552.  
  553.   NullabilityKind getParamTypeInfo(unsigned index) const {
  554.     return getTypeInfo(index + 1);
  555.   }
  556.  
  557.   NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); }
  558.  
  559.   std::optional<RetainCountConventionKind> getRetainCountConvention() const {
  560.     if (!RawRetainCountConvention)
  561.       return std::nullopt;
  562.     return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
  563.   }
  564.   void
  565.   setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
  566.     RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
  567.     assert(getRetainCountConvention() == Value && "bitfield too small");
  568.   }
  569.  
  570.   friend bool operator==(const FunctionInfo &, const FunctionInfo &);
  571.  
  572. private:
  573.   NullabilityKind getTypeInfo(unsigned index) const {
  574.     assert(NullabilityAudited &&
  575.            "Checking the type adjustment on non-audited method.");
  576.  
  577.     // If we don't have info about this parameter, return the default.
  578.     if (index > NumAdjustedNullable)
  579.       return NullabilityKind::NonNull;
  580.     auto nullability = NullabilityPayload >> (index * NullabilityKindSize);
  581.     return static_cast<NullabilityKind>(nullability & NullabilityKindMask);
  582.   }
  583.  
  584. public:
  585.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  586. };
  587.  
  588. inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
  589.   return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
  590.          LHS.NullabilityAudited == RHS.NullabilityAudited &&
  591.          LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
  592.          LHS.NullabilityPayload == RHS.NullabilityPayload &&
  593.          LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
  594.          LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
  595. }
  596.  
  597. inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
  598.   return !(LHS == RHS);
  599. }
  600.  
  601. /// Describes API notes data for an Objective-C method.
  602. class ObjCMethodInfo : public FunctionInfo {
  603. public:
  604.   /// Whether this is a designated initializer of its class.
  605.   unsigned DesignatedInit : 1;
  606.  
  607.   /// Whether this is a required initializer.
  608.   unsigned RequiredInit : 1;
  609.  
  610.   ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {}
  611.  
  612.   friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);
  613.  
  614.   ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) {
  615.     // Merge Nullability.
  616.     if (!NullabilityAudited) {
  617.       if (auto Nullable = RHS.getDefaultNullability()) {
  618.         NullabilityAudited = true;
  619.         addTypeInfo(0, *Nullable);
  620.       }
  621.     }
  622.     return *this;
  623.   }
  624.  
  625.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
  626. };
  627.  
  628. inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
  629.   return static_cast<const FunctionInfo &>(LHS) == RHS &&
  630.          LHS.DesignatedInit == RHS.DesignatedInit &&
  631.          LHS.RequiredInit == RHS.RequiredInit;
  632. }
  633.  
  634. inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
  635.   return !(LHS == RHS);
  636. }
  637.  
  638. /// Describes API notes data for a global variable.
  639. class GlobalVariableInfo : public VariableInfo {
  640. public:
  641.   GlobalVariableInfo() {}
  642. };
  643.  
  644. /// Describes API notes data for a global function.
  645. class GlobalFunctionInfo : public FunctionInfo {
  646. public:
  647.   GlobalFunctionInfo() {}
  648. };
  649.  
  650. /// Describes API notes data for an enumerator.
  651. class EnumConstantInfo : public CommonEntityInfo {
  652. public:
  653.   EnumConstantInfo() {}
  654. };
  655.  
  656. /// Describes API notes data for a tag.
  657. class TagInfo : public CommonTypeInfo {
  658.   unsigned HasFlagEnum : 1;
  659.   unsigned IsFlagEnum : 1;
  660.  
  661. public:
  662.   std::optional<EnumExtensibilityKind> EnumExtensibility;
  663.  
  664.   TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
  665.  
  666.   std::optional<bool> isFlagEnum() const {
  667.     if (HasFlagEnum)
  668.       return IsFlagEnum;
  669.     return std::nullopt;
  670.   }
  671.   void setFlagEnum(std::optional<bool> Value) {
  672.     HasFlagEnum = Value.has_value();
  673.     IsFlagEnum = Value.value_or(false);
  674.   }
  675.  
  676.   TagInfo &operator|=(const TagInfo &RHS) {
  677.     static_cast<CommonTypeInfo &>(*this) |= RHS;
  678.  
  679.     if (!HasFlagEnum)
  680.       setFlagEnum(RHS.isFlagEnum());
  681.  
  682.     if (!EnumExtensibility)
  683.       EnumExtensibility = RHS.EnumExtensibility;
  684.  
  685.     return *this;
  686.   }
  687.  
  688.   friend bool operator==(const TagInfo &, const TagInfo &);
  689.  
  690.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
  691. };
  692.  
  693. inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
  694.   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
  695.          LHS.isFlagEnum() == RHS.isFlagEnum() &&
  696.          LHS.EnumExtensibility == RHS.EnumExtensibility;
  697. }
  698.  
  699. inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) {
  700.   return !(LHS == RHS);
  701. }
  702.  
  703. /// Describes API notes data for a typedef.
  704. class TypedefInfo : public CommonTypeInfo {
  705. public:
  706.   std::optional<SwiftNewTypeKind> SwiftWrapper;
  707.  
  708.   TypedefInfo() {}
  709.  
  710.   TypedefInfo &operator|=(const TypedefInfo &RHS) {
  711.     static_cast<CommonTypeInfo &>(*this) |= RHS;
  712.     if (!SwiftWrapper)
  713.       SwiftWrapper = RHS.SwiftWrapper;
  714.     return *this;
  715.   }
  716.  
  717.   friend bool operator==(const TypedefInfo &, const TypedefInfo &);
  718.  
  719.   LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
  720. };
  721.  
  722. inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) {
  723.   return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
  724.          LHS.SwiftWrapper == RHS.SwiftWrapper;
  725. }
  726.  
  727. inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) {
  728.   return !(LHS == RHS);
  729. }
  730. } // namespace api_notes
  731. } // namespace clang
  732.  
  733. #endif
  734.