blob: 93bb045d6a667046239bccff8deb83dc479d2f6e [file] [log] [blame]
//===-- 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/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include <climits>
#include <optional>
#include <vector>
namespace llvm {
class raw_ostream;
} // namespace llvm
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.
LLVM_PREFERRED_TYPE(bool)
unsigned Unavailable : 1;
/// Whether this entity is marked unavailable in Swift.
LLVM_PREFERRED_TYPE(bool)
unsigned UnavailableInSwift : 1;
private:
/// Whether SwiftPrivate was specified.
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftPrivateSpecified : 1;
/// Whether this entity is considered "private" to a Swift overlay.
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftPrivate : 1;
public:
/// Swift name of this entity.
std::string SwiftName;
CommonEntityInfo()
: Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
SwiftPrivate(0) {}
std::optional<bool> isSwiftPrivate() const {
return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
: std::nullopt;
}
void setSwiftPrivate(std::optional<bool> Private) {
SwiftPrivateSpecified = Private.has_value();
SwiftPrivate = Private.value_or(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.
std::optional<std::string> SwiftBridge;
/// The NS error domain for this type.
std::optional<std::string> NSErrorDomain;
public:
CommonTypeInfo() {}
const std::optional<std::string> &getSwiftBridge() const {
return SwiftBridge;
}
void setSwiftBridge(std::optional<std::string> SwiftType) {
SwiftBridge = SwiftType;
}
const std::optional<std::string> &getNSErrorDomain() const {
return NSErrorDomain;
}
void setNSErrorDomain(const std::optional<std::string> &Domain) {
NSErrorDomain = Domain;
}
void setNSErrorDomain(const std::optional<llvm::StringRef> &Domain) {
NSErrorDomain = Domain ? std::optional<std::string>(std::string(*Domain))
: std::nullopt;
}
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.
LLVM_PREFERRED_TYPE(bool)
unsigned HasDefaultNullability : 1;
/// The default nullability.
LLVM_PREFERRED_TYPE(NullabilityKind)
unsigned DefaultNullability : 2;
/// Whether this class has designated initializers recorded.
LLVM_PREFERRED_TYPE(bool)
unsigned HasDesignatedInits : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftImportAsNonGenericSpecified : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftImportAsNonGeneric : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftObjCMembersSpecified : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftObjCMembers : 1;
public:
ObjCContextInfo()
: 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.
///
/// Returns the default nullability, if implied, or std::nullopt if there is
/// none.
std::optional<NullabilityKind> getDefaultNullability() const {
return HasDefaultNullability
? std::optional<NullabilityKind>(
static_cast<NullabilityKind>(DefaultNullability))
: std::nullopt;
}
/// 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; }
std::optional<bool> getSwiftImportAsNonGeneric() const {
return SwiftImportAsNonGenericSpecified
? std::optional<bool>(SwiftImportAsNonGeneric)
: std::nullopt;
}
void setSwiftImportAsNonGeneric(std::optional<bool> Value) {
SwiftImportAsNonGenericSpecified = Value.has_value();
SwiftImportAsNonGeneric = Value.value_or(false);
}
std::optional<bool> getSwiftObjCMembers() const {
return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers)
: std::nullopt;
}
void setSwiftObjCMembers(std::optional<bool> Value) {
SwiftObjCMembersSpecified = Value.has_value();
SwiftObjCMembers = Value.value_or(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.
LLVM_PREFERRED_TYPE(bool)
unsigned NullabilityAudited : 1;
/// The kind of nullability for this property. Only valid if the nullability
/// has been audited.
LLVM_PREFERRED_TYPE(NullabilityKind)
unsigned Nullable : 2;
/// The C type of the variable, as a string.
std::string Type;
public:
VariableInfo() : NullabilityAudited(false), Nullable(0) {}
std::optional<NullabilityKind> getNullability() const {
return NullabilityAudited ? std::optional<NullabilityKind>(
static_cast<NullabilityKind>(Nullable))
: std::nullopt;
}
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 {
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftImportAsAccessorsSpecified : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftImportAsAccessors : 1;
public:
ObjCPropertyInfo()
: SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
std::optional<bool> getSwiftImportAsAccessors() const {
return SwiftImportAsAccessorsSpecified
? std::optional<bool>(SwiftImportAsAccessors)
: std::nullopt;
}
void setSwiftImportAsAccessors(std::optional<bool> Value) {
SwiftImportAsAccessorsSpecified = Value.has_value();
SwiftImportAsAccessors = Value.value_or(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.
LLVM_PREFERRED_TYPE(bool)
unsigned NoEscapeSpecified : 1;
/// Whether the this parameter has the 'noescape' attribute.
LLVM_PREFERRED_TYPE(bool)
unsigned NoEscape : 1;
/// A biased RetainCountConventionKind, where 0 means "unspecified".
///
/// Only relevant for out-parameters.
unsigned RawRetainCountConvention : 3;
public:
ParamInfo()
: NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {}
std::optional<bool> isNoEscape() const {
if (!NoEscapeSpecified)
return std::nullopt;
return NoEscape;
}
void setNoEscape(std::optional<bool> Value) {
NoEscapeSpecified = Value.has_value();
NoEscape = Value.value_or(false);
}
std::optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
return std::nullopt;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 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 uint64_t 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.
LLVM_PREFERRED_TYPE(bool)
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()
: 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); }
std::optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
return std::nullopt;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 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.
LLVM_PREFERRED_TYPE(bool)
unsigned DesignatedInit : 1;
/// Whether this is a required initializer.
LLVM_PREFERRED_TYPE(bool)
unsigned RequiredInit : 1;
ObjCMethodInfo() : 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() {}
};
/// Describes API notes data for a global function.
class GlobalFunctionInfo : public FunctionInfo {
public:
GlobalFunctionInfo() {}
};
/// Describes API notes data for an enumerator.
class EnumConstantInfo : public CommonEntityInfo {
public:
EnumConstantInfo() {}
};
/// Describes API notes data for a tag.
class TagInfo : public CommonTypeInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned HasFlagEnum : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned IsFlagEnum : 1;
public:
std::optional<std::string> SwiftImportAs;
std::optional<std::string> SwiftRetainOp;
std::optional<std::string> SwiftReleaseOp;
std::optional<EnumExtensibilityKind> EnumExtensibility;
TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
std::optional<bool> isFlagEnum() const {
if (HasFlagEnum)
return IsFlagEnum;
return std::nullopt;
}
void setFlagEnum(std::optional<bool> Value) {
HasFlagEnum = Value.has_value();
IsFlagEnum = Value.value_or(false);
}
TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
if (!SwiftImportAs)
SwiftImportAs = RHS.SwiftImportAs;
if (!SwiftRetainOp)
SwiftRetainOp = RHS.SwiftRetainOp;
if (!SwiftReleaseOp)
SwiftReleaseOp = RHS.SwiftReleaseOp;
if (!HasFlagEnum)
setFlagEnum(RHS.isFlagEnum());
if (!EnumExtensibility)
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.SwiftImportAs == RHS.SwiftImportAs &&
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
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:
std::optional<SwiftNewTypeKind> SwiftWrapper;
TypedefInfo() {}
TypedefInfo &operator|=(const TypedefInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
if (!SwiftWrapper)
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);
}
/// The file extension used for the source representation of API notes.
static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes";
/// Opaque context ID used to refer to an Objective-C class or protocol or a C++
/// namespace.
class ContextID {
public:
unsigned Value;
explicit ContextID(unsigned value) : Value(value) {}
};
enum class ContextKind : uint8_t {
ObjCClass = 0,
ObjCProtocol = 1,
Namespace = 2,
};
struct Context {
ContextID id;
ContextKind kind;
Context(ContextID id, ContextKind kind) : id(id), kind(kind) {}
};
/// A temporary reference to an Objective-C selector, suitable for
/// referencing selector data on the stack.
///
/// Instances of this struct do not store references to any of the
/// data they contain; it is up to the user to ensure that the data
/// referenced by the identifier list persists.
struct ObjCSelectorRef {
unsigned NumArgs;
llvm::ArrayRef<llvm::StringRef> Identifiers;
};
} // namespace api_notes
} // namespace clang
#endif