1//===-- Types.h - API Notes Data Types --------------------------*- 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#ifndef LLVM_CLANG_APINOTES_TYPES_H
10#define LLVM_CLANG_APINOTES_TYPES_H
11
12#include "clang/Basic/Specifiers.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15#include <climits>
16#include <optional>
17#include <vector>
18
19namespace llvm {
20class raw_ostream;
21} // namespace llvm
22
23namespace clang {
24namespace api_notes {
25enum class RetainCountConventionKind {
26 None,
27 CFReturnsRetained,
28 CFReturnsNotRetained,
29 NSReturnsRetained,
30 NSReturnsNotRetained,
31};
32
33/// The payload for an enum_extensibility attribute. This is a tri-state rather
34/// than just a boolean because the presence of the attribute indicates
35/// auditing.
36enum class EnumExtensibilityKind {
37 None,
38 Open,
39 Closed,
40};
41
42/// The kind of a swift_wrapper/swift_newtype.
43enum class SwiftNewTypeKind {
44 None,
45 Struct,
46 Enum,
47};
48
49/// Describes API notes data for any entity.
50///
51/// This is used as the base of all API notes.
52class CommonEntityInfo {
53public:
54 /// Message to use when this entity is unavailable.
55 std::string UnavailableMsg;
56
57 /// Whether this entity is marked unavailable.
58 LLVM_PREFERRED_TYPE(bool)
59 unsigned Unavailable : 1;
60
61 /// Whether this entity is marked unavailable in Swift.
62 LLVM_PREFERRED_TYPE(bool)
63 unsigned UnavailableInSwift : 1;
64
65private:
66 /// Whether SwiftPrivate was specified.
67 LLVM_PREFERRED_TYPE(bool)
68 unsigned SwiftPrivateSpecified : 1;
69
70 /// Whether this entity is considered "private" to a Swift overlay.
71 LLVM_PREFERRED_TYPE(bool)
72 unsigned SwiftPrivate : 1;
73
74public:
75 /// Swift name of this entity.
76 std::string SwiftName;
77
78 CommonEntityInfo()
79 : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
80 SwiftPrivate(0) {}
81
82 std::optional<bool> isSwiftPrivate() const {
83 return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
84 : std::nullopt;
85 }
86
87 void setSwiftPrivate(std::optional<bool> Private) {
88 SwiftPrivateSpecified = Private.has_value();
89 SwiftPrivate = Private.value_or(u: 0);
90 }
91
92 friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
93
94 CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) {
95 // Merge unavailability.
96 if (RHS.Unavailable) {
97 Unavailable = true;
98 if (UnavailableMsg.empty())
99 UnavailableMsg = RHS.UnavailableMsg;
100 }
101
102 if (RHS.UnavailableInSwift) {
103 UnavailableInSwift = true;
104 if (UnavailableMsg.empty())
105 UnavailableMsg = RHS.UnavailableMsg;
106 }
107
108 if (!SwiftPrivateSpecified)
109 setSwiftPrivate(RHS.isSwiftPrivate());
110
111 if (SwiftName.empty())
112 SwiftName = RHS.SwiftName;
113
114 return *this;
115 }
116
117 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
118};
119
120inline bool operator==(const CommonEntityInfo &LHS,
121 const CommonEntityInfo &RHS) {
122 return LHS.UnavailableMsg == RHS.UnavailableMsg &&
123 LHS.Unavailable == RHS.Unavailable &&
124 LHS.UnavailableInSwift == RHS.UnavailableInSwift &&
125 LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
126 LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName;
127}
128
129inline bool operator!=(const CommonEntityInfo &LHS,
130 const CommonEntityInfo &RHS) {
131 return !(LHS == RHS);
132}
133
134/// Describes API notes for types.
135class CommonTypeInfo : public CommonEntityInfo {
136 /// The Swift type to which a given type is bridged.
137 ///
138 /// Reflects the swift_bridge attribute.
139 std::optional<std::string> SwiftBridge;
140
141 /// The NS error domain for this type.
142 std::optional<std::string> NSErrorDomain;
143
144public:
145 CommonTypeInfo() {}
146
147 const std::optional<std::string> &getSwiftBridge() const {
148 return SwiftBridge;
149 }
150
151 void setSwiftBridge(std::optional<std::string> SwiftType) {
152 SwiftBridge = SwiftType;
153 }
154
155 const std::optional<std::string> &getNSErrorDomain() const {
156 return NSErrorDomain;
157 }
158
159 void setNSErrorDomain(const std::optional<std::string> &Domain) {
160 NSErrorDomain = Domain;
161 }
162
163 void setNSErrorDomain(const std::optional<llvm::StringRef> &Domain) {
164 NSErrorDomain = Domain ? std::optional<std::string>(std::string(*Domain))
165 : std::nullopt;
166 }
167
168 friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
169
170 CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
171 // Merge inherited info.
172 static_cast<CommonEntityInfo &>(*this) |= RHS;
173
174 if (!SwiftBridge)
175 setSwiftBridge(RHS.getSwiftBridge());
176 if (!NSErrorDomain)
177 setNSErrorDomain(RHS.getNSErrorDomain());
178
179 return *this;
180 }
181
182 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
183};
184
185inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
186 return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
187 LHS.SwiftBridge == RHS.SwiftBridge &&
188 LHS.NSErrorDomain == RHS.NSErrorDomain;
189}
190
191inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
192 return !(LHS == RHS);
193}
194
195/// Describes API notes data for an Objective-C class or protocol.
196class ObjCContextInfo : public CommonTypeInfo {
197 /// Whether this class has a default nullability.
198 LLVM_PREFERRED_TYPE(bool)
199 unsigned HasDefaultNullability : 1;
200
201 /// The default nullability.
202 LLVM_PREFERRED_TYPE(NullabilityKind)
203 unsigned DefaultNullability : 2;
204
205 /// Whether this class has designated initializers recorded.
206 LLVM_PREFERRED_TYPE(bool)
207 unsigned HasDesignatedInits : 1;
208
209 LLVM_PREFERRED_TYPE(bool)
210 unsigned SwiftImportAsNonGenericSpecified : 1;
211 LLVM_PREFERRED_TYPE(bool)
212 unsigned SwiftImportAsNonGeneric : 1;
213
214 LLVM_PREFERRED_TYPE(bool)
215 unsigned SwiftObjCMembersSpecified : 1;
216 LLVM_PREFERRED_TYPE(bool)
217 unsigned SwiftObjCMembers : 1;
218
219public:
220 ObjCContextInfo()
221 : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0),
222 SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false),
223 SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {}
224
225 /// Determine the default nullability for properties and methods of this
226 /// class.
227 ///
228 /// Returns the default nullability, if implied, or std::nullopt if there is
229 /// none.
230 std::optional<NullabilityKind> getDefaultNullability() const {
231 return HasDefaultNullability
232 ? std::optional<NullabilityKind>(
233 static_cast<NullabilityKind>(DefaultNullability))
234 : std::nullopt;
235 }
236
237 /// Set the default nullability for properties and methods of this class.
238 void setDefaultNullability(NullabilityKind Kind) {
239 HasDefaultNullability = true;
240 DefaultNullability = static_cast<unsigned>(Kind);
241 }
242
243 bool hasDesignatedInits() const { return HasDesignatedInits; }
244 void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; }
245
246 std::optional<bool> getSwiftImportAsNonGeneric() const {
247 return SwiftImportAsNonGenericSpecified
248 ? std::optional<bool>(SwiftImportAsNonGeneric)
249 : std::nullopt;
250 }
251 void setSwiftImportAsNonGeneric(std::optional<bool> Value) {
252 SwiftImportAsNonGenericSpecified = Value.has_value();
253 SwiftImportAsNonGeneric = Value.value_or(u: false);
254 }
255
256 std::optional<bool> getSwiftObjCMembers() const {
257 return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers)
258 : std::nullopt;
259 }
260 void setSwiftObjCMembers(std::optional<bool> Value) {
261 SwiftObjCMembersSpecified = Value.has_value();
262 SwiftObjCMembers = Value.value_or(u: false);
263 }
264
265 /// Strip off any information within the class information structure that is
266 /// module-local, such as 'audited' flags.
267 void stripModuleLocalInfo() {
268 HasDefaultNullability = false;
269 DefaultNullability = 0;
270 }
271
272 friend bool operator==(const ObjCContextInfo &, const ObjCContextInfo &);
273
274 ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) {
275 // Merge inherited info.
276 static_cast<CommonTypeInfo &>(*this) |= RHS;
277
278 // Merge nullability.
279 if (!getDefaultNullability())
280 if (auto Nullability = RHS.getDefaultNullability())
281 setDefaultNullability(*Nullability);
282
283 if (!SwiftImportAsNonGenericSpecified)
284 setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric());
285
286 if (!SwiftObjCMembersSpecified)
287 setSwiftObjCMembers(RHS.getSwiftObjCMembers());
288
289 HasDesignatedInits |= RHS.HasDesignatedInits;
290
291 return *this;
292 }
293
294 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
295};
296
297inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
298 return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
299 LHS.getDefaultNullability() == RHS.getDefaultNullability() &&
300 LHS.HasDesignatedInits == RHS.HasDesignatedInits &&
301 LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() &&
302 LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers();
303}
304
305inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
306 return !(LHS == RHS);
307}
308
309/// API notes for a variable/property.
310class VariableInfo : public CommonEntityInfo {
311 /// Whether this property has been audited for nullability.
312 LLVM_PREFERRED_TYPE(bool)
313 unsigned NullabilityAudited : 1;
314
315 /// The kind of nullability for this property. Only valid if the nullability
316 /// has been audited.
317 LLVM_PREFERRED_TYPE(NullabilityKind)
318 unsigned Nullable : 2;
319
320 /// The C type of the variable, as a string.
321 std::string Type;
322
323public:
324 VariableInfo() : NullabilityAudited(false), Nullable(0) {}
325
326 std::optional<NullabilityKind> getNullability() const {
327 return NullabilityAudited ? std::optional<NullabilityKind>(
328 static_cast<NullabilityKind>(Nullable))
329 : std::nullopt;
330 }
331
332 void setNullabilityAudited(NullabilityKind kind) {
333 NullabilityAudited = true;
334 Nullable = static_cast<unsigned>(kind);
335 }
336
337 const std::string &getType() const { return Type; }
338 void setType(const std::string &type) { Type = type; }
339
340 friend bool operator==(const VariableInfo &, const VariableInfo &);
341
342 VariableInfo &operator|=(const VariableInfo &RHS) {
343 static_cast<CommonEntityInfo &>(*this) |= RHS;
344
345 if (!NullabilityAudited && RHS.NullabilityAudited)
346 setNullabilityAudited(*RHS.getNullability());
347 if (Type.empty())
348 Type = RHS.Type;
349
350 return *this;
351 }
352
353 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
354};
355
356inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) {
357 return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
358 LHS.NullabilityAudited == RHS.NullabilityAudited &&
359 LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type;
360}
361
362inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) {
363 return !(LHS == RHS);
364}
365
366/// Describes API notes data for an Objective-C property.
367class ObjCPropertyInfo : public VariableInfo {
368 LLVM_PREFERRED_TYPE(bool)
369 unsigned SwiftImportAsAccessorsSpecified : 1;
370 LLVM_PREFERRED_TYPE(bool)
371 unsigned SwiftImportAsAccessors : 1;
372
373public:
374 ObjCPropertyInfo()
375 : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
376
377 std::optional<bool> getSwiftImportAsAccessors() const {
378 return SwiftImportAsAccessorsSpecified
379 ? std::optional<bool>(SwiftImportAsAccessors)
380 : std::nullopt;
381 }
382 void setSwiftImportAsAccessors(std::optional<bool> Value) {
383 SwiftImportAsAccessorsSpecified = Value.has_value();
384 SwiftImportAsAccessors = Value.value_or(u: false);
385 }
386
387 friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
388
389 /// Merge class-wide information into the given property.
390 ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) {
391 static_cast<CommonEntityInfo &>(*this) |= RHS;
392
393 // Merge nullability.
394 if (!getNullability())
395 if (auto Nullable = RHS.getDefaultNullability())
396 setNullabilityAudited(*Nullable);
397
398 return *this;
399 }
400
401 ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) {
402 static_cast<VariableInfo &>(*this) |= RHS;
403
404 if (!SwiftImportAsAccessorsSpecified)
405 setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors());
406
407 return *this;
408 }
409
410 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
411};
412
413inline bool operator==(const ObjCPropertyInfo &LHS,
414 const ObjCPropertyInfo &RHS) {
415 return static_cast<const VariableInfo &>(LHS) == RHS &&
416 LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors();
417}
418
419inline bool operator!=(const ObjCPropertyInfo &LHS,
420 const ObjCPropertyInfo &RHS) {
421 return !(LHS == RHS);
422}
423
424/// Describes a function or method parameter.
425class ParamInfo : public VariableInfo {
426 /// Whether noescape was specified.
427 LLVM_PREFERRED_TYPE(bool)
428 unsigned NoEscapeSpecified : 1;
429
430 /// Whether the this parameter has the 'noescape' attribute.
431 LLVM_PREFERRED_TYPE(bool)
432 unsigned NoEscape : 1;
433
434 /// A biased RetainCountConventionKind, where 0 means "unspecified".
435 ///
436 /// Only relevant for out-parameters.
437 unsigned RawRetainCountConvention : 3;
438
439public:
440 ParamInfo()
441 : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {}
442
443 std::optional<bool> isNoEscape() const {
444 if (!NoEscapeSpecified)
445 return std::nullopt;
446 return NoEscape;
447 }
448 void setNoEscape(std::optional<bool> Value) {
449 NoEscapeSpecified = Value.has_value();
450 NoEscape = Value.value_or(u: false);
451 }
452
453 std::optional<RetainCountConventionKind> getRetainCountConvention() const {
454 if (!RawRetainCountConvention)
455 return std::nullopt;
456 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
457 }
458 void
459 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
460 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
461 assert(getRetainCountConvention() == Value && "bitfield too small");
462 }
463
464 ParamInfo &operator|=(const ParamInfo &RHS) {
465 static_cast<VariableInfo &>(*this) |= RHS;
466
467 if (!NoEscapeSpecified && RHS.NoEscapeSpecified) {
468 NoEscapeSpecified = true;
469 NoEscape = RHS.NoEscape;
470 }
471
472 if (!RawRetainCountConvention)
473 RawRetainCountConvention = RHS.RawRetainCountConvention;
474
475 return *this;
476 }
477
478 friend bool operator==(const ParamInfo &, const ParamInfo &);
479
480 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
481};
482
483inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) {
484 return static_cast<const VariableInfo &>(LHS) == RHS &&
485 LHS.NoEscapeSpecified == RHS.NoEscapeSpecified &&
486 LHS.NoEscape == RHS.NoEscape &&
487 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
488}
489
490inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
491 return !(LHS == RHS);
492}
493
494/// API notes for a function or method.
495class FunctionInfo : public CommonEntityInfo {
496private:
497 static constexpr const uint64_t NullabilityKindMask = 0x3;
498 static constexpr const unsigned NullabilityKindSize = 2;
499
500 static constexpr const unsigned ReturnInfoIndex = 0;
501
502public:
503 // If yes, we consider all types to be non-nullable unless otherwise noted.
504 // If this flag is not set, the pointer types are considered to have
505 // unknown nullability.
506
507 /// Whether the signature has been audited with respect to nullability.
508 LLVM_PREFERRED_TYPE(bool)
509 unsigned NullabilityAudited : 1;
510
511 /// Number of types whose nullability is encoded with the NullabilityPayload.
512 unsigned NumAdjustedNullable : 8;
513
514 /// A biased RetainCountConventionKind, where 0 means "unspecified".
515 unsigned RawRetainCountConvention : 3;
516
517 // NullabilityKindSize bits are used to encode the nullability. The info
518 // about the return type is stored at position 0, followed by the nullability
519 // of the parameters.
520
521 /// Stores the nullability of the return type and the parameters.
522 uint64_t NullabilityPayload = 0;
523
524 /// The result type of this function, as a C type.
525 std::string ResultType;
526
527 /// The function parameters.
528 std::vector<ParamInfo> Params;
529
530 FunctionInfo()
531 : NullabilityAudited(false), NumAdjustedNullable(0),
532 RawRetainCountConvention() {}
533
534 static unsigned getMaxNullabilityIndex() {
535 return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize);
536 }
537
538 void addTypeInfo(unsigned index, NullabilityKind kind) {
539 assert(index <= getMaxNullabilityIndex());
540 assert(static_cast<unsigned>(kind) < NullabilityKindMask);
541
542 NullabilityAudited = true;
543 if (NumAdjustedNullable < index + 1)
544 NumAdjustedNullable = index + 1;
545
546 // Mask the bits.
547 NullabilityPayload &=
548 ~(NullabilityKindMask << (index * NullabilityKindSize));
549
550 // Set the value.
551 unsigned kindValue = (static_cast<unsigned>(kind))
552 << (index * NullabilityKindSize);
553 NullabilityPayload |= kindValue;
554 }
555
556 /// Adds the return type info.
557 void addReturnTypeInfo(NullabilityKind kind) {
558 addTypeInfo(index: ReturnInfoIndex, kind);
559 }
560
561 /// Adds the parameter type info.
562 void addParamTypeInfo(unsigned index, NullabilityKind kind) {
563 addTypeInfo(index: index + 1, kind);
564 }
565
566 NullabilityKind getParamTypeInfo(unsigned index) const {
567 return getTypeInfo(index: index + 1);
568 }
569
570 NullabilityKind getReturnTypeInfo() const { return getTypeInfo(index: 0); }
571
572 std::optional<RetainCountConventionKind> getRetainCountConvention() const {
573 if (!RawRetainCountConvention)
574 return std::nullopt;
575 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
576 }
577 void
578 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
579 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
580 assert(getRetainCountConvention() == Value && "bitfield too small");
581 }
582
583 friend bool operator==(const FunctionInfo &, const FunctionInfo &);
584
585private:
586 NullabilityKind getTypeInfo(unsigned index) const {
587 assert(NullabilityAudited &&
588 "Checking the type adjustment on non-audited method.");
589
590 // If we don't have info about this parameter, return the default.
591 if (index > NumAdjustedNullable)
592 return NullabilityKind::NonNull;
593 auto nullability = NullabilityPayload >> (index * NullabilityKindSize);
594 return static_cast<NullabilityKind>(nullability & NullabilityKindMask);
595 }
596
597public:
598 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
599};
600
601inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
602 return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
603 LHS.NullabilityAudited == RHS.NullabilityAudited &&
604 LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
605 LHS.NullabilityPayload == RHS.NullabilityPayload &&
606 LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
607 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
608}
609
610inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
611 return !(LHS == RHS);
612}
613
614/// Describes API notes data for an Objective-C method.
615class ObjCMethodInfo : public FunctionInfo {
616public:
617 /// Whether this is a designated initializer of its class.
618 LLVM_PREFERRED_TYPE(bool)
619 unsigned DesignatedInit : 1;
620
621 /// Whether this is a required initializer.
622 LLVM_PREFERRED_TYPE(bool)
623 unsigned RequiredInit : 1;
624
625 ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {}
626
627 friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);
628
629 ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) {
630 // Merge Nullability.
631 if (!NullabilityAudited) {
632 if (auto Nullable = RHS.getDefaultNullability()) {
633 NullabilityAudited = true;
634 addTypeInfo(index: 0, kind: *Nullable);
635 }
636 }
637 return *this;
638 }
639
640 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
641};
642
643inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
644 return static_cast<const FunctionInfo &>(LHS) == RHS &&
645 LHS.DesignatedInit == RHS.DesignatedInit &&
646 LHS.RequiredInit == RHS.RequiredInit;
647}
648
649inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
650 return !(LHS == RHS);
651}
652
653/// Describes API notes data for a global variable.
654class GlobalVariableInfo : public VariableInfo {
655public:
656 GlobalVariableInfo() {}
657};
658
659/// Describes API notes data for a global function.
660class GlobalFunctionInfo : public FunctionInfo {
661public:
662 GlobalFunctionInfo() {}
663};
664
665/// Describes API notes data for an enumerator.
666class EnumConstantInfo : public CommonEntityInfo {
667public:
668 EnumConstantInfo() {}
669};
670
671/// Describes API notes data for a tag.
672class TagInfo : public CommonTypeInfo {
673 LLVM_PREFERRED_TYPE(bool)
674 unsigned HasFlagEnum : 1;
675 LLVM_PREFERRED_TYPE(bool)
676 unsigned IsFlagEnum : 1;
677
678public:
679 std::optional<std::string> SwiftImportAs;
680 std::optional<std::string> SwiftRetainOp;
681 std::optional<std::string> SwiftReleaseOp;
682
683 std::optional<EnumExtensibilityKind> EnumExtensibility;
684
685 TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
686
687 std::optional<bool> isFlagEnum() const {
688 if (HasFlagEnum)
689 return IsFlagEnum;
690 return std::nullopt;
691 }
692 void setFlagEnum(std::optional<bool> Value) {
693 HasFlagEnum = Value.has_value();
694 IsFlagEnum = Value.value_or(u: false);
695 }
696
697 TagInfo &operator|=(const TagInfo &RHS) {
698 static_cast<CommonTypeInfo &>(*this) |= RHS;
699
700 if (!SwiftImportAs)
701 SwiftImportAs = RHS.SwiftImportAs;
702 if (!SwiftRetainOp)
703 SwiftRetainOp = RHS.SwiftRetainOp;
704 if (!SwiftReleaseOp)
705 SwiftReleaseOp = RHS.SwiftReleaseOp;
706
707 if (!HasFlagEnum)
708 setFlagEnum(RHS.isFlagEnum());
709
710 if (!EnumExtensibility)
711 EnumExtensibility = RHS.EnumExtensibility;
712
713 return *this;
714 }
715
716 friend bool operator==(const TagInfo &, const TagInfo &);
717
718 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
719};
720
721inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
722 return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
723 LHS.SwiftImportAs == RHS.SwiftImportAs &&
724 LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
725 LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
726 LHS.isFlagEnum() == RHS.isFlagEnum() &&
727 LHS.EnumExtensibility == RHS.EnumExtensibility;
728}
729
730inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) {
731 return !(LHS == RHS);
732}
733
734/// Describes API notes data for a typedef.
735class TypedefInfo : public CommonTypeInfo {
736public:
737 std::optional<SwiftNewTypeKind> SwiftWrapper;
738
739 TypedefInfo() {}
740
741 TypedefInfo &operator|=(const TypedefInfo &RHS) {
742 static_cast<CommonTypeInfo &>(*this) |= RHS;
743 if (!SwiftWrapper)
744 SwiftWrapper = RHS.SwiftWrapper;
745 return *this;
746 }
747
748 friend bool operator==(const TypedefInfo &, const TypedefInfo &);
749
750 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
751};
752
753inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) {
754 return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
755 LHS.SwiftWrapper == RHS.SwiftWrapper;
756}
757
758inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) {
759 return !(LHS == RHS);
760}
761
762/// The file extension used for the source representation of API notes.
763static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes";
764
765/// Opaque context ID used to refer to an Objective-C class or protocol or a C++
766/// namespace.
767class ContextID {
768public:
769 unsigned Value;
770
771 explicit ContextID(unsigned value) : Value(value) {}
772};
773
774enum class ContextKind : uint8_t {
775 ObjCClass = 0,
776 ObjCProtocol = 1,
777 Namespace = 2,
778};
779
780struct Context {
781 ContextID id;
782 ContextKind kind;
783
784 Context(ContextID id, ContextKind kind) : id(id), kind(kind) {}
785};
786
787/// A temporary reference to an Objective-C selector, suitable for
788/// referencing selector data on the stack.
789///
790/// Instances of this struct do not store references to any of the
791/// data they contain; it is up to the user to ensure that the data
792/// referenced by the identifier list persists.
793struct ObjCSelectorRef {
794 unsigned NumArgs;
795 llvm::ArrayRef<llvm::StringRef> Identifiers;
796};
797} // namespace api_notes
798} // namespace clang
799
800#endif
801

source code of clang/include/clang/APINotes/Types.h