Coverage Report

Created: 2024-01-17 10:31

/src/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/APINotesWriter.h"
18
#include "clang/APINotes/Types.h"
19
#include "clang/Basic/LLVM.h"
20
#include "clang/Basic/Specifiers.h"
21
#include "llvm/ADT/StringSet.h"
22
#include "llvm/Support/SourceMgr.h"
23
#include "llvm/Support/VersionTuple.h"
24
#include "llvm/Support/YAMLTraits.h"
25
#include <optional>
26
#include <vector>
27
28
using namespace clang;
29
using namespace api_notes;
30
31
namespace {
32
enum class APIAvailability {
33
  Available = 0,
34
  None,
35
  NonSwift,
36
};
37
} // namespace
38
39
namespace llvm {
40
namespace yaml {
41
template <> struct ScalarEnumerationTraits<APIAvailability> {
42
0
  static void enumeration(IO &IO, APIAvailability &AA) {
43
0
    IO.enumCase(AA, "none", APIAvailability::None);
44
0
    IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);
45
0
    IO.enumCase(AA, "available", APIAvailability::Available);
46
0
  }
47
};
48
} // namespace yaml
49
} // namespace llvm
50
51
namespace {
52
enum class MethodKind {
53
  Class,
54
  Instance,
55
};
56
} // namespace
57
58
namespace llvm {
59
namespace yaml {
60
template <> struct ScalarEnumerationTraits<MethodKind> {
61
0
  static void enumeration(IO &IO, MethodKind &MK) {
62
0
    IO.enumCase(MK, "Class", MethodKind::Class);
63
0
    IO.enumCase(MK, "Instance", MethodKind::Instance);
64
0
  }
65
};
66
} // namespace yaml
67
} // namespace llvm
68
69
namespace {
70
struct Param {
71
  unsigned Position;
72
  std::optional<bool> NoEscape = false;
73
  std::optional<NullabilityKind> Nullability;
74
  std::optional<RetainCountConventionKind> RetainCountConvention;
75
  StringRef Type;
76
};
77
78
typedef std::vector<Param> ParamsSeq;
79
} // namespace
80
81
LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
82
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)
83
84
namespace llvm {
85
namespace yaml {
86
template <> struct ScalarEnumerationTraits<NullabilityKind> {
87
0
  static void enumeration(IO &IO, NullabilityKind &NK) {
88
0
    IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
89
0
    IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
90
0
    IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
91
0
    IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
92
    // TODO: Mapping this to it's own value would allow for better cross
93
    // checking. Also the default should be Unknown.
94
0
    IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);
95
96
    // Aliases for compatibility with existing APINotes.
97
0
    IO.enumCase(NK, "N", NullabilityKind::NonNull);
98
0
    IO.enumCase(NK, "O", NullabilityKind::Nullable);
99
0
    IO.enumCase(NK, "U", NullabilityKind::Unspecified);
100
0
    IO.enumCase(NK, "S", NullabilityKind::Unspecified);
101
0
  }
102
};
103
104
template <> struct ScalarEnumerationTraits<RetainCountConventionKind> {
105
0
  static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {
106
0
    IO.enumCase(RCCK, "none", RetainCountConventionKind::None);
107
0
    IO.enumCase(RCCK, "CFReturnsRetained",
108
0
                RetainCountConventionKind::CFReturnsRetained);
109
0
    IO.enumCase(RCCK, "CFReturnsNotRetained",
110
0
                RetainCountConventionKind::CFReturnsNotRetained);
111
0
    IO.enumCase(RCCK, "NSReturnsRetained",
112
0
                RetainCountConventionKind::NSReturnsRetained);
113
0
    IO.enumCase(RCCK, "NSReturnsNotRetained",
114
0
                RetainCountConventionKind::NSReturnsNotRetained);
115
0
  }
116
};
117
118
template <> struct MappingTraits<Param> {
119
0
  static void mapping(IO &IO, Param &P) {
120
0
    IO.mapRequired("Position", P.Position);
121
0
    IO.mapOptional("Nullability", P.Nullability, std::nullopt);
122
0
    IO.mapOptional("RetainCountConvention", P.RetainCountConvention);
123
0
    IO.mapOptional("NoEscape", P.NoEscape);
124
0
    IO.mapOptional("Type", P.Type, StringRef(""));
125
0
  }
126
};
127
} // namespace yaml
128
} // namespace llvm
129
130
namespace {
131
typedef std::vector<NullabilityKind> NullabilitySeq;
132
133
struct AvailabilityItem {
134
  APIAvailability Mode = APIAvailability::Available;
135
  StringRef Msg;
136
};
137
138
/// Old attribute deprecated in favor of SwiftName.
139
enum class FactoryAsInitKind {
140
  /// Infer based on name and type (the default).
141
  Infer,
142
  /// Treat as a class method.
143
  AsClassMethod,
144
  /// Treat as an initializer.
145
  AsInitializer,
146
};
147
148
struct Method {
149
  StringRef Selector;
150
  MethodKind Kind;
151
  ParamsSeq Params;
152
  NullabilitySeq Nullability;
153
  std::optional<NullabilityKind> NullabilityOfRet;
154
  std::optional<RetainCountConventionKind> RetainCountConvention;
155
  AvailabilityItem Availability;
156
  std::optional<bool> SwiftPrivate;
157
  StringRef SwiftName;
158
  FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
159
  bool DesignatedInit = false;
160
  bool Required = false;
161
  StringRef ResultType;
162
};
163
164
typedef std::vector<Method> MethodsSeq;
165
} // namespace
166
167
LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
168
169
namespace llvm {
170
namespace yaml {
171
template <> struct ScalarEnumerationTraits<FactoryAsInitKind> {
172
0
  static void enumeration(IO &IO, FactoryAsInitKind &FIK) {
173
0
    IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);
174
0
    IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);
175
0
    IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);
176
0
  }
