| //===-- Types.h - API Notes Data Types --------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_APINOTES_TYPES_H |
| #define LLVM_CLANG_APINOTES_TYPES_H |
| |
| #include "clang/Basic/Specifiers.h" |
| #include "llvm/ADT/Optional.h" |
| #include "llvm/ADT/StringRef.h" |
| #include <climits> |
| #include <vector> |
| |
| namespace clang { |
| namespace api_notes { |
| enum class RetainCountConventionKind { |
| None, |
| CFReturnsRetained, |
| CFReturnsNotRetained, |
| NSReturnsRetained, |
| NSReturnsNotRetained, |
| }; |
| |
| /// The payload for an enum_extensibility attribute. This is a tri-state rather |
| /// than just a boolean because the presence of the attribute indicates |
| /// auditing. |
| enum class EnumExtensibilityKind { |
| None, |
| Open, |
| Closed, |
| }; |
| |
| /// The kind of a swift_wrapper/swift_newtype. |
| enum class SwiftNewTypeKind { |
| None, |
| Struct, |
| Enum, |
| }; |
| |
| /// Describes API notes data for any entity. |
| /// |
| /// This is used as the base of all API notes. |
| class CommonEntityInfo { |
| public: |
| /// Message to use when this entity is unavailable. |
| std::string UnavailableMsg; |
| |
| /// Whether this entity is marked unavailable. |
| unsigned Unavailable : 1; |
| |
| /// Whether this entity is marked unavailable in Swift. |
| unsigned UnavailableInSwift : 1; |
| |
| private: |
| /// Whether SwiftPrivate was specified. |
| unsigned SwiftPrivateSpecified : 1; |
| |
| /// Whether this entity is considered "private" to a Swift overlay. |
| unsigned SwiftPrivate : 1; |
| |
| public: |
| /// Swift name of this entity. |
| std::string SwiftName; |
| |
| CommonEntityInfo() |
| : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0), |
| SwiftPrivate(0) {} |
| |
| llvm::Optional<bool> isSwiftPrivate() const { |
| return SwiftPrivateSpecified ? llvm::Optional<bool>(SwiftPrivate) |
| : llvm::None; |
| } |
| |
| void setSwiftPrivate(llvm::Optional<bool> Private) { |
| SwiftPrivateSpecified = Private.hasValue(); |
| SwiftPrivate = Private.hasValue() ? *Private : 0; |
| } |
| |
| friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &); |
| |
| CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) { |
| // Merge unavailability. |
| if (RHS.Unavailable) { |
| Unavailable = true; |
| if (UnavailableMsg.empty()) |
| UnavailableMsg = RHS.UnavailableMsg; |
| } |
| |
| if (RHS.UnavailableInSwift) { |
| UnavailableInSwift = true; |
| if (UnavailableMsg.empty()) |
| UnavailableMsg = RHS.UnavailableMsg; |
| } |
| |
| if (!SwiftPrivateSpecified) |
| setSwiftPrivate(RHS.isSwiftPrivate()); |
| |
| if (SwiftName.empty()) |
| SwiftName = RHS.SwiftName; |
| |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const CommonEntityInfo &LHS, |
| const CommonEntityInfo &RHS) { |
| return LHS.UnavailableMsg == RHS.UnavailableMsg && |
| LHS.Unavailable == RHS.Unavailable && |
| LHS.UnavailableInSwift == RHS.UnavailableInSwift && |
| LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified && |
| LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName; |
| } |
| |
| inline bool operator!=(const CommonEntityInfo &LHS, |
| const CommonEntityInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes for types. |
| class CommonTypeInfo : public CommonEntityInfo { |
| /// The Swift type to which a given type is bridged. |
| /// |
| /// Reflects the swift_bridge attribute. |
| llvm::Optional<std::string> SwiftBridge; |
| |
| /// The NS error domain for this type. |
| llvm::Optional<std::string> NSErrorDomain; |
| |
| public: |
| CommonTypeInfo() : CommonEntityInfo() {} |
| |
| const llvm::Optional<std::string> &getSwiftBridge() const { |
| return SwiftBridge; |
| } |
| |
| void setSwiftBridge(const llvm::Optional<std::string> &SwiftType) { |
| SwiftBridge = SwiftType; |
| } |
| |
| void setSwiftBridge(const llvm::Optional<llvm::StringRef> &SwiftType) { |
| SwiftBridge = SwiftType |
| ? llvm::Optional<std::string>(std::string(*SwiftType)) |
| : llvm::None; |
| } |
| |
| const llvm::Optional<std::string> &getNSErrorDomain() const { |
| return NSErrorDomain; |
| } |
| |
| void setNSErrorDomain(const llvm::Optional<std::string> &Domain) { |
| NSErrorDomain = Domain; |
| } |
| |
| void setNSErrorDomain(const llvm::Optional<llvm::StringRef> &Domain) { |
| NSErrorDomain = |
| Domain ? llvm::Optional<std::string>(std::string(*Domain)) : llvm::None; |
| } |
| |
| friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &); |
| |
| CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) { |
| // Merge inherited info. |
| static_cast<CommonEntityInfo &>(*this) |= RHS; |
| |
| if (!SwiftBridge) |
| setSwiftBridge(RHS.getSwiftBridge()); |
| if (!NSErrorDomain) |
| setNSErrorDomain(RHS.getNSErrorDomain()); |
| |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) { |
| return static_cast<const CommonEntityInfo &>(LHS) == RHS && |
| LHS.SwiftBridge == RHS.SwiftBridge && |
| LHS.NSErrorDomain == RHS.NSErrorDomain; |
| } |
| |
| inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes data for an Objective-C class or protocol. |
| class ObjCContextInfo : public CommonTypeInfo { |
| /// Whether this class has a default nullability. |
| unsigned HasDefaultNullability : 1; |
| |
| /// The default nullability. |
| unsigned DefaultNullability : 2; |
| |
| /// Whether this class has designated initializers recorded. |
| unsigned HasDesignatedInits : 1; |
| |
| unsigned SwiftImportAsNonGenericSpecified : 1; |
| unsigned SwiftImportAsNonGeneric : 1; |
| |
| unsigned SwiftObjCMembersSpecified : 1; |
| unsigned SwiftObjCMembers : 1; |
| |
| public: |
| ObjCContextInfo() |
| : CommonTypeInfo(), HasDefaultNullability(0), DefaultNullability(0), |
| HasDesignatedInits(0), SwiftImportAsNonGenericSpecified(false), |
| SwiftImportAsNonGeneric(false), SwiftObjCMembersSpecified(false), |
| SwiftObjCMembers(false) {} |
| |
| /// Determine the default nullability for properties and methods of this |
| /// class. |
| /// |
| /// eturns the default nullability, if implied, or None if there is no |
| llvm::Optional<NullabilityKind> getDefaultNullability() const { |
| return HasDefaultNullability |
| ? llvm::Optional<NullabilityKind>( |
| static_cast<NullabilityKind>(DefaultNullability)) |
| : llvm::None; |
| } |
| |
| /// Set the default nullability for properties and methods of this class. |
| void setDefaultNullability(NullabilityKind Kind) { |
| HasDefaultNullability = true; |
| DefaultNullability = static_cast<unsigned>(Kind); |
| } |
| |
| bool hasDesignatedInits() const { return HasDesignatedInits; } |
| void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; } |
| |
| llvm::Optional<bool> getSwiftImportAsNonGeneric() const { |
| return SwiftImportAsNonGenericSpecified |
| ? llvm::Optional<bool>(SwiftImportAsNonGeneric) |
| : llvm::None; |
| } |
| void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) { |
| SwiftImportAsNonGenericSpecified = Value.hasValue(); |
| SwiftImportAsNonGeneric = Value.hasValue() ? *Value : false; |
| } |
| |
| llvm::Optional<bool> getSwiftObjCMembers() const { |
| return SwiftObjCMembersSpecified ? llvm::Optional<bool>(SwiftObjCMembers) |
| : llvm::None; |
| } |
| void setSwiftObjCMembers(llvm::Optional<bool> Value) { |
| SwiftObjCMembersSpecified = Value.hasValue(); |
| SwiftObjCMembers = Value.hasValue() ? *Value : false; |
| } |
| |
| /// Strip off any information within the class information structure that is |
| /// module-local, such as 'audited' flags. |
| void stripModuleLocalInfo() { |
| HasDefaultNullability = false; |
| DefaultNullability = 0; |
| } |
| |
| friend bool operator==(const ObjCContextInfo &, const ObjCContextInfo &); |
| |
| ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) { |
| // Merge inherited info. |
| static_cast<CommonTypeInfo &>(*this) |= RHS; |
| |
| // Merge nullability. |
| if (!getDefaultNullability()) |
| if (auto Nullability = RHS.getDefaultNullability()) |
| setDefaultNullability(*Nullability); |
| |
| if (!SwiftImportAsNonGenericSpecified) |
| setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric()); |
| |
| if (!SwiftObjCMembersSpecified) |
| setSwiftObjCMembers(RHS.getSwiftObjCMembers()); |
| |
| HasDesignatedInits |= RHS.HasDesignatedInits; |
| |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); |
| }; |
| |
| inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { |
| return static_cast<const CommonTypeInfo &>(LHS) == RHS && |
| LHS.getDefaultNullability() == RHS.getDefaultNullability() && |
| LHS.HasDesignatedInits == RHS.HasDesignatedInits && |
| LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() && |
| LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers(); |
| } |
| |
| inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// API notes for a variable/property. |
| class VariableInfo : public CommonEntityInfo { |
| /// Whether this property has been audited for nullability. |
| unsigned NullabilityAudited : 1; |
| |
| /// The kind of nullability for this property. Only valid if the nullability |
| /// has been audited. |
| unsigned Nullable : 2; |
| |
| /// The C type of the variable, as a string. |
| std::string Type; |
| |
| public: |
| VariableInfo() : CommonEntityInfo(), NullabilityAudited(false), Nullable(0) {} |
| |
| llvm::Optional<NullabilityKind> getNullability() const { |
| return NullabilityAudited ? llvm::Optional<NullabilityKind>( |
| static_cast<NullabilityKind>(Nullable)) |
| : llvm::None; |
| } |
| |
| void setNullabilityAudited(NullabilityKind kind) { |
| NullabilityAudited = true; |
| Nullable = static_cast<unsigned>(kind); |
| } |
| |
| const std::string &getType() const { return Type; } |
| void setType(const std::string &type) { Type = type; } |
| |
| friend bool operator==(const VariableInfo &, const VariableInfo &); |
| |
| VariableInfo &operator|=(const VariableInfo &RHS) { |
| static_cast<CommonEntityInfo &>(*this) |= RHS; |
| |
| if (!NullabilityAudited && RHS.NullabilityAudited) |
| setNullabilityAudited(*RHS.getNullability()); |
| if (Type.empty()) |
| Type = RHS.Type; |
| |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) { |
| return static_cast<const CommonEntityInfo &>(LHS) == RHS && |
| LHS.NullabilityAudited == RHS.NullabilityAudited && |
| LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type; |
| } |
| |
| inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes data for an Objective-C property. |
| class ObjCPropertyInfo : public VariableInfo { |
| unsigned SwiftImportAsAccessorsSpecified : 1; |
| unsigned SwiftImportAsAccessors : 1; |
| |
| public: |
| ObjCPropertyInfo() |
| : VariableInfo(), SwiftImportAsAccessorsSpecified(false), |
| SwiftImportAsAccessors(false) {} |
| |
| llvm::Optional<bool> getSwiftImportAsAccessors() const { |
| return SwiftImportAsAccessorsSpecified |
| ? llvm::Optional<bool>(SwiftImportAsAccessors) |
| : llvm::None; |
| } |
| void setSwiftImportAsAccessors(llvm::Optional<bool> Value) { |
| SwiftImportAsAccessorsSpecified = Value.hasValue(); |
| SwiftImportAsAccessors = Value.hasValue() ? *Value : false; |
| } |
| |
| friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &); |
| |
| /// Merge class-wide information into the given property. |
| ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) { |
| static_cast<CommonEntityInfo &>(*this) |= RHS; |
| |
| // Merge nullability. |
| if (!getNullability()) |
| if (auto Nullable = RHS.getDefaultNullability()) |
| setNullabilityAudited(*Nullable); |
| |
| return *this; |
| } |
| |
| ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) { |
| static_cast<VariableInfo &>(*this) |= RHS; |
| |
| if (!SwiftImportAsAccessorsSpecified) |
| setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors()); |
| |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const ObjCPropertyInfo &LHS, |
| const ObjCPropertyInfo &RHS) { |
| return static_cast<const VariableInfo &>(LHS) == RHS && |
| LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors(); |
| } |
| |
| inline bool operator!=(const ObjCPropertyInfo &LHS, |
| const ObjCPropertyInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes a function or method parameter. |
| class ParamInfo : public VariableInfo { |
| /// Whether noescape was specified. |
| unsigned NoEscapeSpecified : 1; |
| |
| /// Whether the this parameter has the 'noescape' attribute. |
| unsigned NoEscape : 1; |
| |
| /// A biased RetainCountConventionKind, where 0 means "unspecified". |
| /// |
| /// Only relevant for out-parameters. |
| unsigned RawRetainCountConvention : 3; |
| |
| public: |
| ParamInfo() |
| : VariableInfo(), NoEscapeSpecified(false), NoEscape(false), |
| RawRetainCountConvention() {} |
| |
| llvm::Optional<bool> isNoEscape() const { |
| if (!NoEscapeSpecified) |
| return llvm::None; |
| return NoEscape; |
| } |
| void setNoEscape(llvm::Optional<bool> Value) { |
| NoEscapeSpecified = Value.hasValue(); |
| NoEscape = Value.hasValue() ? *Value : false; |
| } |
| |
| llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const { |
| if (!RawRetainCountConvention) |
| return llvm::None; |
| return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); |
| } |
| void |
| setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) { |
| RawRetainCountConvention = |
| Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0; |
| assert(getRetainCountConvention() == Value && "bitfield too small"); |
| } |
| |
| ParamInfo &operator|=(const ParamInfo &RHS) { |
| static_cast<VariableInfo &>(*this) |= RHS; |
| |
| if (!NoEscapeSpecified && RHS.NoEscapeSpecified) { |
| NoEscapeSpecified = true; |
| NoEscape = RHS.NoEscape; |
| } |
| |
| if (!RawRetainCountConvention) |
| RawRetainCountConvention = RHS.RawRetainCountConvention; |
| |
| return *this; |
| } |
| |
| friend bool operator==(const ParamInfo &, const ParamInfo &); |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) { |
| return static_cast<const VariableInfo &>(LHS) == RHS && |
| LHS.NoEscapeSpecified == RHS.NoEscapeSpecified && |
| LHS.NoEscape == RHS.NoEscape && |
| LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; |
| } |
| |
| inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// API notes for a function or method. |
| class FunctionInfo : public CommonEntityInfo { |
| private: |
| static constexpr const unsigned NullabilityKindMask = 0x3; |
| static constexpr const unsigned NullabilityKindSize = 2; |
| |
| static constexpr const unsigned ReturnInfoIndex = 0; |
| |
| public: |
| // If yes, we consider all types to be non-nullable unless otherwise noted. |
| // If this flag is not set, the pointer types are considered to have |
| // unknown nullability. |
| |
| /// Whether the signature has been audited with respect to nullability. |
| unsigned NullabilityAudited : 1; |
| |
| /// Number of types whose nullability is encoded with the NullabilityPayload. |
| unsigned NumAdjustedNullable : 8; |
| |
| /// A biased RetainCountConventionKind, where 0 means "unspecified". |
| unsigned RawRetainCountConvention : 3; |
| |
| // NullabilityKindSize bits are used to encode the nullability. The info |
| // about the return type is stored at position 0, followed by the nullability |
| // of the parameters. |
| |
| /// Stores the nullability of the return type and the parameters. |
| uint64_t NullabilityPayload = 0; |
| |
| /// The result type of this function, as a C type. |
| std::string ResultType; |
| |
| /// The function parameters. |
| std::vector<ParamInfo> Params; |
| |
| FunctionInfo() |
| : CommonEntityInfo(), NullabilityAudited(false), NumAdjustedNullable(0), |
| RawRetainCountConvention() {} |
| |
| static unsigned getMaxNullabilityIndex() { |
| return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize); |
| } |
| |
| void addTypeInfo(unsigned index, NullabilityKind kind) { |
| assert(index <= getMaxNullabilityIndex()); |
| assert(static_cast<unsigned>(kind) < NullabilityKindMask); |
| |
| NullabilityAudited = true; |
| if (NumAdjustedNullable < index + 1) |
| NumAdjustedNullable = index + 1; |
| |
| // Mask the bits. |
| NullabilityPayload &= |
| ~(NullabilityKindMask << (index * NullabilityKindSize)); |
| |
| // Set the value. |
| unsigned kindValue = (static_cast<unsigned>(kind)) |
| << (index * NullabilityKindSize); |
| NullabilityPayload |= kindValue; |
| } |
| |
| /// Adds the return type info. |
| void addReturnTypeInfo(NullabilityKind kind) { |
| addTypeInfo(ReturnInfoIndex, kind); |
| } |
| |
| /// Adds the parameter type info. |
| void addParamTypeInfo(unsigned index, NullabilityKind kind) { |
| addTypeInfo(index + 1, kind); |
| } |
| |
| NullabilityKind getParamTypeInfo(unsigned index) const { |
| return getTypeInfo(index + 1); |
| } |
| |
| NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); } |
| |
| llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const { |
| if (!RawRetainCountConvention) |
| return llvm::None; |
| return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); |
| } |
| void |
| setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) { |
| RawRetainCountConvention = |
| Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0; |
| assert(getRetainCountConvention() == Value && "bitfield too small"); |
| } |
| |
| friend bool operator==(const FunctionInfo &, const FunctionInfo &); |
| |
| private: |
| NullabilityKind getTypeInfo(unsigned index) const { |
| assert(NullabilityAudited && |
| "Checking the type adjustment on non-audited method."); |
| |
| // If we don't have info about this parameter, return the default. |
| if (index > NumAdjustedNullable) |
| return NullabilityKind::NonNull; |
| auto nullability = NullabilityPayload >> (index * NullabilityKindSize); |
| return static_cast<NullabilityKind>(nullability & NullabilityKindMask); |
| } |
| |
| public: |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { |
| return static_cast<const CommonEntityInfo &>(LHS) == RHS && |
| LHS.NullabilityAudited == RHS.NullabilityAudited && |
| LHS.NumAdjustedNullable == RHS.NumAdjustedNullable && |
| LHS.NullabilityPayload == RHS.NullabilityPayload && |
| LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params && |
| LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; |
| } |
| |
| inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes data for an Objective-C method. |
| class ObjCMethodInfo : public FunctionInfo { |
| public: |
| /// Whether this is a designated initializer of its class. |
| unsigned DesignatedInit : 1; |
| |
| /// Whether this is a required initializer. |
| unsigned RequiredInit : 1; |
| |
| ObjCMethodInfo() |
| : FunctionInfo(), DesignatedInit(false), RequiredInit(false) {} |
| |
| friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &); |
| |
| ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) { |
| // Merge Nullability. |
| if (!NullabilityAudited) { |
| if (auto Nullable = RHS.getDefaultNullability()) { |
| NullabilityAudited = true; |
| addTypeInfo(0, *Nullable); |
| } |
| } |
| return *this; |
| } |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); |
| }; |
| |
| inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { |
| return static_cast<const FunctionInfo &>(LHS) == RHS && |
| LHS.DesignatedInit == RHS.DesignatedInit && |
| LHS.RequiredInit == RHS.RequiredInit; |
| } |
| |
| inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes data for a global variable. |
| class GlobalVariableInfo : public VariableInfo { |
| public: |
| GlobalVariableInfo() : VariableInfo() {} |
| }; |
| |
| /// Describes API notes data for a global function. |
| class GlobalFunctionInfo : public FunctionInfo { |
| public: |
| GlobalFunctionInfo() : FunctionInfo() {} |
| }; |
| |
| /// Describes API notes data for an enumerator. |
| class EnumConstantInfo : public CommonEntityInfo { |
| public: |
| EnumConstantInfo() : CommonEntityInfo() {} |
| }; |
| |
| /// Describes API notes data for a tag. |
| class TagInfo : public CommonTypeInfo { |
| unsigned HasFlagEnum : 1; |
| unsigned IsFlagEnum : 1; |
| |
| public: |
| llvm::Optional<EnumExtensibilityKind> EnumExtensibility; |
| |
| TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) {} |
| |
| llvm::Optional<bool> isFlagEnum() const { |
| if (HasFlagEnum) |
| return IsFlagEnum; |
| return llvm::None; |
| } |
| void setFlagEnum(llvm::Optional<bool> Value) { |
| HasFlagEnum = Value.hasValue(); |
| IsFlagEnum = Value.hasValue() ? *Value : false; |
| } |
| |
| TagInfo &operator|=(const TagInfo &RHS) { |
| static_cast<CommonTypeInfo &>(*this) |= RHS; |
| |
| if (!HasFlagEnum && HasFlagEnum) |
| setFlagEnum(RHS.isFlagEnum()); |
| |
| if (!EnumExtensibility.hasValue()) |
| EnumExtensibility = RHS.EnumExtensibility; |
| |
| return *this; |
| } |
| |
| friend bool operator==(const TagInfo &, const TagInfo &); |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); |
| }; |
| |
| inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) { |
| return static_cast<const CommonTypeInfo &>(LHS) == RHS && |
| LHS.isFlagEnum() == RHS.isFlagEnum() && |
| LHS.EnumExtensibility == RHS.EnumExtensibility; |
| } |
| |
| inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| |
| /// Describes API notes data for a typedef. |
| class TypedefInfo : public CommonTypeInfo { |
| public: |
| llvm::Optional<SwiftNewTypeKind> SwiftWrapper; |
| |
| TypedefInfo() : CommonTypeInfo() {} |
| |
| TypedefInfo &operator|=(const TypedefInfo &RHS) { |
| static_cast<CommonTypeInfo &>(*this) |= RHS; |
| if (!SwiftWrapper.hasValue()) |
| SwiftWrapper = RHS.SwiftWrapper; |
| return *this; |
| } |
| |
| friend bool operator==(const TypedefInfo &, const TypedefInfo &); |
| |
| LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; |
| }; |
| |
| inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) { |
| return static_cast<const CommonTypeInfo &>(LHS) == RHS && |
| LHS.SwiftWrapper == RHS.SwiftWrapper; |
| } |
| |
| inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) { |
| return !(LHS == RHS); |
| } |
| } // namespace api_notes |
| } // namespace clang |
| |
| #endif |