Coverage Report

Created: 2023-09-21 18:56

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