177
};
178
179
template <> struct MappingTraits<Method> {
180
0
  static void mapping(IO &IO, Method &M) {
181
0
    IO.mapRequired("Selector", M.Selector);
182
0
    IO.mapRequired("MethodKind", M.Kind);
183
0
    IO.mapOptional("Parameters", M.Params);
184
0
    IO.mapOptional("Nullability", M.Nullability);
185
0
    IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
186
0
    IO.mapOptional("RetainCountConvention", M.RetainCountConvention);
187
0
    IO.mapOptional("Availability", M.Availability.Mode,
188
0
                   APIAvailability::Available);
189
0
    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
190
0
    IO.mapOptional("SwiftPrivate", M.SwiftPrivate);
191
0
    IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));
192
0
    IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
193
0
    IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
194
0
    IO.mapOptional("Required", M.Required, false);
195
0
    IO.mapOptional("ResultType", M.ResultType, StringRef(""));
196
0
  }
197
};
198
} // namespace yaml
199
} // namespace llvm
200
201
namespace {
202
struct Property {
203
  StringRef Name;
204
  std::optional<MethodKind> Kind;
205
  std::optional<NullabilityKind> Nullability;
206
  AvailabilityItem Availability;
207
  std::optional<bool> SwiftPrivate;
208
  StringRef SwiftName;
209
  std::optional<bool> SwiftImportAsAccessors;
210
  StringRef Type;
211
};
212
213
typedef std::vector<Property> PropertiesSeq;
214
} // namespace
215
216
LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
217
218
namespace llvm {
219
namespace yaml {
220
template <> struct MappingTraits<Property> {
221
0
  static void mapping(IO &IO, Property &P) {
222
0
    IO.mapRequired("Name", P.Name);
223
0
    IO.mapOptional("PropertyKind", P.Kind);
224
0
    IO.mapOptional("Nullability", P.Nullability, std::nullopt);
225
0
    IO.mapOptional("Availability", P.Availability.Mode,
226
0
                   APIAvailability::Available);
227
0
    IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));
228
0
    IO.mapOptional("SwiftPrivate", P.SwiftPrivate);
229
0
    IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
230
0
    IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
231
0
    IO.mapOptional("Type", P.Type, StringRef(""));
232
0
  }
233
};
234
} // namespace yaml
235
} // namespace llvm
236
237
namespace {
238
struct Class {
239
  StringRef Name;
240
  bool AuditedForNullability = false;
241
  AvailabilityItem Availability;
242
  std::optional<bool> SwiftPrivate;
243
  StringRef SwiftName;
244
  std::optional<StringRef> SwiftBridge;
245
  std::optional<StringRef> NSErrorDomain;
246
  std::optional<bool> SwiftImportAsNonGeneric;
247
  std::optional<bool> SwiftObjCMembers;
248
  MethodsSeq Methods;
249
  PropertiesSeq Properties;
250
};
251
252
typedef std::vector<Class> ClassesSeq;
253
} // namespace
254
255
LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
256
257
namespace llvm {
258
namespace yaml {
259
template <> struct MappingTraits<Class> {
260
0
  static void mapping(IO &IO, Class &C) {
261
0
    IO.mapRequired("Name", C.Name);
262
0
    IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);
263
0
    IO.mapOptional("Availability", C.Availability.Mode,
264
0
                   APIAvailability::Available);
265
0
    IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));
266
0
    IO.mapOptional("SwiftPrivate", C.SwiftPrivate);
267
0
    IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));
268
0
    IO.mapOptional("SwiftBridge", C.SwiftBridge);
269
0
    IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
270
0
    IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
271
0
    IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
272
0
    IO.mapOptional("Methods", C.Methods);
273
0
    IO.mapOptional("Properties", C.Properties);
274
0
  }
