1166124Srafan//===-- APINotesYAMLCompiler.cpp - API Notes YAML Format Reader -*- C++ -*-===//
2166124Srafan//
3166124Srafan// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4166124Srafan// See https://llvm.org/LICENSE.txt for license information.
5166124Srafan// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6166124Srafan//
7166124Srafan//===----------------------------------------------------------------------===//
8166124Srafan//
9166124Srafan// The types defined locally are designed to represent the YAML state, which
10166124Srafan// adds an additional bit of state: e.g. a tri-state boolean attribute (yes, no,
11166124Srafan// not applied) becomes a tri-state boolean + present.  As a result, while these
12166124Srafan// enumerations appear to be redefining constants from the attributes table
13166124Srafan// data, they are distinct.
14166124Srafan//
15166124Srafan
16166124Srafan#include "clang/APINotes/APINotesYAMLCompiler.h"
17166124Srafan#include "clang/APINotes/Types.h"
18166124Srafan#include "clang/Basic/LLVM.h"
19166124Srafan#include "clang/Basic/Specifiers.h"
20166124Srafan#include "llvm/ADT/Optional.h"
21166124Srafan#include "llvm/Support/VersionTuple.h"
22166124Srafan#include "llvm/Support/YAMLParser.h"
23166124Srafan#include "llvm/Support/YAMLTraits.h"
24166124Srafan#include <vector>
25166124Srafanusing namespace clang;
26166124Srafanusing namespace api_notes;
27166124Srafan
28166124Srafannamespace {
2950276Speterenum class APIAvailability {
3050276Speter  Available = 0,
3150276Speter  OSX,
3250276Speter  IOS,
3350276Speter  None,
3450276Speter  NonSwift,
3550276Speter};
3650276Speter} // namespace
3750276Speter
3850276Speternamespace llvm {
3950276Speternamespace yaml {
4050276Spetertemplate <> struct ScalarEnumerationTraits<APIAvailability> {
4150276Speter  static void enumeration(IO &IO, APIAvailability &AA) {
4250276Speter    IO.enumCase(AA, "OSX", APIAvailability::OSX);
4350276Speter    IO.enumCase(AA, "iOS", APIAvailability::IOS);
4450276Speter    IO.enumCase(AA, "none", APIAvailability::None);
4550276Speter    IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);
4650276Speter    IO.enumCase(AA, "available", APIAvailability::Available);
4750276Speter  }
4850276Speter};
4950276Speter} // namespace yaml
5050276Speter} // namespace llvm
5150276Speter
5250276Speternamespace {
5350276Speterenum class MethodKind {
5450276Speter  Class,
5550276Speter  Instance,
5650276Speter};
5750276Speter} // namespace
5850276Speter
5950276Speternamespace llvm {
6050276Speternamespace yaml {
6150276Spetertemplate <> struct ScalarEnumerationTraits<MethodKind> {
6250276Speter  static void enumeration(IO &IO, MethodKind &MK) {
6350276Speter    IO.enumCase(MK, "Class", MethodKind::Class);
6450276Speter    IO.enumCase(MK, "Instance", MethodKind::Instance);
6550276Speter  }
6650276Speter};
6750276Speter} // namespace yaml
6850276Speter} // namespace llvm
6950276Speter
7050276Speternamespace {
7150276Speterstruct Param {
7250276Speter  unsigned Position;
7350276Speter  Optional<bool> NoEscape = false;
7450276Speter  Optional<NullabilityKind> Nullability;
7550276Speter  Optional<RetainCountConventionKind> RetainCountConvention;
7650276Speter  StringRef Type;
7750276Speter};
7850276Speter
7950276Spetertypedef std::vector<Param> ParamsSeq;
8050276Speter} // namespace
8150276Speter
8250276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Param)
8350276SpeterLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)
8450276Speter
8550276Speternamespace llvm {
8650276Speternamespace yaml {
8750276Spetertemplate <> struct ScalarEnumerationTraits<NullabilityKind> {
8850276Speter  static void enumeration(IO &IO, NullabilityKind &NK) {
8950276Speter    IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
9050276Speter    IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
9150276Speter    IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
9250276Speter    IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
9350276Speter    // TODO: Mapping this to it's own value would allow for better cross
9450276Speter    // checking. Also the default should be Unknown.
9550276Speter    IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);
9650276Speter
9750276Speter    // Aliases for compatibility with existing APINotes.
9850276Speter    IO.enumCase(NK, "N", NullabilityKind::NonNull);
9950276Speter    IO.enumCase(NK, "O", NullabilityKind::Nullable);
10050276Speter    IO.enumCase(NK, "U", NullabilityKind::Unspecified);
10150276Speter    IO.enumCase(NK, "S", NullabilityKind::Unspecified);
10250276Speter  }
10350276Speter};
10450276Speter
10550276Spetertemplate <> struct ScalarEnumerationTraits<RetainCountConventionKind> {
10650276Speter  static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {
10750276Speter    IO.enumCase(RCCK, "none", RetainCountConventionKind::None);
10850276Speter    IO.enumCase(RCCK, "CFReturnsRetained",
10950276Speter                RetainCountConventionKind::CFReturnsRetained);
11050276Speter    IO.enumCase(RCCK, "CFReturnsNotRetained",
11150276Speter                RetainCountConventionKind::CFReturnsNotRetained);
11250276Speter    IO.enumCase(RCCK, "NSReturnsRetained",
11350276Speter                RetainCountConventionKind::NSReturnsRetained);
11450276Speter    IO.enumCase(RCCK, "NSReturnsNotRetained",
115166124Srafan                RetainCountConventionKind::NSReturnsNotRetained);
11650276Speter  }
11750276Speter};
11850276Speter
11950276Spetertemplate <> struct MappingTraits<Param> {
12050276Speter  static void mapping(IO &IO, Param &P) {
12150276Speter    IO.mapRequired("Position", P.Position);
12250276Speter    IO.mapOptional("Nullability", P.Nullability, llvm::None);
12350276Speter    IO.mapOptional("RetainCountConvention", P.RetainCountConvention);
12450276Speter    IO.mapOptional("NoEscape", P.NoEscape);
12550276Speter    IO.mapOptional("Type", P.Type, StringRef(""));
12650276Speter  }
12750276Speter};
12850276Speter} // namespace yaml
12950276Speter} // namespace llvm
13050276Speter
13150276Speternamespace {
13250276Spetertypedef std::vector<NullabilityKind> NullabilitySeq;
13350276Speter
134166124Srafanstruct AvailabilityItem {
13550276Speter  APIAvailability Mode = APIAvailability::Available;
13650276Speter  StringRef Msg;
13750276Speter};
13850276Speter
13950276Speter/// Old attribute deprecated in favor of SwiftName.
14050276Speterenum class FactoryAsInitKind {
14150276Speter  /// Infer based on name and type (the default).
14250276Speter  Infer,
14350276Speter  /// Treat as a class method.
14450276Speter  AsClassMethod,
14550276Speter  /// Treat as an initializer.
146166124Srafan  AsInitializer,
147166124Srafan};
148166124Srafan
149166124Srafanstruct Method {
150166124Srafan  StringRef Selector;
151166124Srafan  MethodKind Kind;
152166124Srafan  ParamsSeq Params;
153166124Srafan  NullabilitySeq Nullability;
154166124Srafan  Optional<NullabilityKind> NullabilityOfRet;
155166124Srafan  Optional<RetainCountConventionKind> RetainCountConvention;
156166124Srafan  AvailabilityItem Availability;
15750276Speter  Optional<bool> SwiftPrivate;
15850276Speter  StringRef SwiftName;
15950276Speter  FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
16050276Speter  bool DesignatedInit = false;
16150276Speter  bool Required = false;
16250276Speter  StringRef ResultType;
16350276Speter};
16450276Speter
16550276Spetertypedef std::vector<Method> MethodsSeq;
16650276Speter} // namespace
16750276Speter
16850276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Method)
16950276Speter
17050276Speternamespace llvm {
17150276Speternamespace yaml {
17250276Spetertemplate <> struct ScalarEnumerationTraits<FactoryAsInitKind> {
17350276Speter  static void enumeration(IO &IO, FactoryAsInitKind &FIK) {
17450276Speter    IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);
17550276Speter    IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);
17650276Speter    IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);
17750276Speter  }
17850276Speter};
17950276Speter
18050276Spetertemplate <> struct MappingTraits<Method> {
18150276Speter  static void mapping(IO &IO, Method &M) {
18250276Speter    IO.mapRequired("Selector", M.Selector);
18350276Speter    IO.mapRequired("MethodKind", M.Kind);
18450276Speter    IO.mapOptional("Parameters", M.Params);
18550276Speter    IO.mapOptional("Nullability", M.Nullability);
18650276Speter    IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, llvm::None);
18750276Speter    IO.mapOptional("RetainCountConvention", M.RetainCountConvention);
18850276Speter    IO.mapOptional("Availability", M.Availability.Mode,
18950276Speter                   APIAvailability::Available);
19050276Speter    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
19150276Speter    IO.mapOptional("SwiftPrivate", M.SwiftPrivate);
19250276Speter    IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));
19350276Speter    IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
19450276Speter    IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
19550276Speter    IO.mapOptional("Required", M.Required, false);
19650276Speter    IO.mapOptional("ResultType", M.ResultType, StringRef(""));
19750276Speter  }
19850276Speter};
19950276Speter} // namespace yaml
20050276Speter} // namespace llvm
20150276Speter
20250276Speternamespace {
20350276Speterstruct Property {
20450276Speter  StringRef Name;
20550276Speter  llvm::Optional<MethodKind> Kind;
20650276Speter  llvm::Optional<NullabilityKind> Nullability;
20750276Speter  AvailabilityItem Availability;
20850276Speter  Optional<bool> SwiftPrivate;
20950276Speter  StringRef SwiftName;
21050276Speter  Optional<bool> SwiftImportAsAccessors;
21150276Speter  StringRef Type;
21250276Speter};
21350276Speter
21450276Spetertypedef std::vector<Property> PropertiesSeq;
21550276Speter} // namespace
21650276Speter
21750276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Property)
21850276Speter
21950276Speternamespace llvm {
22050276Speternamespace yaml {
22150276Spetertemplate <> struct MappingTraits<Property> {
22250276Speter  static void mapping(IO &IO, Property &P) {
22350276Speter    IO.mapRequired("Name", P.Name);
22450276Speter    IO.mapOptional("PropertyKind", P.Kind);
22550276Speter    IO.mapOptional("Nullability", P.Nullability, llvm::None);
22650276Speter    IO.mapOptional("Availability", P.Availability.Mode,
22750276Speter                   APIAvailability::Available);
22850276Speter    IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));
22950276Speter    IO.mapOptional("SwiftPrivate", P.SwiftPrivate);
23050276Speter    IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
23150276Speter    IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
23250276Speter    IO.mapOptional("Type", P.Type, StringRef(""));
23350276Speter  }
23466963Speter};
23550276Speter} // namespace yaml
23650276Speter} // namespace llvm
23750276Speter
23850276Speternamespace {
23950276Speterstruct Class {
24050276Speter  StringRef Name;
24150276Speter  bool AuditedForNullability = false;
24250276Speter  AvailabilityItem Availability;
24350276Speter  Optional<bool> SwiftPrivate;
24450276Speter  StringRef SwiftName;
24550276Speter  Optional<StringRef> SwiftBridge;
24650276Speter  Optional<StringRef> NSErrorDomain;
24750276Speter  Optional<bool> SwiftImportAsNonGeneric;
24850276Speter  Optional<bool> SwiftObjCMembers;
24950276Speter  MethodsSeq Methods;
250166124Srafan  PropertiesSeq Properties;
25150276Speter};
252166124Srafan
25350276Spetertypedef std::vector<Class> ClassesSeq;
25450276Speter} // namespace
25550276Speter
25650276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Class)
25750276Speter
25850276Speternamespace llvm {
25950276Speternamespace yaml {
26050276Spetertemplate <> struct MappingTraits<Class> {
26150276Speter  static void mapping(IO &IO, Class &C) {
26250276Speter    IO.mapRequired("Name", C.Name);
26350276Speter    IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);
26450276Speter    IO.mapOptional("Availability", C.Availability.Mode,
26550276Speter                   APIAvailability::Available);
26650276Speter    IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));
26750276Speter    IO.mapOptional("SwiftPrivate", C.SwiftPrivate);
26850276Speter    IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));
26950276Speter    IO.mapOptional("SwiftBridge", C.SwiftBridge);
27050276Speter    IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
27150276Speter    IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
27250276Speter    IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
27350276Speter    IO.mapOptional("Methods", C.Methods);
27450276Speter    IO.mapOptional("Properties", C.Properties);
27550276Speter  }
27650276Speter};
27750276Speter} // namespace yaml
27850276Speter} // namespace llvm
27950276Speter
28050276Speternamespace {
28150276Speterstruct Function {
28250276Speter  StringRef Name;
28350276Speter  ParamsSeq Params;
28450276Speter  NullabilitySeq Nullability;
28550276Speter  Optional<NullabilityKind> NullabilityOfRet;
28650276Speter  Optional<api_notes::RetainCountConventionKind> RetainCountConvention;
28750276Speter  AvailabilityItem Availability;
28850276Speter  Optional<bool> SwiftPrivate;
28950276Speter  StringRef SwiftName;
29050276Speter  StringRef Type;
29150276Speter  StringRef ResultType;
29250276Speter};
29350276Speter
29450276Spetertypedef std::vector<Function> FunctionsSeq;
29550276Speter} // namespace
29650276Speter
29750276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Function)
29850276Speter
29950276Speternamespace llvm {
30050276Speternamespace yaml {
30150276Spetertemplate <> struct MappingTraits<Function> {
30250276Speter  static void mapping(IO &IO, Function &F) {
30350276Speter    IO.mapRequired("Name", F.Name);
30450276Speter    IO.mapOptional("Parameters", F.Params);
30550276Speter    IO.mapOptional("Nullability", F.Nullability);
30650276Speter    IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, llvm::None);
30750276Speter    IO.mapOptional("RetainCountConvention", F.RetainCountConvention);
30850276Speter    IO.mapOptional("Availability", F.Availability.Mode,
30950276Speter                   APIAvailability::Available);
31050276Speter    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
31150276Speter    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
31250276Speter    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
31350276Speter    IO.mapOptional("ResultType", F.ResultType, StringRef(""));
31450276Speter  }
31550276Speter};
31650276Speter} // namespace yaml
31750276Speter} // namespace llvm
31850276Speter
31950276Speternamespace {
32050276Speterstruct GlobalVariable {
32150276Speter  StringRef Name;
32250276Speter  llvm::Optional<NullabilityKind> Nullability;
32350276Speter  AvailabilityItem Availability;
32450276Speter  Optional<bool> SwiftPrivate;
32550276Speter  StringRef SwiftName;
32650276Speter  StringRef Type;
32750276Speter};
32850276Speter
32950276Spetertypedef std::vector<GlobalVariable> GlobalVariablesSeq;
33050276Speter} // namespace
33150276Speter
33250276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
33350276Speter
33450276Speternamespace llvm {
33550276Speternamespace yaml {
336166124Srafantemplate <> struct MappingTraits<GlobalVariable> {
33750276Speter  static void mapping(IO &IO, GlobalVariable &GV) {
33850276Speter    IO.mapRequired("Name", GV.Name);
33950276Speter    IO.mapOptional("Nullability", GV.Nullability, llvm::None);
34050276Speter    IO.mapOptional("Availability", GV.Availability.Mode,
34150276Speter                   APIAvailability::Available);
34250276Speter    IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));
34350276Speter    IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
34450276Speter    IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
34550276Speter    IO.mapOptional("Type", GV.Type, StringRef(""));
34650276Speter  }
34750276Speter};
34850276Speter} // namespace yaml
34950276Speter} // namespace llvm
35050276Speter
35150276Speternamespace {
35250276Speterstruct EnumConstant {
35350276Speter  StringRef Name;
35450276Speter  AvailabilityItem Availability;
35550276Speter  Optional<bool> SwiftPrivate;
35650276Speter  StringRef SwiftName;
35750276Speter};
35850276Speter
35950276Spetertypedef std::vector<EnumConstant> EnumConstantsSeq;
36050276Speter} // namespace
36166963Speter
362166124SrafanLLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
363166124Srafan
36466963Speternamespace llvm {
36566963Speternamespace yaml {
36666963Spetertemplate <> struct MappingTraits<EnumConstant> {
36766963Speter  static void mapping(IO &IO, EnumConstant &EC) {
368166124Srafan    IO.mapRequired("Name", EC.Name);
369166124Srafan    IO.mapOptional("Availability", EC.Availability.Mode,
370166124Srafan                   APIAvailability::Available);
37166963Speter    IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
372166124Srafan    IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
37366963Speter    IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
37450276Speter  }
37550276Speter};
37650276Speter} // namespace yaml
37750276Speter} // namespace llvm
37850276Speter
37950276Speternamespace {
38050276Speter/// Syntactic sugar for EnumExtensibility and FlagEnum
38150276Speterenum class EnumConvenienceAliasKind {
38250276Speter  /// EnumExtensibility: none, FlagEnum: false
38350276Speter  None,
38450276Speter  /// EnumExtensibility: open, FlagEnum: false
38550276Speter  CFEnum,
38650276Speter  /// EnumExtensibility: open, FlagEnum: true
38750276Speter  CFOptions,
38850276Speter  /// EnumExtensibility: closed, FlagEnum: false
38950276Speter  CFClosedEnum
39050276Speter};
39150276Speter} // namespace
39250276Speter
39350276Speternamespace llvm {
39450276Speternamespace yaml {
39550276Spetertemplate <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
396166124Srafan  static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {
39750276Speter    IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);
39850276Speter    IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);
39950276Speter    IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);
40050276Speter    IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);
40150276Speter    IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);
40250276Speter    IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
40350276Speter    IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
404166124Srafan  }
40550276Speter};
406166124Srafan} // namespace yaml
40750276Speter} // namespace llvm
40850276Speter
40950276Speternamespace {
41050276Speterstruct Tag {
41150276Speter  StringRef Name;
41250276Speter  AvailabilityItem Availability;
41350276Speter  StringRef SwiftName;
414166124Srafan  Optional<bool> SwiftPrivate;
41550276Speter  Optional<StringRef> SwiftBridge;
41650276Speter  Optional<StringRef> NSErrorDomain;
41750276Speter  Optional<EnumExtensibilityKind> EnumExtensibility;
41850276Speter  Optional<bool> FlagEnum;
41950276Speter  Optional<EnumConvenienceAliasKind> EnumConvenienceKind;
42050276Speter};
42150276Speter
42250276Spetertypedef std::vector<Tag> TagsSeq;
42350276Speter} // namespace
42450276Speter
42550276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
42650276Speter
42750276Speternamespace llvm {
42850276Speternamespace yaml {
42950276Spetertemplate <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {
43050276Speter  static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {
43150276Speter    IO.enumCase(EEK, "none", EnumExtensibilityKind::None);
43250276Speter    IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);
43350276Speter    IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);
43450276Speter  }
43550276Speter};
43650276Speter
43750276Spetertemplate <> struct MappingTraits<Tag> {
43850276Speter  static void mapping(IO &IO, Tag &T) {
43950276Speter    IO.mapRequired("Name", T.Name);
44050276Speter    IO.mapOptional("Availability", T.Availability.Mode,
44150276Speter                   APIAvailability::Available);
44250276Speter    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
44350276Speter    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
44450276Speter    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
44550276Speter    IO.mapOptional("SwiftBridge", T.SwiftBridge);
44650276Speter    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
44750276Speter    IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
44850276Speter    IO.mapOptional("FlagEnum", T.FlagEnum);
44950276Speter    IO.mapOptional("EnumKind", T.EnumConvenienceKind);
45050276Speter  }
45150276Speter};
45250276Speter} // namespace yaml
45350276Speter} // namespace llvm
45450276Speter
45550276Speternamespace {
45650276Speterstruct Typedef {
45750276Speter  StringRef Name;
45850276Speter  AvailabilityItem Availability;
45950276Speter  StringRef SwiftName;
46050276Speter  Optional<bool> SwiftPrivate;
46150276Speter  Optional<StringRef> SwiftBridge;
46250276Speter  Optional<StringRef> NSErrorDomain;
46350276Speter  Optional<SwiftNewTypeKind> SwiftType;
46450276Speter};
46550276Speter
46650276Spetertypedef std::vector<Typedef> TypedefsSeq;
46750276Speter} // namespace
46850276Speter
46950276SpeterLLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
47050276Speter
47150276Speternamespace llvm {
47250276Speternamespace yaml {
47350276Spetertemplate <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {
47450276Speter  static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {
47550276Speter    IO.enumCase(SWK, "none", SwiftNewTypeKind::None);
47650276Speter    IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);
47750276Speter    IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);
47850276Speter  }
47950276Speter};
480166124Srafan
48150276Spetertemplate <> struct MappingTraits<Typedef> {
48250276Speter  static void mapping(IO &IO, Typedef &T) {
48350276Speter    IO.mapRequired("Name", T.Name);
48450276Speter    IO.mapOptional("Availability", T.Availability.Mode,
48550276Speter                   APIAvailability::Available);
48650276Speter    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
48750276Speter    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
48850276Speter    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
48950276Speter    IO.mapOptional("SwiftBridge", T.SwiftBridge);
49050276Speter    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
49150276Speter    IO.mapOptional("SwiftWrapper", T.SwiftType);
49250276Speter  }
49350276Speter};
49450276Speter} // namespace yaml
49550276Speter} // namespace llvm
49650276Speter
49750276Speternamespace {
49850276Speterstruct TopLevelItems {
49950276Speter  ClassesSeq Classes;
50050276Speter  ClassesSeq Protocols;
50150276Speter  FunctionsSeq Functions;
50250276Speter  GlobalVariablesSeq Globals;
50350276Speter  EnumConstantsSeq EnumConstants;
50450276Speter  TagsSeq Tags;
50550276Speter  TypedefsSeq Typedefs;
50650276Speter};
50750276Speter} // namespace
50850276Speter
50950276Speternamespace llvm {
51050276Speternamespace yaml {
51150276Speterstatic void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {
51250276Speter  IO.mapOptional("Classes", TLI.Classes);
51350276Speter  IO.mapOptional("Protocols", TLI.Protocols);
51450276Speter  IO.mapOptional("Functions", TLI.Functions);
51550276Speter  IO.mapOptional("Globals", TLI.Globals);
51650276Speter  IO.mapOptional("Enumerators", TLI.EnumConstants);
51750276Speter  IO.mapOptional("Tags", TLI.Tags);
51850276Speter  IO.mapOptional("Typedefs", TLI.Typedefs);
51950276Speter}
52050276Speter} // namespace yaml
52150276Speter} // namespace llvm
52250276Speter
52350276Speternamespace {
52450276Speterstruct Versioned {
52550276Speter  VersionTuple Version;
52650276Speter  TopLevelItems Items;
52750276Speter};
52850276Speter
52950276Spetertypedef std::vector<Versioned> VersionedSeq;
53050276Speter} // namespace
531166124Srafan
532166124SrafanLLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
533166124Srafan
534166124Srafannamespace llvm {
535166124Srafannamespace yaml {
536166124Srafantemplate <> struct MappingTraits<Versioned> {
537166124Srafan  static void mapping(IO &IO, Versioned &V) {
53850276Speter    IO.mapRequired("Version", V.Version);
539166124Srafan    mapTopLevelItems(IO, V.Items);
54050276Speter  }
54150276Speter};
54250276Speter} // namespace yaml
54350276Speter} // namespace llvm
54450276Speter
54550276Speternamespace {
54650276Speterstruct Module {
547166124Srafan  StringRef Name;
54850276Speter  AvailabilityItem Availability;
54950276Speter  TopLevelItems TopLevel;
55050276Speter  VersionedSeq SwiftVersions;
55150276Speter
55250276Speter  llvm::Optional<bool> SwiftInferImportAsMember = {llvm::None};
55350276Speter
55450276Speter#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
55550276Speter  LLVM_DUMP_METHOD void dump() /*const*/;
55650276Speter#endif
55750276Speter};
55850276Speter} // namespace
55950276Speter
56050276Speternamespace llvm {
56150276Speternamespace yaml {
56250276Spetertemplate <> struct MappingTraits<Module> {
56350276Speter  static void mapping(IO &IO, Module &M) {
56450276Speter    IO.mapRequired("Name", M.Name);
56550276Speter    IO.mapOptional("Availability", M.Availability.Mode,
56650276Speter                   APIAvailability::Available);
56750276Speter    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
56850276Speter    IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
56950276Speter    mapTopLevelItems(IO, M.TopLevel);
57050276Speter    IO.mapOptional("SwiftVersions", M.SwiftVersions);
57150276Speter  }
57250276Speter};
57350276Speter} // namespace yaml
57450276Speter} // namespace llvm
57550276Speter
57650276Speter#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
57750276SpeterLLVM_DUMP_METHOD void Module::dump() {
57850276Speter  llvm::yaml::Output OS(llvm::errs());
57950276Speter  OS << *this;
58050276Speter}
58150276Speter#endif
58250276Speter
58350276Speternamespace {
58450276Speterbool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
58550276Speter                   void *DiagContext) {
58650276Speter  llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
58750276Speter  IS >> M;
58850276Speter  return static_cast<bool>(IS.error());
58950276Speter}
59050276Speter} // namespace
59150276Speter
59250276Speterbool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
59350276Speter                                            llvm::raw_ostream &OS) {
59450276Speter  Module M;
59550276Speter  if (parseAPINotes(YI, M, nullptr, nullptr))
59650276Speter    return true;
597166124Srafan
59850276Speter  llvm::yaml::Output YOS(OS);
59950276Speter  YOS << M;
60050276Speter
60150276Speter  return false;
60250276Speter}
60350276Speter