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