275
};
276
} // namespace yaml
277
} // namespace llvm
278
279
namespace {
280
struct Function {
281
  StringRef Name;
282
  ParamsSeq Params;
283
  NullabilitySeq Nullability;
284
  std::optional<NullabilityKind> NullabilityOfRet;
285
  std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
286
  AvailabilityItem Availability;
287
  std::optional<bool> SwiftPrivate;
288
  StringRef SwiftName;
289
  StringRef Type;
290
  StringRef ResultType;
291
};
292
293
typedef std::vector<Function> FunctionsSeq;
294
} // namespace
295
296
LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
297
298
namespace llvm {
299
namespace yaml {
300
template <> struct MappingTraits<Function> {
301
0
  static void mapping(IO &IO, Function &F) {
302
0
    IO.mapRequired("Name", F.Name);
303
0
    IO.mapOptional("Parameters", F.Params);
304
0
    IO.mapOptional("Nullability", F.Nullability);
305
0
    IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
306
0
    IO.mapOptional("RetainCountConvention", F.RetainCountConvention);
307
0
    IO.mapOptional("Availability", F.Availability.Mode,
308
0
                   APIAvailability::Available);
309
0
    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
310
0
    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
311
0
    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
312
0
    IO.mapOptional("ResultType", F.ResultType, StringRef(""));
313
0
  }
314
};
315
} // namespace yaml
316
} // namespace llvm
317
318
namespace {
319
struct GlobalVariable {
320
  StringRef Name;
321
  std::optional<NullabilityKind> Nullability;
322
  AvailabilityItem Availability;
323
  std::optional<bool> SwiftPrivate;
324
  StringRef SwiftName;
325
  StringRef Type;
326
};
327
328
typedef std::vector<GlobalVariable> GlobalVariablesSeq;
329
} // namespace
330
331
LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
332
333
namespace llvm {
334
namespace yaml {
335
template <> struct MappingTraits<GlobalVariable> {
336
0
  static void mapping(IO &IO, GlobalVariable &GV) {
337
0
    IO.mapRequired("Name", GV.Name);
338
0
    IO.mapOptional("Nullability", GV.Nullability, std::nullopt);
339
0
    IO.mapOptional("Availability", GV.Availability.Mode,
340
0
                   APIAvailability::Available);
341
0
    IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));
342
0
    IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
343
0
    IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
344
0
    IO.mapOptional("Type", GV.Type, StringRef(""));
345
0
  }
346
};
347
} // namespace yaml
348
} // namespace llvm
349
350
namespace {
351
struct EnumConstant {
352
  StringRef Name;
353
  AvailabilityItem Availability;
354
  std::optional<bool> SwiftPrivate;
355
  StringRef SwiftName;
356
};
357
358
typedef std::vector<EnumConstant> EnumConstantsSeq;
359
} // namespace
360
361
LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
362
363
namespace llvm {
364
namespace yaml {
365
template <> struct MappingTraits<EnumConstant> {
366
0
  static void mapping(IO &IO, EnumConstant &EC) {
367
0
    IO.mapRequired("Name", EC.Name);
368
0
    IO.mapOptional("Availability", EC.Availability.Mode,
369
0
                   APIAvailability::Available);
370
0
    IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
371
0
    IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
372
0
    IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
373
0
  }
374
};
375
} // namespace yaml
376
} // namespace llvm
377
378
namespace {
379
/// Syntactic sugar for EnumExtensibility and FlagEnum
380
enum class EnumConvenienceAliasKind {
381
  /// EnumExtensibility: none, FlagEnum: false
382
  None,
383
  /// EnumExtensibility: open, FlagEnum: false
384
  CFEnum,
385
  /// EnumExtensibility: open, FlagEnum: true
386
  CFOptions,
387
  /// EnumExtensibility: closed, FlagEnum: false
388
  CFClosedEnum
389
};
390
} // namespace
391
392
namespace llvm {
393
namespace yaml {
394
template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
395
0
  static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {
396
0
    IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);
397
0
    IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);
398
0
    IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);
399
0
    IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);
400
0
    IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);
401
0
    IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
402
0
    IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
403
0
  }
404
};
405
} // namespace yaml
406
} // namespace llvm
407
408
namespace {
409
struct Tag {
410
  StringRef Name;
411
  AvailabilityItem Availability;
412
  StringRef SwiftName;
413
  std::optional<bool> SwiftPrivate;
414
  std::optional<StringRef> SwiftBridge;
415
  std::optional<StringRef> NSErrorDomain;
416
  std::optional<std::string> SwiftImportAs;
417
  std::optional<std::string> SwiftRetainOp;
418
  std::optional<std::string> SwiftReleaseOp;
419
  std::optional<EnumExtensibilityKind> EnumExtensibility;
420
  std::optional<bool> FlagEnum;
421
  std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
422
};
423
424
typedef std::vector<Tag> TagsSeq;
425
} // namespace
426
427
LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
428
429
namespace llvm {
430
namespace yaml {
431
template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {
432
0
  static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {
433
0
    IO.enumCase(EEK, "none", EnumExtensibilityKind::None);
434
0
    IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);
435
0
    IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);
436
0
  }
437
};
438
439
template <> struct MappingTraits<Tag> {
440
0
  static void mapping(IO &IO, Tag &T) {
441
0
    IO.mapRequired("Name", T.Name);
442
0
    IO.mapOptional("Availability", T.Availability.Mode,
443
0
                   APIAvailability::Available);
444
0
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
445
0
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
446
0
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
447
0
    IO.mapOptional("SwiftBridge", T.SwiftBridge);
448
0
    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
449
0
    IO.mapOptional("SwiftImportAs", T.SwiftImportAs);
450
0
    IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);
451
0
    IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);
452
0
    IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
453
0
    IO.mapOptional("FlagEnum", T.FlagEnum);
454
0
    IO.mapOptional("EnumKind", T.EnumConvenienceKind);
455
0
  }
