1e8d8bef9SDimitry Andric //===-- APINotesYAMLCompiler.cpp - API Notes YAML Format Reader -*- C++ -*-===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric // 9e8d8bef9SDimitry Andric // The types defined locally are designed to represent the YAML state, which 10e8d8bef9SDimitry Andric // adds an additional bit of state: e.g. a tri-state boolean attribute (yes, no, 11e8d8bef9SDimitry Andric // not applied) becomes a tri-state boolean + present. As a result, while these 12e8d8bef9SDimitry Andric // enumerations appear to be redefining constants from the attributes table 13e8d8bef9SDimitry Andric // data, they are distinct. 14e8d8bef9SDimitry Andric // 15e8d8bef9SDimitry Andric 16e8d8bef9SDimitry Andric #include "clang/APINotes/APINotesYAMLCompiler.h" 17e8d8bef9SDimitry Andric #include "clang/APINotes/Types.h" 18e8d8bef9SDimitry Andric #include "clang/Basic/LLVM.h" 19e8d8bef9SDimitry Andric #include "clang/Basic/Specifiers.h" 20e8d8bef9SDimitry Andric #include "llvm/ADT/Optional.h" 21e8d8bef9SDimitry Andric #include "llvm/Support/VersionTuple.h" 22e8d8bef9SDimitry Andric #include "llvm/Support/YAMLParser.h" 23e8d8bef9SDimitry Andric #include "llvm/Support/YAMLTraits.h" 24e8d8bef9SDimitry Andric #include <vector> 25e8d8bef9SDimitry Andric using namespace clang; 26e8d8bef9SDimitry Andric using namespace api_notes; 27e8d8bef9SDimitry Andric 28e8d8bef9SDimitry Andric namespace { 29e8d8bef9SDimitry Andric enum class APIAvailability { 30e8d8bef9SDimitry Andric Available = 0, 31e8d8bef9SDimitry Andric OSX, 32e8d8bef9SDimitry Andric IOS, 33e8d8bef9SDimitry Andric None, 34e8d8bef9SDimitry Andric NonSwift, 35e8d8bef9SDimitry Andric }; 36e8d8bef9SDimitry Andric } // namespace 37e8d8bef9SDimitry Andric 38e8d8bef9SDimitry Andric namespace llvm { 39e8d8bef9SDimitry Andric namespace yaml { 40e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<APIAvailability> { 41e8d8bef9SDimitry Andric static void enumeration(IO &IO, APIAvailability &AA) { 42e8d8bef9SDimitry Andric IO.enumCase(AA, "OSX", APIAvailability::OSX); 43e8d8bef9SDimitry Andric IO.enumCase(AA, "iOS", APIAvailability::IOS); 44e8d8bef9SDimitry Andric IO.enumCase(AA, "none", APIAvailability::None); 45e8d8bef9SDimitry Andric IO.enumCase(AA, "nonswift", APIAvailability::NonSwift); 46e8d8bef9SDimitry Andric IO.enumCase(AA, "available", APIAvailability::Available); 47e8d8bef9SDimitry Andric } 48e8d8bef9SDimitry Andric }; 49e8d8bef9SDimitry Andric } // namespace yaml 50e8d8bef9SDimitry Andric } // namespace llvm 51e8d8bef9SDimitry Andric 52e8d8bef9SDimitry Andric namespace { 53e8d8bef9SDimitry Andric enum class MethodKind { 54e8d8bef9SDimitry Andric Class, 55e8d8bef9SDimitry Andric Instance, 56e8d8bef9SDimitry Andric }; 57e8d8bef9SDimitry Andric } // namespace 58e8d8bef9SDimitry Andric 59e8d8bef9SDimitry Andric namespace llvm { 60e8d8bef9SDimitry Andric namespace yaml { 61e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<MethodKind> { 62e8d8bef9SDimitry Andric static void enumeration(IO &IO, MethodKind &MK) { 63e8d8bef9SDimitry Andric IO.enumCase(MK, "Class", MethodKind::Class); 64e8d8bef9SDimitry Andric IO.enumCase(MK, "Instance", MethodKind::Instance); 65e8d8bef9SDimitry Andric } 66e8d8bef9SDimitry Andric }; 67e8d8bef9SDimitry Andric } // namespace yaml 68e8d8bef9SDimitry Andric } // namespace llvm 69e8d8bef9SDimitry Andric 70e8d8bef9SDimitry Andric namespace { 71e8d8bef9SDimitry Andric struct Param { 72e8d8bef9SDimitry Andric unsigned Position; 73e8d8bef9SDimitry Andric Optional<bool> NoEscape = false; 74e8d8bef9SDimitry Andric Optional<NullabilityKind> Nullability; 75e8d8bef9SDimitry Andric Optional<RetainCountConventionKind> RetainCountConvention; 76e8d8bef9SDimitry Andric StringRef Type; 77e8d8bef9SDimitry Andric }; 78e8d8bef9SDimitry Andric 79e8d8bef9SDimitry Andric typedef std::vector<Param> ParamsSeq; 80e8d8bef9SDimitry Andric } // namespace 81e8d8bef9SDimitry Andric 82e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Param) 83e8d8bef9SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind) 84e8d8bef9SDimitry Andric 85e8d8bef9SDimitry Andric namespace llvm { 86e8d8bef9SDimitry Andric namespace yaml { 87e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<NullabilityKind> { 88e8d8bef9SDimitry Andric static void enumeration(IO &IO, NullabilityKind &NK) { 89e8d8bef9SDimitry Andric IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull); 90e8d8bef9SDimitry Andric IO.enumCase(NK, "Optional", NullabilityKind::Nullable); 91e8d8bef9SDimitry Andric IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified); 92e8d8bef9SDimitry Andric IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult); 93e8d8bef9SDimitry Andric // TODO: Mapping this to it's own value would allow for better cross 94e8d8bef9SDimitry Andric // checking. Also the default should be Unknown. 95e8d8bef9SDimitry Andric IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified); 96e8d8bef9SDimitry Andric 97e8d8bef9SDimitry Andric // Aliases for compatibility with existing APINotes. 98e8d8bef9SDimitry Andric IO.enumCase(NK, "N", NullabilityKind::NonNull); 99e8d8bef9SDimitry Andric IO.enumCase(NK, "O", NullabilityKind::Nullable); 100e8d8bef9SDimitry Andric IO.enumCase(NK, "U", NullabilityKind::Unspecified); 101e8d8bef9SDimitry Andric IO.enumCase(NK, "S", NullabilityKind::Unspecified); 102e8d8bef9SDimitry Andric } 103e8d8bef9SDimitry Andric }; 104e8d8bef9SDimitry Andric 105e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<RetainCountConventionKind> { 106e8d8bef9SDimitry Andric static void enumeration(IO &IO, RetainCountConventionKind &RCCK) { 107e8d8bef9SDimitry Andric IO.enumCase(RCCK, "none", RetainCountConventionKind::None); 108e8d8bef9SDimitry Andric IO.enumCase(RCCK, "CFReturnsRetained", 109e8d8bef9SDimitry Andric RetainCountConventionKind::CFReturnsRetained); 110e8d8bef9SDimitry Andric IO.enumCase(RCCK, "CFReturnsNotRetained", 111e8d8bef9SDimitry Andric RetainCountConventionKind::CFReturnsNotRetained); 112e8d8bef9SDimitry Andric IO.enumCase(RCCK, "NSReturnsRetained", 113e8d8bef9SDimitry Andric RetainCountConventionKind::NSReturnsRetained); 114e8d8bef9SDimitry Andric IO.enumCase(RCCK, "NSReturnsNotRetained", 115e8d8bef9SDimitry Andric RetainCountConventionKind::NSReturnsNotRetained); 116e8d8bef9SDimitry Andric } 117e8d8bef9SDimitry Andric }; 118e8d8bef9SDimitry Andric 119e8d8bef9SDimitry Andric template <> struct MappingTraits<Param> { 120e8d8bef9SDimitry Andric static void mapping(IO &IO, Param &P) { 121e8d8bef9SDimitry Andric IO.mapRequired("Position", P.Position); 122e8d8bef9SDimitry Andric IO.mapOptional("Nullability", P.Nullability, llvm::None); 123e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", P.RetainCountConvention); 124e8d8bef9SDimitry Andric IO.mapOptional("NoEscape", P.NoEscape); 125e8d8bef9SDimitry Andric IO.mapOptional("Type", P.Type, StringRef("")); 126e8d8bef9SDimitry Andric } 127e8d8bef9SDimitry Andric }; 128e8d8bef9SDimitry Andric } // namespace yaml 129e8d8bef9SDimitry Andric } // namespace llvm 130e8d8bef9SDimitry Andric 131e8d8bef9SDimitry Andric namespace { 132e8d8bef9SDimitry Andric typedef std::vector<NullabilityKind> NullabilitySeq; 133e8d8bef9SDimitry Andric 134e8d8bef9SDimitry Andric struct AvailabilityItem { 135e8d8bef9SDimitry Andric APIAvailability Mode = APIAvailability::Available; 136e8d8bef9SDimitry Andric StringRef Msg; 137e8d8bef9SDimitry Andric }; 138e8d8bef9SDimitry Andric 139e8d8bef9SDimitry Andric /// Old attribute deprecated in favor of SwiftName. 140e8d8bef9SDimitry Andric enum class FactoryAsInitKind { 141e8d8bef9SDimitry Andric /// Infer based on name and type (the default). 142e8d8bef9SDimitry Andric Infer, 143e8d8bef9SDimitry Andric /// Treat as a class method. 144e8d8bef9SDimitry Andric AsClassMethod, 145e8d8bef9SDimitry Andric /// Treat as an initializer. 146e8d8bef9SDimitry Andric AsInitializer, 147e8d8bef9SDimitry Andric }; 148e8d8bef9SDimitry Andric 149e8d8bef9SDimitry Andric struct Method { 150e8d8bef9SDimitry Andric StringRef Selector; 151e8d8bef9SDimitry Andric MethodKind Kind; 152e8d8bef9SDimitry Andric ParamsSeq Params; 153e8d8bef9SDimitry Andric NullabilitySeq Nullability; 154e8d8bef9SDimitry Andric Optional<NullabilityKind> NullabilityOfRet; 155e8d8bef9SDimitry Andric Optional<RetainCountConventionKind> RetainCountConvention; 156e8d8bef9SDimitry Andric AvailabilityItem Availability; 157e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 158e8d8bef9SDimitry Andric StringRef SwiftName; 159e8d8bef9SDimitry Andric FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer; 160e8d8bef9SDimitry Andric bool DesignatedInit = false; 161e8d8bef9SDimitry Andric bool Required = false; 162e8d8bef9SDimitry Andric StringRef ResultType; 163e8d8bef9SDimitry Andric }; 164e8d8bef9SDimitry Andric 165e8d8bef9SDimitry Andric typedef std::vector<Method> MethodsSeq; 166e8d8bef9SDimitry Andric } // namespace 167e8d8bef9SDimitry Andric 168e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Method) 169e8d8bef9SDimitry Andric 170e8d8bef9SDimitry Andric namespace llvm { 171e8d8bef9SDimitry Andric namespace yaml { 172e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<FactoryAsInitKind> { 173e8d8bef9SDimitry Andric static void enumeration(IO &IO, FactoryAsInitKind &FIK) { 174e8d8bef9SDimitry Andric IO.enumCase(FIK, "A", FactoryAsInitKind::Infer); 175e8d8bef9SDimitry Andric IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod); 176e8d8bef9SDimitry Andric IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer); 177e8d8bef9SDimitry Andric } 178e8d8bef9SDimitry Andric }; 179e8d8bef9SDimitry Andric 180e8d8bef9SDimitry Andric template <> struct MappingTraits<Method> { 181e8d8bef9SDimitry Andric static void mapping(IO &IO, Method &M) { 182e8d8bef9SDimitry Andric IO.mapRequired("Selector", M.Selector); 183e8d8bef9SDimitry Andric IO.mapRequired("MethodKind", M.Kind); 184e8d8bef9SDimitry Andric IO.mapOptional("Parameters", M.Params); 185e8d8bef9SDimitry Andric IO.mapOptional("Nullability", M.Nullability); 186e8d8bef9SDimitry Andric IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, llvm::None); 187e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", M.RetainCountConvention); 188e8d8bef9SDimitry Andric IO.mapOptional("Availability", M.Availability.Mode, 189e8d8bef9SDimitry Andric APIAvailability::Available); 190e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef("")); 191e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", M.SwiftPrivate); 192e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", M.SwiftName, StringRef("")); 193e8d8bef9SDimitry Andric IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer); 194e8d8bef9SDimitry Andric IO.mapOptional("DesignatedInit", M.DesignatedInit, false); 195e8d8bef9SDimitry Andric IO.mapOptional("Required", M.Required, false); 196e8d8bef9SDimitry Andric IO.mapOptional("ResultType", M.ResultType, StringRef("")); 197e8d8bef9SDimitry Andric } 198e8d8bef9SDimitry Andric }; 199e8d8bef9SDimitry Andric } // namespace yaml 200e8d8bef9SDimitry Andric } // namespace llvm 201e8d8bef9SDimitry Andric 202e8d8bef9SDimitry Andric namespace { 203e8d8bef9SDimitry Andric struct Property { 204e8d8bef9SDimitry Andric StringRef Name; 205e8d8bef9SDimitry Andric llvm::Optional<MethodKind> Kind; 206e8d8bef9SDimitry Andric llvm::Optional<NullabilityKind> Nullability; 207e8d8bef9SDimitry Andric AvailabilityItem Availability; 208e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 209e8d8bef9SDimitry Andric StringRef SwiftName; 210e8d8bef9SDimitry Andric Optional<bool> SwiftImportAsAccessors; 211e8d8bef9SDimitry Andric StringRef Type; 212e8d8bef9SDimitry Andric }; 213e8d8bef9SDimitry Andric 214e8d8bef9SDimitry Andric typedef std::vector<Property> PropertiesSeq; 215e8d8bef9SDimitry Andric } // namespace 216e8d8bef9SDimitry Andric 217e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Property) 218e8d8bef9SDimitry Andric 219e8d8bef9SDimitry Andric namespace llvm { 220e8d8bef9SDimitry Andric namespace yaml { 221e8d8bef9SDimitry Andric template <> struct MappingTraits<Property> { 222e8d8bef9SDimitry Andric static void mapping(IO &IO, Property &P) { 223e8d8bef9SDimitry Andric IO.mapRequired("Name", P.Name); 224e8d8bef9SDimitry Andric IO.mapOptional("PropertyKind", P.Kind); 225e8d8bef9SDimitry Andric IO.mapOptional("Nullability", P.Nullability, llvm::None); 226e8d8bef9SDimitry Andric IO.mapOptional("Availability", P.Availability.Mode, 227e8d8bef9SDimitry Andric APIAvailability::Available); 228e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef("")); 229e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", P.SwiftPrivate); 230e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", P.SwiftName, StringRef("")); 231e8d8bef9SDimitry Andric IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors); 232e8d8bef9SDimitry Andric IO.mapOptional("Type", P.Type, StringRef("")); 233e8d8bef9SDimitry Andric } 234e8d8bef9SDimitry Andric }; 235e8d8bef9SDimitry Andric } // namespace yaml 236e8d8bef9SDimitry Andric } // namespace llvm 237e8d8bef9SDimitry Andric 238e8d8bef9SDimitry Andric namespace { 239e8d8bef9SDimitry Andric struct Class { 240e8d8bef9SDimitry Andric StringRef Name; 241e8d8bef9SDimitry Andric bool AuditedForNullability = false; 242e8d8bef9SDimitry Andric AvailabilityItem Availability; 243e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 244e8d8bef9SDimitry Andric StringRef SwiftName; 245e8d8bef9SDimitry Andric Optional<StringRef> SwiftBridge; 246e8d8bef9SDimitry Andric Optional<StringRef> NSErrorDomain; 247e8d8bef9SDimitry Andric Optional<bool> SwiftImportAsNonGeneric; 248e8d8bef9SDimitry Andric Optional<bool> SwiftObjCMembers; 249e8d8bef9SDimitry Andric MethodsSeq Methods; 250e8d8bef9SDimitry Andric PropertiesSeq Properties; 251e8d8bef9SDimitry Andric }; 252e8d8bef9SDimitry Andric 253e8d8bef9SDimitry Andric typedef std::vector<Class> ClassesSeq; 254e8d8bef9SDimitry Andric } // namespace 255e8d8bef9SDimitry Andric 256e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Class) 257e8d8bef9SDimitry Andric 258e8d8bef9SDimitry Andric namespace llvm { 259e8d8bef9SDimitry Andric namespace yaml { 260e8d8bef9SDimitry Andric template <> struct MappingTraits<Class> { 261e8d8bef9SDimitry Andric static void mapping(IO &IO, Class &C) { 262e8d8bef9SDimitry Andric IO.mapRequired("Name", C.Name); 263e8d8bef9SDimitry Andric IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false); 264e8d8bef9SDimitry Andric IO.mapOptional("Availability", C.Availability.Mode, 265e8d8bef9SDimitry Andric APIAvailability::Available); 266e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef("")); 267e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", C.SwiftPrivate); 268e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", C.SwiftName, StringRef("")); 269e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", C.SwiftBridge); 270e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", C.NSErrorDomain); 271e8d8bef9SDimitry Andric IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric); 272e8d8bef9SDimitry Andric IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers); 273e8d8bef9SDimitry Andric IO.mapOptional("Methods", C.Methods); 274e8d8bef9SDimitry Andric IO.mapOptional("Properties", C.Properties); 275e8d8bef9SDimitry Andric } 276e8d8bef9SDimitry Andric }; 277e8d8bef9SDimitry Andric } // namespace yaml 278e8d8bef9SDimitry Andric } // namespace llvm 279e8d8bef9SDimitry Andric 280e8d8bef9SDimitry Andric namespace { 281e8d8bef9SDimitry Andric struct Function { 282e8d8bef9SDimitry Andric StringRef Name; 283e8d8bef9SDimitry Andric ParamsSeq Params; 284e8d8bef9SDimitry Andric NullabilitySeq Nullability; 285e8d8bef9SDimitry Andric Optional<NullabilityKind> NullabilityOfRet; 286e8d8bef9SDimitry Andric Optional<api_notes::RetainCountConventionKind> RetainCountConvention; 287e8d8bef9SDimitry Andric AvailabilityItem Availability; 288e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 289e8d8bef9SDimitry Andric StringRef SwiftName; 290e8d8bef9SDimitry Andric StringRef Type; 291e8d8bef9SDimitry Andric StringRef ResultType; 292e8d8bef9SDimitry Andric }; 293e8d8bef9SDimitry Andric 294e8d8bef9SDimitry Andric typedef std::vector<Function> FunctionsSeq; 295e8d8bef9SDimitry Andric } // namespace 296e8d8bef9SDimitry Andric 297e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Function) 298e8d8bef9SDimitry Andric 299e8d8bef9SDimitry Andric namespace llvm { 300e8d8bef9SDimitry Andric namespace yaml { 301e8d8bef9SDimitry Andric template <> struct MappingTraits<Function> { 302e8d8bef9SDimitry Andric static void mapping(IO &IO, Function &F) { 303e8d8bef9SDimitry Andric IO.mapRequired("Name", F.Name); 304e8d8bef9SDimitry Andric IO.mapOptional("Parameters", F.Params); 305e8d8bef9SDimitry Andric IO.mapOptional("Nullability", F.Nullability); 306e8d8bef9SDimitry Andric IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, llvm::None); 307e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", F.RetainCountConvention); 308e8d8bef9SDimitry Andric IO.mapOptional("Availability", F.Availability.Mode, 309e8d8bef9SDimitry Andric APIAvailability::Available); 310e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef("")); 311e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", F.SwiftPrivate); 312e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", F.SwiftName, StringRef("")); 313e8d8bef9SDimitry Andric IO.mapOptional("ResultType", F.ResultType, StringRef("")); 314e8d8bef9SDimitry Andric } 315e8d8bef9SDimitry Andric }; 316e8d8bef9SDimitry Andric } // namespace yaml 317e8d8bef9SDimitry Andric } // namespace llvm 318e8d8bef9SDimitry Andric 319e8d8bef9SDimitry Andric namespace { 320e8d8bef9SDimitry Andric struct GlobalVariable { 321e8d8bef9SDimitry Andric StringRef Name; 322e8d8bef9SDimitry Andric llvm::Optional<NullabilityKind> Nullability; 323e8d8bef9SDimitry Andric AvailabilityItem Availability; 324e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 325e8d8bef9SDimitry Andric StringRef SwiftName; 326e8d8bef9SDimitry Andric StringRef Type; 327e8d8bef9SDimitry Andric }; 328e8d8bef9SDimitry Andric 329e8d8bef9SDimitry Andric typedef std::vector<GlobalVariable> GlobalVariablesSeq; 330e8d8bef9SDimitry Andric } // namespace 331e8d8bef9SDimitry Andric 332e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable) 333e8d8bef9SDimitry Andric 334e8d8bef9SDimitry Andric namespace llvm { 335e8d8bef9SDimitry Andric namespace yaml { 336e8d8bef9SDimitry Andric template <> struct MappingTraits<GlobalVariable> { 337e8d8bef9SDimitry Andric static void mapping(IO &IO, GlobalVariable &GV) { 338e8d8bef9SDimitry Andric IO.mapRequired("Name", GV.Name); 339e8d8bef9SDimitry Andric IO.mapOptional("Nullability", GV.Nullability, llvm::None); 340e8d8bef9SDimitry Andric IO.mapOptional("Availability", GV.Availability.Mode, 341e8d8bef9SDimitry Andric APIAvailability::Available); 342e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef("")); 343e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", GV.SwiftPrivate); 344e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", GV.SwiftName, StringRef("")); 345e8d8bef9SDimitry Andric IO.mapOptional("Type", GV.Type, StringRef("")); 346e8d8bef9SDimitry Andric } 347e8d8bef9SDimitry Andric }; 348e8d8bef9SDimitry Andric } // namespace yaml 349e8d8bef9SDimitry Andric } // namespace llvm 350e8d8bef9SDimitry Andric 351e8d8bef9SDimitry Andric namespace { 352e8d8bef9SDimitry Andric struct EnumConstant { 353e8d8bef9SDimitry Andric StringRef Name; 354e8d8bef9SDimitry Andric AvailabilityItem Availability; 355e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 356e8d8bef9SDimitry Andric StringRef SwiftName; 357e8d8bef9SDimitry Andric }; 358e8d8bef9SDimitry Andric 359e8d8bef9SDimitry Andric typedef std::vector<EnumConstant> EnumConstantsSeq; 360e8d8bef9SDimitry Andric } // namespace 361e8d8bef9SDimitry Andric 362e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant) 363e8d8bef9SDimitry Andric 364e8d8bef9SDimitry Andric namespace llvm { 365e8d8bef9SDimitry Andric namespace yaml { 366e8d8bef9SDimitry Andric template <> struct MappingTraits<EnumConstant> { 367e8d8bef9SDimitry Andric static void mapping(IO &IO, EnumConstant &EC) { 368e8d8bef9SDimitry Andric IO.mapRequired("Name", EC.Name); 369e8d8bef9SDimitry Andric IO.mapOptional("Availability", EC.Availability.Mode, 370e8d8bef9SDimitry Andric APIAvailability::Available); 371e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef("")); 372e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", EC.SwiftPrivate); 373e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", EC.SwiftName, StringRef("")); 374e8d8bef9SDimitry Andric } 375e8d8bef9SDimitry Andric }; 376e8d8bef9SDimitry Andric } // namespace yaml 377e8d8bef9SDimitry Andric } // namespace llvm 378e8d8bef9SDimitry Andric 379e8d8bef9SDimitry Andric namespace { 380e8d8bef9SDimitry Andric /// Syntactic sugar for EnumExtensibility and FlagEnum 381e8d8bef9SDimitry Andric enum class EnumConvenienceAliasKind { 382e8d8bef9SDimitry Andric /// EnumExtensibility: none, FlagEnum: false 383e8d8bef9SDimitry Andric None, 384e8d8bef9SDimitry Andric /// EnumExtensibility: open, FlagEnum: false 385e8d8bef9SDimitry Andric CFEnum, 386e8d8bef9SDimitry Andric /// EnumExtensibility: open, FlagEnum: true 387e8d8bef9SDimitry Andric CFOptions, 388e8d8bef9SDimitry Andric /// EnumExtensibility: closed, FlagEnum: false 389e8d8bef9SDimitry Andric CFClosedEnum 390e8d8bef9SDimitry Andric }; 391e8d8bef9SDimitry Andric } // namespace 392e8d8bef9SDimitry Andric 393e8d8bef9SDimitry Andric namespace llvm { 394e8d8bef9SDimitry Andric namespace yaml { 395e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> { 396e8d8bef9SDimitry Andric static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) { 397e8d8bef9SDimitry Andric IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None); 398e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum); 399e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum); 400e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions); 401e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions); 402e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum); 403e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum); 404e8d8bef9SDimitry Andric } 405e8d8bef9SDimitry Andric }; 406e8d8bef9SDimitry Andric } // namespace yaml 407e8d8bef9SDimitry Andric } // namespace llvm 408e8d8bef9SDimitry Andric 409e8d8bef9SDimitry Andric namespace { 410e8d8bef9SDimitry Andric struct Tag { 411e8d8bef9SDimitry Andric StringRef Name; 412e8d8bef9SDimitry Andric AvailabilityItem Availability; 413e8d8bef9SDimitry Andric StringRef SwiftName; 414e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 415e8d8bef9SDimitry Andric Optional<StringRef> SwiftBridge; 416e8d8bef9SDimitry Andric Optional<StringRef> NSErrorDomain; 417e8d8bef9SDimitry Andric Optional<EnumExtensibilityKind> EnumExtensibility; 418e8d8bef9SDimitry Andric Optional<bool> FlagEnum; 419e8d8bef9SDimitry Andric Optional<EnumConvenienceAliasKind> EnumConvenienceKind; 420e8d8bef9SDimitry Andric }; 421e8d8bef9SDimitry Andric 422e8d8bef9SDimitry Andric typedef std::vector<Tag> TagsSeq; 423e8d8bef9SDimitry Andric } // namespace 424e8d8bef9SDimitry Andric 425e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Tag) 426e8d8bef9SDimitry Andric 427e8d8bef9SDimitry Andric namespace llvm { 428e8d8bef9SDimitry Andric namespace yaml { 429e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> { 430e8d8bef9SDimitry Andric static void enumeration(IO &IO, EnumExtensibilityKind &EEK) { 431e8d8bef9SDimitry Andric IO.enumCase(EEK, "none", EnumExtensibilityKind::None); 432e8d8bef9SDimitry Andric IO.enumCase(EEK, "open", EnumExtensibilityKind::Open); 433e8d8bef9SDimitry Andric IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed); 434e8d8bef9SDimitry Andric } 435e8d8bef9SDimitry Andric }; 436e8d8bef9SDimitry Andric 437e8d8bef9SDimitry Andric template <> struct MappingTraits<Tag> { 438e8d8bef9SDimitry Andric static void mapping(IO &IO, Tag &T) { 439e8d8bef9SDimitry Andric IO.mapRequired("Name", T.Name); 440e8d8bef9SDimitry Andric IO.mapOptional("Availability", T.Availability.Mode, 441e8d8bef9SDimitry Andric APIAvailability::Available); 442e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef("")); 443e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", T.SwiftPrivate); 444e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", T.SwiftName, StringRef("")); 445e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", T.SwiftBridge); 446e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", T.NSErrorDomain); 447e8d8bef9SDimitry Andric IO.mapOptional("EnumExtensibility", T.EnumExtensibility); 448e8d8bef9SDimitry Andric IO.mapOptional("FlagEnum", T.FlagEnum); 449e8d8bef9SDimitry Andric IO.mapOptional("EnumKind", T.EnumConvenienceKind); 450e8d8bef9SDimitry Andric } 451e8d8bef9SDimitry Andric }; 452e8d8bef9SDimitry Andric } // namespace yaml 453e8d8bef9SDimitry Andric } // namespace llvm 454e8d8bef9SDimitry Andric 455e8d8bef9SDimitry Andric namespace { 456e8d8bef9SDimitry Andric struct Typedef { 457e8d8bef9SDimitry Andric StringRef Name; 458e8d8bef9SDimitry Andric AvailabilityItem Availability; 459e8d8bef9SDimitry Andric StringRef SwiftName; 460e8d8bef9SDimitry Andric Optional<bool> SwiftPrivate; 461e8d8bef9SDimitry Andric Optional<StringRef> SwiftBridge; 462e8d8bef9SDimitry Andric Optional<StringRef> NSErrorDomain; 463e8d8bef9SDimitry Andric Optional<SwiftNewTypeKind> SwiftType; 464e8d8bef9SDimitry Andric }; 465e8d8bef9SDimitry Andric 466e8d8bef9SDimitry Andric typedef std::vector<Typedef> TypedefsSeq; 467e8d8bef9SDimitry Andric } // namespace 468e8d8bef9SDimitry Andric 469e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef) 470e8d8bef9SDimitry Andric 471e8d8bef9SDimitry Andric namespace llvm { 472e8d8bef9SDimitry Andric namespace yaml { 473e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> { 474e8d8bef9SDimitry Andric static void enumeration(IO &IO, SwiftNewTypeKind &SWK) { 475e8d8bef9SDimitry Andric IO.enumCase(SWK, "none", SwiftNewTypeKind::None); 476e8d8bef9SDimitry Andric IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct); 477e8d8bef9SDimitry Andric IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum); 478e8d8bef9SDimitry Andric } 479e8d8bef9SDimitry Andric }; 480e8d8bef9SDimitry Andric 481e8d8bef9SDimitry Andric template <> struct MappingTraits<Typedef> { 482e8d8bef9SDimitry Andric static void mapping(IO &IO, Typedef &T) { 483e8d8bef9SDimitry Andric IO.mapRequired("Name", T.Name); 484e8d8bef9SDimitry Andric IO.mapOptional("Availability", T.Availability.Mode, 485e8d8bef9SDimitry Andric APIAvailability::Available); 486e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef("")); 487e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", T.SwiftPrivate); 488e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", T.SwiftName, StringRef("")); 489e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", T.SwiftBridge); 490e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", T.NSErrorDomain); 491e8d8bef9SDimitry Andric IO.mapOptional("SwiftWrapper", T.SwiftType); 492e8d8bef9SDimitry Andric } 493e8d8bef9SDimitry Andric }; 494e8d8bef9SDimitry Andric } // namespace yaml 495e8d8bef9SDimitry Andric } // namespace llvm 496e8d8bef9SDimitry Andric 497e8d8bef9SDimitry Andric namespace { 498e8d8bef9SDimitry Andric struct TopLevelItems { 499e8d8bef9SDimitry Andric ClassesSeq Classes; 500e8d8bef9SDimitry Andric ClassesSeq Protocols; 501e8d8bef9SDimitry Andric FunctionsSeq Functions; 502e8d8bef9SDimitry Andric GlobalVariablesSeq Globals; 503e8d8bef9SDimitry Andric EnumConstantsSeq EnumConstants; 504e8d8bef9SDimitry Andric TagsSeq Tags; 505e8d8bef9SDimitry Andric TypedefsSeq Typedefs; 506e8d8bef9SDimitry Andric }; 507e8d8bef9SDimitry Andric } // namespace 508e8d8bef9SDimitry Andric 509e8d8bef9SDimitry Andric namespace llvm { 510e8d8bef9SDimitry Andric namespace yaml { 511e8d8bef9SDimitry Andric static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) { 512e8d8bef9SDimitry Andric IO.mapOptional("Classes", TLI.Classes); 513e8d8bef9SDimitry Andric IO.mapOptional("Protocols", TLI.Protocols); 514e8d8bef9SDimitry Andric IO.mapOptional("Functions", TLI.Functions); 515e8d8bef9SDimitry Andric IO.mapOptional("Globals", TLI.Globals); 516e8d8bef9SDimitry Andric IO.mapOptional("Enumerators", TLI.EnumConstants); 517e8d8bef9SDimitry Andric IO.mapOptional("Tags", TLI.Tags); 518e8d8bef9SDimitry Andric IO.mapOptional("Typedefs", TLI.Typedefs); 519e8d8bef9SDimitry Andric } 520e8d8bef9SDimitry Andric } // namespace yaml 521e8d8bef9SDimitry Andric } // namespace llvm 522e8d8bef9SDimitry Andric 523e8d8bef9SDimitry Andric namespace { 524e8d8bef9SDimitry Andric struct Versioned { 525e8d8bef9SDimitry Andric VersionTuple Version; 526e8d8bef9SDimitry Andric TopLevelItems Items; 527e8d8bef9SDimitry Andric }; 528e8d8bef9SDimitry Andric 529e8d8bef9SDimitry Andric typedef std::vector<Versioned> VersionedSeq; 530e8d8bef9SDimitry Andric } // namespace 531e8d8bef9SDimitry Andric 532e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned) 533e8d8bef9SDimitry Andric 534e8d8bef9SDimitry Andric namespace llvm { 535e8d8bef9SDimitry Andric namespace yaml { 536e8d8bef9SDimitry Andric template <> struct MappingTraits<Versioned> { 537e8d8bef9SDimitry Andric static void mapping(IO &IO, Versioned &V) { 538e8d8bef9SDimitry Andric IO.mapRequired("Version", V.Version); 539e8d8bef9SDimitry Andric mapTopLevelItems(IO, V.Items); 540e8d8bef9SDimitry Andric } 541e8d8bef9SDimitry Andric }; 542e8d8bef9SDimitry Andric } // namespace yaml 543e8d8bef9SDimitry Andric } // namespace llvm 544e8d8bef9SDimitry Andric 545e8d8bef9SDimitry Andric namespace { 546e8d8bef9SDimitry Andric struct Module { 547e8d8bef9SDimitry Andric StringRef Name; 548e8d8bef9SDimitry Andric AvailabilityItem Availability; 549e8d8bef9SDimitry Andric TopLevelItems TopLevel; 550e8d8bef9SDimitry Andric VersionedSeq SwiftVersions; 551e8d8bef9SDimitry Andric 552e8d8bef9SDimitry Andric llvm::Optional<bool> SwiftInferImportAsMember = {llvm::None}; 553e8d8bef9SDimitry Andric 554*fe6060f1SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 555e8d8bef9SDimitry Andric LLVM_DUMP_METHOD void dump() /*const*/; 556*fe6060f1SDimitry Andric #endif 557e8d8bef9SDimitry Andric }; 558e8d8bef9SDimitry Andric } // namespace 559e8d8bef9SDimitry Andric 560e8d8bef9SDimitry Andric namespace llvm { 561e8d8bef9SDimitry Andric namespace yaml { 562e8d8bef9SDimitry Andric template <> struct MappingTraits<Module> { 563e8d8bef9SDimitry Andric static void mapping(IO &IO, Module &M) { 564e8d8bef9SDimitry Andric IO.mapRequired("Name", M.Name); 565e8d8bef9SDimitry Andric IO.mapOptional("Availability", M.Availability.Mode, 566e8d8bef9SDimitry Andric APIAvailability::Available); 567e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef("")); 568e8d8bef9SDimitry Andric IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember); 569e8d8bef9SDimitry Andric mapTopLevelItems(IO, M.TopLevel); 570e8d8bef9SDimitry Andric IO.mapOptional("SwiftVersions", M.SwiftVersions); 571e8d8bef9SDimitry Andric } 572e8d8bef9SDimitry Andric }; 573e8d8bef9SDimitry Andric } // namespace yaml 574e8d8bef9SDimitry Andric } // namespace llvm 575e8d8bef9SDimitry Andric 576*fe6060f1SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 577*fe6060f1SDimitry Andric LLVM_DUMP_METHOD void Module::dump() { 578e8d8bef9SDimitry Andric llvm::yaml::Output OS(llvm::errs()); 579e8d8bef9SDimitry Andric OS << *this; 580e8d8bef9SDimitry Andric } 581*fe6060f1SDimitry Andric #endif 582e8d8bef9SDimitry Andric 583e8d8bef9SDimitry Andric namespace { 584e8d8bef9SDimitry Andric bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag, 585e8d8bef9SDimitry Andric void *DiagContext) { 586e8d8bef9SDimitry Andric llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext); 587e8d8bef9SDimitry Andric IS >> M; 588e8d8bef9SDimitry Andric return static_cast<bool>(IS.error()); 589e8d8bef9SDimitry Andric } 590e8d8bef9SDimitry Andric } // namespace 591e8d8bef9SDimitry Andric 592e8d8bef9SDimitry Andric bool clang::api_notes::parseAndDumpAPINotes(StringRef YI, 593e8d8bef9SDimitry Andric llvm::raw_ostream &OS) { 594e8d8bef9SDimitry Andric Module M; 595e8d8bef9SDimitry Andric if (parseAPINotes(YI, M, nullptr, nullptr)) 596e8d8bef9SDimitry Andric return true; 597e8d8bef9SDimitry Andric 598e8d8bef9SDimitry Andric llvm::yaml::Output YOS(OS); 599e8d8bef9SDimitry Andric YOS << M; 600e8d8bef9SDimitry Andric 601e8d8bef9SDimitry Andric return false; 602e8d8bef9SDimitry Andric } 603