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