compnerd updated this revision to Diff 306487.
compnerd marked 5 inline comments as done.
compnerd added a comment.

Address review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91104/new/

https://reviews.llvm.org/D91104

Files:
  clang/include/clang/APINotes/Types.h
  clang/lib/APINotes/APINotesTypes.cpp
  clang/lib/APINotes/CMakeLists.txt

Index: clang/lib/APINotes/CMakeLists.txt
===================================================================
--- clang/lib/APINotes/CMakeLists.txt
+++ clang/lib/APINotes/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   Support)
 add_clang_library(clangAPINotes
+  APINotesTypes.cpp
   APINotesYAMLCompiler.cpp
   LINK_LIBS
     clangBasic)
Index: clang/lib/APINotes/APINotesTypes.cpp
===================================================================
--- /dev/null
+++ clang/lib/APINotes/APINotesTypes.cpp
@@ -0,0 +1,107 @@
+//===-- APINotesTypes.cpp - 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/APINotes/Types.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace api_notes {
+void CommonEntityInfo::dump(llvm::raw_ostream &OS) {
+  if (Unavailable)
+    OS << "[Unavailable] (" << UnavailableMsg << ")" << ' ';
+  if (UnavailableInSwift)
+    OS << "[UnavailableInSwift] ";
+  if (SwiftPrivateSpecified)
+    OS << (SwiftPrivate ? "[SwiftPrivate] " : "");
+  if (!SwiftName.empty())
+    OS << "Swift Name: " << SwiftName << ' ';
+  OS << '\n';
+}
+
+void CommonTypeInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonEntityInfo &>(*this).dump(OS);
+  if (SwiftBridge)
+    OS << "Swift Briged Type: " << *SwiftBridge << ' ';
+  if (NSErrorDomain)
+    OS << "NSError Domain: " << *NSErrorDomain << ' ';
+  OS << '\n';
+}
+
+void ObjCContextInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonTypeInfo &>(*this).dump(OS);
+  if (HasDefaultNullability)
+    OS << "DefaultNullability: " << DefaultNullability << ' ';
+  if (HasDesignatedInits)
+    OS << "[HasDesignatedInits] ";
+  if (SwiftImportAsNonGenericSpecified)
+    OS << (SwiftImportAsNonGeneric ? "[SwiftImportAsNonGeneric] " : "");
+  if (SwiftObjCMembersSpecified)
+    OS << (SwiftObjCMembers ? "[SwiftObjCMembers] " : "");
+  OS << '\n';
+}
+
+void VariableInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonEntityInfo &>(*this).dump(OS);
+  if (NullabilityAudited)
+    OS << "Audited Nullability: " << Nullable << ' ';
+  if (!Type.empty())
+    OS << "C Type: " << Type << ' ';
+  OS << '\n';
+}
+
+void ObjCPropertyInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<VariableInfo &>(*this).dump(OS);
+  if (SwiftImportAsAccessorsSpecified)
+    OS << (SwiftImportAsAccessors ? "[SwiftImportAsAccessors] " : "");
+  OS << '\n';
+}
+
+void ParamInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<VariableInfo &>(*this).dump(OS);
+  if (NoEscapeSpecified)
+    OS << (NoEscape ? "[NoEscape] " : "");
+  OS << "RawRetainCountConvention: " << RawRetainCountConvention << ' ';
+  OS << '\n';
+}
+
+void FunctionInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonEntityInfo &>(*this).dump(OS);
+  OS << (NullabilityAudited ? "[NullabilityAudited] " : "")
+     << "RawRetainCountConvention: " << RawRetainCountConvention << ' ';
+  if (!ResultType.empty())
+    OS << "Result Type: " << ResultType << ' ';
+  if (!Params.empty())
+    OS << '\n';
+  for (auto &PI : Params)
+    PI.dump(OS);
+}
+
+void ObjCMethodInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<FunctionInfo &>(*this).dump(OS);
+  OS << (DesignatedInit ? "[DesignatedInit] " : "")
+     << (RequiredInit ? "[RequiredInit] " : "") << '\n';
+}
+
+void TagInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonTypeInfo &>(*this).dump(OS);
+  if (HasFlagEnum)
+    OS << (IsFlagEnum ? "[FlagEnum] " : "");
+  if (EnumExtensibility)
+    OS << "Enum Extensibility: " << static_cast<long>(*EnumExtensibility)
+       << ' ';
+  OS << '\n';
+}
+
+void TypedefInfo::dump(llvm::raw_ostream &OS) {
+  static_cast<CommonTypeInfo &>(*this).dump(OS);
+  if (SwiftWrapper)
+    OS << "Swift Type: " << static_cast<long>(*SwiftWrapper) << ' ';
+  OS << '\n';
+}
+} // namespace api_notes
+} // namespace clang
Index: clang/include/clang/APINotes/Types.h
===================================================================
--- clang/include/clang/APINotes/Types.h
+++ clang/include/clang/APINotes/Types.h
@@ -9,6 +9,12 @@
 #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 {
@@ -34,6 +40,694 @@
   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);
+};
+
+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);
+};
+
+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);
+};
+
+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);
+};
+
+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);
+};
+
+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);
+};
+
+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);
+};
+
+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
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to