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