456
};
457
} // namespace yaml
458
} // namespace llvm
459
460
namespace {
461
struct Typedef {
462
  StringRef Name;
463
  AvailabilityItem Availability;
464
  StringRef SwiftName;
465
  std::optional<bool> SwiftPrivate;
466
  std::optional<StringRef> SwiftBridge;
467
  std::optional<StringRef> NSErrorDomain;
468
  std::optional<SwiftNewTypeKind> SwiftType;
469
};
470
471
typedef std::vector<Typedef> TypedefsSeq;
472
} // namespace
473
474
LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
475
476
namespace llvm {
477
namespace yaml {
478
template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {
479
0
  static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {
480
0
    IO.enumCase(SWK, "none", SwiftNewTypeKind::None);
481
0
    IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);
482
0
    IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);
483
0
  }
484
};
485
486
template <> struct MappingTraits<Typedef> {
487
0
  static void mapping(IO &IO, Typedef &T) {
488
0
    IO.mapRequired("Name", T.Name);
489
0
    IO.mapOptional("Availability", T.Availability.Mode,
490
0
                   APIAvailability::Available);
491
0
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
492
0
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
493
0
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
494
0
    IO.mapOptional("SwiftBridge", T.SwiftBridge);
495
0
    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
496
0
    IO.mapOptional("SwiftWrapper", T.SwiftType);
497
0
  }
498
};
499
} // namespace yaml
500
} // namespace llvm
501
502
namespace {
503
struct Namespace;
504
typedef std::vector<Namespace> NamespacesSeq;
505
506
struct TopLevelItems {
507
  ClassesSeq Classes;
508
  ClassesSeq Protocols;
509
  FunctionsSeq Functions;
510
  GlobalVariablesSeq Globals;
511
  EnumConstantsSeq EnumConstants;
512
  TagsSeq Tags;
513
  TypedefsSeq Typedefs;
514
  NamespacesSeq Namespaces;
515
};
516
} // namespace
517
518
namespace llvm {
519
namespace yaml {
520
0
static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {
521
0
  IO.mapOptional("Classes", TLI.Classes);
522
0
  IO.mapOptional("Protocols", TLI.Protocols);
523
0
  IO.mapOptional("Functions", TLI.Functions);
524
0
  IO.mapOptional("Globals", TLI.Globals);
525
0
  IO.mapOptional("Enumerators", TLI.EnumConstants);
526
0
  IO.mapOptional("Tags", TLI.Tags);
527
0
  IO.mapOptional("Typedefs", TLI.Typedefs);
528
0
  IO.mapOptional("Namespaces", TLI.Namespaces);
529
0
}
530
} // namespace yaml
531
} // namespace llvm
532
533
namespace {
534
struct Namespace {
535
  StringRef Name;
536
  AvailabilityItem Availability;
537
  StringRef SwiftName;
538
  std::optional<bool> SwiftPrivate;
539
  TopLevelItems Items;
540
};
541
} // namespace
542
543
LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
544
545
namespace llvm {
546
namespace yaml {
547
template <> struct MappingTraits<Namespace> {
548
0
  static void mapping(IO &IO, Namespace &T) {
549
0
    IO.mapRequired("Name", T.Name);
550
0
    IO.mapOptional("Availability", T.Availability.Mode,
551
0
                   APIAvailability::Available);
552
0
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
553
0
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
554
0
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
555
0
    mapTopLevelItems(IO, T.Items);
556
0
  }
557
};
558
} // namespace yaml
559
} // namespace llvm
560
561
namespace {
562
struct Versioned {
563
  VersionTuple Version;
564
  TopLevelItems Items;
565
};
566
567
typedef std::vector<Versioned> VersionedSeq;
568
} // namespace
569
570
LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
571
572
namespace llvm {
573
namespace yaml {
574
template <> struct MappingTraits<Versioned> {
575
0
  static void mapping(IO &IO, Versioned &V) {
576
0
    IO.mapRequired("Version", V.Version);
577
0
    mapTopLevelItems(IO, V.Items);
578
0
  }
579
};
580
} // namespace yaml
581
} // namespace llvm
582
583
namespace {
584
struct Module {
585
  StringRef Name;
586
  AvailabilityItem Availability;
587
  TopLevelItems TopLevel;
588
  VersionedSeq SwiftVersions;
589
590
  std::optional<bool> SwiftInferImportAsMember;
591
592
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
593
  LLVM_DUMP_METHOD void dump() /*const*/;
594
#endif
595
};
596
} // namespace
597
598
namespace llvm {
599
namespace yaml {
600
template <> struct MappingTraits<Module> {
601
0
  static void mapping(IO &IO, Module &M) {
602
0
    IO.mapRequired("Name", M.Name);
603
0
    IO.mapOptional("Availability", M.Availability.Mode,
604
0
                   APIAvailability::Available);
605
0
    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
606
0
    IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
607
0
    mapTopLevelItems(IO, M.TopLevel);
608
0
    IO.mapOptional("SwiftVersions", M.SwiftVersions);
609
0
  }
610
};
611
} // namespace yaml
612
} // namespace llvm
613
614
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
615
0
LLVM_DUMP_METHOD void Module::dump() {
616
0
  llvm::yaml::Output OS(llvm::errs());
617
0
  OS << *this;
618
0
}
619
#endif
620
621
namespace {
622
bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
623
0
                   void *DiagContext) {
624
0
  llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
625
0
  IS >> M;
626
0
  return static_cast<bool>(IS.error());
627
0
}
628
} // namespace
629
630
bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
631
0
                                            llvm::raw_ostream &OS) {
632
0
  Module M;
633
0
  if (parseAPINotes(YI, M, nullptr, nullptr))
634
0
    return true;
635
636
0
  llvm::yaml::Output YOS(OS);
637
0
  YOS << M;
638
639
0
  return false;
640
0
}
641
642
namespace {
643
using namespace api_notes;
644
645
class YAMLConverter {
646
  const Module &M;
647
  APINotesWriter Writer;
648
  llvm::raw_ostream &OS;
649
  llvm::SourceMgr::DiagHandlerTy DiagHandler;
650
  void *DiagHandlerCtxt;
651
  bool ErrorOccured;
652
653
  /// Emit a diagnostic
654
0
  bool emitError(llvm::Twine Message) {
655
0
    DiagHandler(
656
0
        llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()),
657
0
        DiagHandlerCtxt);
658
0
    ErrorOccured = true;
659
0
    return true;
660
0
  }
661
662
public:
663
  YAMLConverter(const Module &TheModule, const FileEntry *SourceFile,
664
                llvm::raw_ostream &OS,
665
                llvm::SourceMgr::DiagHandlerTy DiagHandler,
666
                void *DiagHandlerCtxt)
667
      : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
668
        DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
669
0
        ErrorOccured(false) {}
670
671
  void convertAvailability(const AvailabilityItem &Availability,
672
0
                           CommonEntityInfo &CEI, llvm::StringRef APIName) {
673
    // Populate the unavailability information.
674
0
    CEI.Unavailable = (Availability.Mode == APIAvailability::None);
675
0
    CEI.UnavailableInSwift = (Availability.Mode == APIAvailability::NonSwift);
676
0
    if (CEI.Unavailable || CEI.UnavailableInSwift) {
677
0
      CEI.UnavailableMsg = std::string(Availability.Msg);
678
0
    } else {
679
0
      if (!Availability.Msg.empty())
680
0
        emitError(llvm::Twine("availability message for available API '") +
681
0
                  APIName + "' will not be used");
682
0
    }
683
0
  }
684
685
0
  void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo) {
686
0
    for (const auto &P : Params) {
687
0
      ParamInfo PI;
688
0
      if (P.Nullability)
689
0
        PI.setNullabilityAudited(*P.Nullability);
690
0
      PI.setNoEscape(P.NoEscape);
691
0
      PI.setType(std::string(P.Type));
692
0
      PI.setRetainCountConvention(P.RetainCountConvention);
693
0
      if (OutInfo.Params.size() <= P.Position)
694
0
        OutInfo.Params.resize(P.Position + 1);
695
0
      OutInfo.Params[P.Position] |= PI;
696
0
    }
697
0
  }
698
699
  void convertNullability(const NullabilitySeq &Nullability,
700
                          std::optional<NullabilityKind> ReturnNullability,
701
0
                          FunctionInfo &OutInfo, llvm::StringRef APIName) {
702
0
    if (Nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {
703
0
      emitError(llvm::Twine("nullability info for '") + APIName +
704
0
                "' does not fit");
705
0
      return;
706
0
    }
707
708
0
    bool audited = false;
709
0
    unsigned int idx = 1;
710
0
    for (const auto &N : Nullability)
711
0
      OutInfo.addTypeInfo(idx++, N);
712
0
    audited = Nullability.size() > 0 || ReturnNullability;
713
0
    if (audited)
714
0
      OutInfo.addTypeInfo(0, ReturnNullability ? *ReturnNullability
715
0
                                               : NullabilityKind::NonNull);
716
0
    if (!audited)
717
0
      return;
718
0
    OutInfo.NullabilityAudited = audited;
719
0
    OutInfo.NumAdjustedNullable = idx;
720
0
  }
721
722
  /// Convert the common parts of an entity from YAML.
723
  template <typename T>
724
  void convertCommonEntity(const T &Common, CommonEntityInfo &Info,
725
0
                           StringRef APIName) {
726
0
    convertAvailability(Common.Availability, Info, APIName);
727
0
    Info.setSwiftPrivate(Common.SwiftPrivate);
728
0
    Info.SwiftName = std::string(Common.SwiftName);
729
0
  }
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonEntity<(anonymous namespace)::Class>((anonymous namespace)::Class const&, clang::api_notes::CommonEntityInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonEntity<(anonymous namespace)::Method>((anonymous namespace)::Method const&, clang::api_notes::CommonEntityInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonEntity<(anonymous namespace)::Namespace>((anonymous namespace)::Namespace const&, clang::api_notes::CommonEntityInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonEntity<(anonymous namespace)::Tag>((anonymous namespace)::Tag const&, clang::api_notes::CommonEntityInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonEntity<(anonymous namespace)::Typedef>((anonymous namespace)::Typedef const&, clang::api_notes::CommonEntityInfo&, llvm::StringRef)
730
731
  /// Convert the common parts of a type entity from YAML.
732
  template <typename T>
733
  void convertCommonType(const T &Common, CommonTypeInfo &Info,
734
0
                         StringRef APIName) {
735
0
    convertCommonEntity(Common, Info, APIName);
736
0
    if (Common.SwiftBridge)
737
0
      Info.setSwiftBridge(std::string(*Common.SwiftBridge));
738
0
    Info.setNSErrorDomain(Common.NSErrorDomain);
739
0
  }
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonType<(anonymous namespace)::Class>((anonymous namespace)::Class const&, clang::api_notes::CommonTypeInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonType<(anonymous namespace)::Tag>((anonymous namespace)::Tag const&, clang::api_notes::CommonTypeInfo&, llvm::StringRef)
Unexecuted instantiation: APINotesYAMLCompiler.cpp:void (anonymous namespace)::YAMLConverter::convertCommonType<(anonymous namespace)::Typedef>((anonymous namespace)::Typedef const&, clang::api_notes::CommonTypeInfo&, llvm::StringRef)
740
741
  // Translate from Method into ObjCMethodInfo and write it out.
742
  void convertMethod(const Method &M, ContextID ClassID, StringRef ClassName,
743
0
                     VersionTuple SwiftVersion) {
744
0
    ObjCMethodInfo MI;
745
0
    convertCommonEntity(M, MI, M.Selector);
746
747
    // Check if the selector ends with ':' to determine if it takes arguments.
748
0
    bool takesArguments = M.Selector.ends_with(":");
749
750
    // Split the selector into pieces.
751
0
    llvm::SmallVector<StringRef, 4> Args;
752
0
    M.Selector.split(Args, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
753
0
    if (!takesArguments && Args.size() > 1) {
754
0
      emitError("selector '" + M.Selector + "' is missing a ':' at the end");
755
0
      return;
756
0
    }
757
758
    // Construct ObjCSelectorRef.
759
0
    api_notes::ObjCSelectorRef Selector;
760
0
    Selector.NumArgs = !takesArguments ? 0 : Args.size();
761
0
    Selector.Identifiers = Args;
762
763
    // Translate the initializer info.
764
0
    MI.DesignatedInit = M.DesignatedInit;
765
0
    MI.RequiredInit = M.Required;
766
0
    if (M.FactoryAsInit != FactoryAsInitKind::Infer)
767
0
      emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
768
769
0
    MI.ResultType = std::string(M.ResultType);
770
771
    // Translate parameter information.
772
0
    convertParams(M.Params, MI);
773
774
    // Translate nullability info.
775
0
    convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
776
777
0
    MI.setRetainCountConvention(M.RetainCountConvention);
778
779
    // Write it.
780
0
    Writer.addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,
781
0
                         SwiftVersion);
782
0
  }
783
784
  void convertContext(std::optional<ContextID> ParentContextID, const Class &C,
785
0
                      ContextKind Kind, VersionTuple SwiftVersion) {
786
    // Write the class.
787
0
    ObjCContextInfo CI;
788
0
    convertCommonType(C, CI, C.Name);
789
790
0
    if (C.AuditedForNullability)
791
0
      CI.setDefaultNullability(NullabilityKind::NonNull);
792
0
    if (C.SwiftImportAsNonGeneric)
793
0
      CI.setSwiftImportAsNonGeneric(*C.SwiftImportAsNonGeneric);
794
0
    if (C.SwiftObjCMembers)
795
0
      CI.setSwiftObjCMembers(*C.SwiftObjCMembers);
796
797
0
    ContextID CtxID =
798
0
        Writer.addObjCContext(ParentContextID, C.Name, Kind, CI, SwiftVersion);
799
800
    // Write all methods.
801
0
    llvm::StringMap<std::pair<bool, bool>> KnownMethods;
802
0
    for (const auto &method : C.Methods) {
803
      // Check for duplicate method definitions.
804
0
      bool IsInstanceMethod = method.Kind == MethodKind::Instance;
805
0
      bool &Known = IsInstanceMethod ? KnownMethods[method.Selector].first
806
0
                                     : KnownMethods[method.Selector].second;
807
0
      if (Known) {
808
0
        emitError(llvm::Twine("duplicate definition of method '") +
809
0
                  (IsInstanceMethod ? "-" : "+") + "[" + C.Name + " " +
810
0
                  method.Selector + "]'");
811
0
        continue;
812
0
      }
813
0
      Known = true;
814
815
0
      convertMethod(method, CtxID, C.Name, SwiftVersion);
816
0
    }
817
818
    // Write all properties.
819
0
    llvm::StringSet<> KnownInstanceProperties;
820
0
    llvm::StringSet<> KnownClassProperties;
821
0
    for (const auto &Property : C.Properties) {
822
      // Check for duplicate property definitions.
823
0
      if ((!Property.Kind || *Property.Kind == MethodKind::Instance) &&
824
0
          !KnownInstanceProperties.insert(Property.Name).second) {
825
0
        emitError(llvm::Twine("duplicate definition of instance property '") +
826
0
                  C.Name + "." + Property.Name + "'");
827
0
        continue;
828
0
      }
829
830
0
      if ((!Property.Kind || *Property.Kind == MethodKind::Class) &&
831
0
          !KnownClassProperties.insert(Property.Name).second) {
832
0
        emitError(llvm::Twine("duplicate definition of class property '") +
833
0
                  C.Name + "." + Property.Name + "'");
834
0
        continue;
835
0
      }
836
837
      // Translate from Property into ObjCPropertyInfo.
838
0
      ObjCPropertyInfo PI;
839
0
      convertAvailability(Property.Availability, PI, Property.Name);
840
0
      PI.setSwiftPrivate(Property.SwiftPrivate);
841
0
      PI.SwiftName = std::string(Property.SwiftName);
842
0
      if (Property.Nullability)
843
0
        PI.setNullabilityAudited(*Property.Nullability);
844
0
      if (Property.SwiftImportAsAccessors)
845
0
        PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);
846
0
      PI.setType(std::string(Property.Type));
847
848
      // Add both instance and class properties with this name.
849
0
      if (Property.Kind) {
850
0
        Writer.addObjCProperty(CtxID, Property.Name,
851
0
                               *Property.Kind == MethodKind::Instance, PI,
852
0
                               SwiftVersion);
853
0
      } else {
854
0
        Writer.addObjCProperty(CtxID, Property.Name, true, PI, SwiftVersion);
855
0
        Writer.addObjCProperty(CtxID, Property.Name, false, PI, SwiftVersion);
856
0
      }
857
0
    }
858
0
  }
859
860
  void convertNamespaceContext(std::optional<ContextID> ParentContextID,
861
                               const Namespace &TheNamespace,
862
0
                               VersionTuple SwiftVersion) {
863
    // Write the namespace.
864
0
    ObjCContextInfo CI;
865
0
    convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
866
867
0
    ContextID CtxID =
868
0
        Writer.addObjCContext(ParentContextID, TheNamespace.Name,
869
0
                              ContextKind::Namespace, CI, SwiftVersion);
870
871
0
    convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
872
0
                         TheNamespace.Items, SwiftVersion);
873
0
  }
874
875
  void convertTopLevelItems(std::optional<Context> Ctx,
876
                            const TopLevelItems &TLItems,
877
0
                            VersionTuple SwiftVersion) {
878
0
    std::optional<ContextID> CtxID =
879
0
        Ctx ? std::optional(Ctx->id) : std::nullopt;
880
881
    // Write all classes.
882
0
    llvm::StringSet<> KnownClasses;
883
0
    for (const auto &Class : TLItems.Classes) {
884
      // Check for duplicate class definitions.
885
0
      if (!KnownClasses.insert(Class.Name).second) {
886
0
        emitError(llvm::Twine("multiple definitions of class '") + Class.Name +
887
0
                  "'");
888
0
        continue;
889
0
      }
890
891
0
      convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
892
0
    }
893
894
    // Write all protocols.
895
0
    llvm::StringSet<> KnownProtocols;
896
0
    for (const auto &Protocol : TLItems.Protocols) {
897
      // Check for duplicate protocol definitions.
898
0
      if (!KnownProtocols.insert(Protocol.Name).second) {
899
0
        emitError(llvm::Twine("multiple definitions of protocol '") +
900
0
                  Protocol.Name + "'");
901
0
        continue;
902
0
      }
903
904
0
      convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
905
0
    }
906
907
    // Write all namespaces.
908
0
    llvm::StringSet<> KnownNamespaces;
909
0
    for (const auto &Namespace : TLItems.Namespaces) {
910
      // Check for duplicate namespace definitions.
911
0
      if (!KnownNamespaces.insert(Namespace.Name).second) {
912
0
        emitError(llvm::Twine("multiple definitions of namespace '") +
913
0
                  Namespace.Name + "'");
914
0
        continue;
915
0
      }
916
917
0
      convertNamespaceContext(CtxID, Namespace, SwiftVersion);
918
0
    }
919
920
    // Write all global variables.
921
0
    llvm::StringSet<> KnownGlobals;
922
0
    for (const auto &Global : TLItems.Globals) {
923
      // Check for duplicate global variables.
924
0
      if (!KnownGlobals.insert(Global.Name).second) {
925
0
        emitError(llvm::Twine("multiple definitions of global variable '") +
926
0
                  Global.Name + "'");
927
0
        continue;
928
0
      }
929
930
0
      GlobalVariableInfo GVI;
931
0
      convertAvailability(Global.Availability, GVI, Global.Name);
932
0
      GVI.setSwiftPrivate(Global.SwiftPrivate);
933
0
      GVI.SwiftName = std::string(Global.SwiftName);
934
0
      if (Global.Nullability)
935
0
        GVI.setNullabilityAudited(*Global.Nullability);
936
0
      GVI.setType(std::string(Global.Type));
937
0
      Writer.addGlobalVariable(Ctx, Global.Name, GVI, SwiftVersion);
938
0
    }
939
940
    // Write all global functions.
941
0
    llvm::StringSet<> KnownFunctions;
942
0
    for (const auto &Function : TLItems.Functions) {
943
      // Check for duplicate global functions.
944
0
      if (!KnownFunctions.insert(Function.Name).second) {
945
0
        emitError(llvm::Twine("multiple definitions of global function '") +
946
0
                  Function.Name + "'");
947
0
        continue;
948
0
      }
949
950
0
      GlobalFunctionInfo GFI;
951
0
      convertAvailability(Function.Availability, GFI, Function.Name);
952
0
      GFI.setSwiftPrivate(Function.SwiftPrivate);
953
0
      GFI.SwiftName = std::string(Function.SwiftName);
954
0
      convertParams(Function.Params, GFI);
955
0
      convertNullability(Function.Nullability, Function.NullabilityOfRet, GFI,
956
0
                         Function.Name);
957
0
      GFI.ResultType = std::string(Function.ResultType);
958
0
      GFI.setRetainCountConvention(Function.RetainCountConvention);
959
0
      Writer.addGlobalFunction(Ctx, Function.Name, GFI, SwiftVersion);
960
0
    }
961
962
    // Write all enumerators.
963
0
    llvm::StringSet<> KnownEnumConstants;
964
0
    for (const auto &EnumConstant : TLItems.EnumConstants) {
965
      // Check for duplicate enumerators
966
0
      if (!KnownEnumConstants.insert(EnumConstant.Name).second) {
967
0
        emitError(llvm::Twine("multiple definitions of enumerator '") +
968
0
                  EnumConstant.Name + "'");
969
0
        continue;
970
0
      }
971
972
0
      EnumConstantInfo ECI;
973
0
      convertAvailability(EnumConstant.Availability, ECI, EnumConstant.Name);
974
0
      ECI.setSwiftPrivate(EnumConstant.SwiftPrivate);
975
0
      ECI.SwiftName = std::string(EnumConstant.SwiftName);
976
0
      Writer.addEnumConstant(EnumConstant.Name, ECI, SwiftVersion);
977
0
    }
978
979
    // Write all tags.
980
0
    llvm::StringSet<> KnownTags;
981
0
    for (const auto &Tag : TLItems.Tags) {
982
      // Check for duplicate tag definitions.
983
0
      if (!KnownTags.insert(Tag.Name).second) {
984
0
        emitError(llvm::Twine("multiple definitions of tag '") + Tag.Name +
985
0
                  "'");
986
0
        continue;
987
0
      }
988
989
0
      TagInfo TI;
990
0
      convertCommonType(Tag, TI, Tag.Name);
991
992
0
      if ((Tag.SwiftRetainOp || Tag.SwiftReleaseOp) && !Tag.SwiftImportAs) {
993
0
        emitError(llvm::Twine("should declare SwiftImportAs to use "
994
0
                              "SwiftRetainOp and SwiftReleaseOp (for ") +
995
0
                  Tag.Name + ")");
996
0
        continue;
997
0
      }
998
0
      if (Tag.SwiftReleaseOp.has_value() != Tag.SwiftRetainOp.has_value()) {
999
0
        emitError(llvm::Twine("should declare both SwiftReleaseOp and "
1000
0
                              "SwiftRetainOp (for ") +
1001
0
                  Tag.Name + ")");
1002
0
        continue;
1003
0
      }
1004
1005
0
      if (Tag.SwiftImportAs)
1006
0
        TI.SwiftImportAs = Tag.SwiftImportAs;
1007
0
      if (Tag.SwiftRetainOp)
1008
0
        TI.SwiftRetainOp = Tag.SwiftRetainOp;
1009
0
      if (Tag.SwiftReleaseOp)
1010
0
        TI.SwiftReleaseOp = Tag.SwiftReleaseOp;
1011
1012
0
      if (Tag.EnumConvenienceKind) {
1013
0
        if (Tag.EnumExtensibility) {
1014
0
          emitError(
1015
0
              llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +
1016
0
              Tag.Name + ")");
1017
0
          continue;
1018
0
        }
1019
0
        if (Tag.FlagEnum) {
1020
0
          emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +
1021
0
                    Tag.Name + ")");
1022
0
          continue;
1023
0
        }
1024
0
        switch (*Tag.EnumConvenienceKind) {
1025
0
        case EnumConvenienceAliasKind::None:
1026
0
          TI.EnumExtensibility = EnumExtensibilityKind::None;
1027
0
          TI.setFlagEnum(false);
1028
0
          break;
1029
0
        case EnumConvenienceAliasKind::CFEnum:
1030
0
          TI.EnumExtensibility = EnumExtensibilityKind::Open;
1031
0
          TI.setFlagEnum(false);
1032
0
          break;
1033
0
        case EnumConvenienceAliasKind::CFOptions:
1034
0
          TI.EnumExtensibility = EnumExtensibilityKind::Open;
1035
0
          TI.setFlagEnum(true);
1036
0
          break;
1037
0
        case EnumConvenienceAliasKind::CFClosedEnum:
1038
0
          TI.EnumExtensibility = EnumExtensibilityKind::Closed;
1039
0
          TI.setFlagEnum(false);
1040
0
          break;
1041
0
        }
1042
0
      } else {
1043
0
        TI.EnumExtensibility = Tag.EnumExtensibility;
1044
0
        TI.setFlagEnum(Tag.FlagEnum);
1045
0
      }
1046
1047
0
      Writer.addTag(Ctx, Tag.Name, TI, SwiftVersion);
1048
0
    }
1049
1050
    // Write all typedefs.
1051
0
    llvm::StringSet<> KnownTypedefs;
1052
0
    for (const auto &Typedef : TLItems.Typedefs) {
1053
      // Check for duplicate typedef definitions.
1054
0
      if (!KnownTypedefs.insert(Typedef.Name).second) {
1055
0
        emitError(llvm::Twine("multiple definitions of typedef '") +
1056
0
                  Typedef.Name + "'");
1057
0
        continue;
1058
0
      }
1059
1060
0
      TypedefInfo TInfo;
1061
0
      convertCommonType(Typedef, TInfo, Typedef.Name);
1062
0
      TInfo.SwiftWrapper = Typedef.SwiftType;
1063
1064
0
      Writer.addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);
1065
0
    }
1066
0
  }
1067
1068
0
  bool convertModule() {
1069
    // Write the top-level items.
1070
0
    convertTopLevelItems(/* context */ std::nullopt, M.TopLevel,
1071
0
                         VersionTuple());
1072
1073
    // Convert the versioned information.
1074
0
    for (const auto &Versioned : M.SwiftVersions)
1075
0
      convertTopLevelItems(/* context */ std::nullopt, Versioned.Items,
1076
0
                           Versioned.Version);
1077
1078
0
    if (!ErrorOccured)
1079
0
      Writer.writeToStream(OS);
1080
1081
0
    return ErrorOccured;
1082
0
  }
1083
};
1084
} // namespace
1085
1086
static bool compile(const Module &M, const FileEntry *SourceFile,
1087
                    llvm::raw_ostream &OS,
1088
                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
1089
0
                    void *DiagHandlerCtxt) {
1090
0
  YAMLConverter C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1091
0
  return C.convertModule();
1092
0
}
1093
1094
/// Simple diagnostic handler that prints diagnostics to standard error.
1095
0
static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context) {
1096
0
  Diag.print(nullptr, llvm::errs());
1097
0
}
1098
1099
bool api_notes::compileAPINotes(StringRef YAMLInput,
1100
                                const FileEntry *SourceFile,
1101
                                llvm::raw_ostream &OS,
1102
                                llvm::SourceMgr::DiagHandlerTy DiagHandler,
1103
0
                                void *DiagHandlerCtxt) {
1104
0
  Module TheModule;
1105
1106
0
  if (!DiagHandler)
1107
0
    DiagHandler = &printDiagnostic;
1108
1109
0
  if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1110
0
    return true;
1111
1112
0
  return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1113
0
}