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 19 namespace llvm { 20 class raw_ostream; 21 } // namespace llvm 22 23 namespace clang { 24 namespace api_notes { 25 enum 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. 36 enum class EnumExtensibilityKind { 37 None, 38 Open, 39 Closed, 40 }; 41 42 /// The kind of a swift_wrapper/swift_newtype. 43 enum 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. 52 class CommonEntityInfo { 53 public: 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 65 private: 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 74 public: 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(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 120 inline 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 129 inline bool operator!=(const CommonEntityInfo &LHS, 130 const CommonEntityInfo &RHS) { 131 return !(LHS == RHS); 132 } 133 134 /// Describes API notes for types. 135 class 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 144 public: 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 185 inline 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 191 inline 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 or a C++ 196 /// namespace. 197 class ContextInfo : public CommonTypeInfo { 198 /// Whether this class has a default nullability. 199 LLVM_PREFERRED_TYPE(bool) 200 unsigned HasDefaultNullability : 1; 201 202 /// The default nullability. 203 LLVM_PREFERRED_TYPE(NullabilityKind) 204 unsigned DefaultNullability : 2; 205 206 /// Whether this class has designated initializers recorded. 207 LLVM_PREFERRED_TYPE(bool) 208 unsigned HasDesignatedInits : 1; 209 210 LLVM_PREFERRED_TYPE(bool) 211 unsigned SwiftImportAsNonGenericSpecified : 1; 212 LLVM_PREFERRED_TYPE(bool) 213 unsigned SwiftImportAsNonGeneric : 1; 214 215 LLVM_PREFERRED_TYPE(bool) 216 unsigned SwiftObjCMembersSpecified : 1; 217 LLVM_PREFERRED_TYPE(bool) 218 unsigned SwiftObjCMembers : 1; 219 220 public: 221 ContextInfo() 222 : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0), 223 SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false), 224 SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {} 225 226 /// Determine the default nullability for properties and methods of this 227 /// class. 228 /// 229 /// Returns the default nullability, if implied, or std::nullopt if there is 230 /// none. 231 std::optional<NullabilityKind> getDefaultNullability() const { 232 return HasDefaultNullability 233 ? std::optional<NullabilityKind>( 234 static_cast<NullabilityKind>(DefaultNullability)) 235 : std::nullopt; 236 } 237 238 /// Set the default nullability for properties and methods of this class. 239 void setDefaultNullability(NullabilityKind Kind) { 240 HasDefaultNullability = true; 241 DefaultNullability = static_cast<unsigned>(Kind); 242 } 243 244 bool hasDesignatedInits() const { return HasDesignatedInits; } 245 void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; } 246 247 std::optional<bool> getSwiftImportAsNonGeneric() const { 248 return SwiftImportAsNonGenericSpecified 249 ? std::optional<bool>(SwiftImportAsNonGeneric) 250 : std::nullopt; 251 } 252 void setSwiftImportAsNonGeneric(std::optional<bool> Value) { 253 SwiftImportAsNonGenericSpecified = Value.has_value(); 254 SwiftImportAsNonGeneric = Value.value_or(false); 255 } 256 257 std::optional<bool> getSwiftObjCMembers() const { 258 return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers) 259 : std::nullopt; 260 } 261 void setSwiftObjCMembers(std::optional<bool> Value) { 262 SwiftObjCMembersSpecified = Value.has_value(); 263 SwiftObjCMembers = Value.value_or(false); 264 } 265 266 friend bool operator==(const ContextInfo &, const ContextInfo &); 267 268 ContextInfo &operator|=(const ContextInfo &RHS) { 269 // Merge inherited info. 270 static_cast<CommonTypeInfo &>(*this) |= RHS; 271 272 // Merge nullability. 273 if (!getDefaultNullability()) 274 if (auto Nullability = RHS.getDefaultNullability()) 275 setDefaultNullability(*Nullability); 276 277 if (!SwiftImportAsNonGenericSpecified) 278 setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric()); 279 280 if (!SwiftObjCMembersSpecified) 281 setSwiftObjCMembers(RHS.getSwiftObjCMembers()); 282 283 HasDesignatedInits |= RHS.HasDesignatedInits; 284 285 return *this; 286 } 287 288 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 289 }; 290 291 inline bool operator==(const ContextInfo &LHS, const ContextInfo &RHS) { 292 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 293 LHS.getDefaultNullability() == RHS.getDefaultNullability() && 294 LHS.HasDesignatedInits == RHS.HasDesignatedInits && 295 LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() && 296 LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers(); 297 } 298 299 inline bool operator!=(const ContextInfo &LHS, const ContextInfo &RHS) { 300 return !(LHS == RHS); 301 } 302 303 /// API notes for a variable/property. 304 class VariableInfo : public CommonEntityInfo { 305 /// Whether this property has been audited for nullability. 306 LLVM_PREFERRED_TYPE(bool) 307 unsigned NullabilityAudited : 1; 308 309 /// The kind of nullability for this property. Only valid if the nullability 310 /// has been audited. 311 LLVM_PREFERRED_TYPE(NullabilityKind) 312 unsigned Nullable : 2; 313 314 /// The C type of the variable, as a string. 315 std::string Type; 316 317 public: 318 VariableInfo() : NullabilityAudited(false), Nullable(0) {} 319 320 std::optional<NullabilityKind> getNullability() const { 321 return NullabilityAudited ? std::optional<NullabilityKind>( 322 static_cast<NullabilityKind>(Nullable)) 323 : std::nullopt; 324 } 325 326 void setNullabilityAudited(NullabilityKind kind) { 327 NullabilityAudited = true; 328 Nullable = static_cast<unsigned>(kind); 329 } 330 331 const std::string &getType() const { return Type; } 332 void setType(const std::string &type) { Type = type; } 333 334 friend bool operator==(const VariableInfo &, const VariableInfo &); 335 336 VariableInfo &operator|=(const VariableInfo &RHS) { 337 static_cast<CommonEntityInfo &>(*this) |= RHS; 338 339 if (!NullabilityAudited && RHS.NullabilityAudited) 340 setNullabilityAudited(*RHS.getNullability()); 341 if (Type.empty()) 342 Type = RHS.Type; 343 344 return *this; 345 } 346 347 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 348 }; 349 350 inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) { 351 return static_cast<const CommonEntityInfo &>(LHS) == RHS && 352 LHS.NullabilityAudited == RHS.NullabilityAudited && 353 LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type; 354 } 355 356 inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) { 357 return !(LHS == RHS); 358 } 359 360 /// Describes API notes data for an Objective-C property. 361 class ObjCPropertyInfo : public VariableInfo { 362 LLVM_PREFERRED_TYPE(bool) 363 unsigned SwiftImportAsAccessorsSpecified : 1; 364 LLVM_PREFERRED_TYPE(bool) 365 unsigned SwiftImportAsAccessors : 1; 366 367 public: 368 ObjCPropertyInfo() 369 : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {} 370 371 std::optional<bool> getSwiftImportAsAccessors() const { 372 return SwiftImportAsAccessorsSpecified 373 ? std::optional<bool>(SwiftImportAsAccessors) 374 : std::nullopt; 375 } 376 void setSwiftImportAsAccessors(std::optional<bool> Value) { 377 SwiftImportAsAccessorsSpecified = Value.has_value(); 378 SwiftImportAsAccessors = Value.value_or(false); 379 } 380 381 friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &); 382 383 /// Merge class-wide information into the given property. 384 ObjCPropertyInfo &operator|=(const ContextInfo &RHS) { 385 static_cast<CommonEntityInfo &>(*this) |= RHS; 386 387 // Merge nullability. 388 if (!getNullability()) 389 if (auto Nullable = RHS.getDefaultNullability()) 390 setNullabilityAudited(*Nullable); 391 392 return *this; 393 } 394 395 ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) { 396 static_cast<VariableInfo &>(*this) |= RHS; 397 398 if (!SwiftImportAsAccessorsSpecified) 399 setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors()); 400 401 return *this; 402 } 403 404 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 405 }; 406 407 inline bool operator==(const ObjCPropertyInfo &LHS, 408 const ObjCPropertyInfo &RHS) { 409 return static_cast<const VariableInfo &>(LHS) == RHS && 410 LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors(); 411 } 412 413 inline bool operator!=(const ObjCPropertyInfo &LHS, 414 const ObjCPropertyInfo &RHS) { 415 return !(LHS == RHS); 416 } 417 418 /// Describes a function or method parameter. 419 class ParamInfo : public VariableInfo { 420 /// Whether noescape was specified. 421 LLVM_PREFERRED_TYPE(bool) 422 unsigned NoEscapeSpecified : 1; 423 424 /// Whether the this parameter has the 'noescape' attribute. 425 LLVM_PREFERRED_TYPE(bool) 426 unsigned NoEscape : 1; 427 428 /// Whether lifetimebound was specified. 429 LLVM_PREFERRED_TYPE(bool) 430 unsigned LifetimeboundSpecified : 1; 431 432 /// Whether the this parameter has the 'lifetimebound' attribute. 433 LLVM_PREFERRED_TYPE(bool) 434 unsigned Lifetimebound : 1; 435 436 /// A biased RetainCountConventionKind, where 0 means "unspecified". 437 /// 438 /// Only relevant for out-parameters. 439 unsigned RawRetainCountConvention : 3; 440 441 public: 442 ParamInfo() 443 : NoEscapeSpecified(false), NoEscape(false), 444 LifetimeboundSpecified(false), Lifetimebound(false), 445 RawRetainCountConvention() {} 446 447 std::optional<bool> isNoEscape() const { 448 return NoEscapeSpecified ? std::optional<bool>(NoEscape) : std::nullopt; 449 } 450 void setNoEscape(std::optional<bool> Value) { 451 NoEscapeSpecified = Value.has_value(); 452 NoEscape = Value.value_or(false); 453 } 454 455 std::optional<bool> isLifetimebound() const { 456 return LifetimeboundSpecified ? std::optional<bool>(Lifetimebound) 457 : std::nullopt; 458 } 459 void setLifetimebound(std::optional<bool> Value) { 460 LifetimeboundSpecified = Value.has_value(); 461 Lifetimebound = Value.value_or(false); 462 } 463 464 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 465 if (!RawRetainCountConvention) 466 return std::nullopt; 467 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 468 } 469 void 470 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) { 471 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0; 472 assert(getRetainCountConvention() == Value && "bitfield too small"); 473 } 474 475 ParamInfo &operator|=(const ParamInfo &RHS) { 476 static_cast<VariableInfo &>(*this) |= RHS; 477 478 if (!NoEscapeSpecified && RHS.NoEscapeSpecified) { 479 NoEscapeSpecified = true; 480 NoEscape = RHS.NoEscape; 481 } 482 483 if (!LifetimeboundSpecified && RHS.LifetimeboundSpecified) { 484 LifetimeboundSpecified = true; 485 Lifetimebound = RHS.Lifetimebound; 486 } 487 488 if (!RawRetainCountConvention) 489 RawRetainCountConvention = RHS.RawRetainCountConvention; 490 491 return *this; 492 } 493 494 friend bool operator==(const ParamInfo &, const ParamInfo &); 495 496 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 497 }; 498 499 inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) { 500 return static_cast<const VariableInfo &>(LHS) == RHS && 501 LHS.NoEscapeSpecified == RHS.NoEscapeSpecified && 502 LHS.NoEscape == RHS.NoEscape && 503 LHS.LifetimeboundSpecified == RHS.LifetimeboundSpecified && 504 LHS.Lifetimebound == RHS.Lifetimebound && 505 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; 506 } 507 508 inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) { 509 return !(LHS == RHS); 510 } 511 512 /// API notes for a function or method. 513 class FunctionInfo : public CommonEntityInfo { 514 private: 515 static constexpr const uint64_t NullabilityKindMask = 0x3; 516 static constexpr const unsigned NullabilityKindSize = 2; 517 518 static constexpr const unsigned ReturnInfoIndex = 0; 519 520 public: 521 // If yes, we consider all types to be non-nullable unless otherwise noted. 522 // If this flag is not set, the pointer types are considered to have 523 // unknown nullability. 524 525 /// Whether the signature has been audited with respect to nullability. 526 LLVM_PREFERRED_TYPE(bool) 527 unsigned NullabilityAudited : 1; 528 529 /// Number of types whose nullability is encoded with the NullabilityPayload. 530 unsigned NumAdjustedNullable : 8; 531 532 /// A biased RetainCountConventionKind, where 0 means "unspecified". 533 unsigned RawRetainCountConvention : 3; 534 535 // NullabilityKindSize bits are used to encode the nullability. The info 536 // about the return type is stored at position 0, followed by the nullability 537 // of the parameters. 538 539 /// Stores the nullability of the return type and the parameters. 540 uint64_t NullabilityPayload = 0; 541 542 /// The result type of this function, as a C type. 543 std::string ResultType; 544 545 /// Ownership convention for return value 546 std::string SwiftReturnOwnership; 547 548 /// The function parameters. 549 std::vector<ParamInfo> Params; 550 551 FunctionInfo() 552 : NullabilityAudited(false), NumAdjustedNullable(0), 553 RawRetainCountConvention() {} 554 555 static unsigned getMaxNullabilityIndex() { 556 return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize); 557 } 558 559 void addTypeInfo(unsigned index, NullabilityKind kind) { 560 assert(index <= getMaxNullabilityIndex()); 561 assert(static_cast<unsigned>(kind) < NullabilityKindMask); 562 563 NullabilityAudited = true; 564 if (NumAdjustedNullable < index + 1) 565 NumAdjustedNullable = index + 1; 566 567 // Mask the bits. 568 NullabilityPayload &= 569 ~(NullabilityKindMask << (index * NullabilityKindSize)); 570 571 // Set the value. 572 unsigned kindValue = (static_cast<unsigned>(kind)) 573 << (index * NullabilityKindSize); 574 NullabilityPayload |= kindValue; 575 } 576 577 /// Adds the return type info. 578 void addReturnTypeInfo(NullabilityKind kind) { 579 addTypeInfo(ReturnInfoIndex, kind); 580 } 581 582 /// Adds the parameter type info. 583 void addParamTypeInfo(unsigned index, NullabilityKind kind) { 584 addTypeInfo(index + 1, kind); 585 } 586 587 NullabilityKind getParamTypeInfo(unsigned index) const { 588 return getTypeInfo(index + 1); 589 } 590 591 NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); } 592 593 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 594 if (!RawRetainCountConvention) 595 return std::nullopt; 596 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 597 } 598 void 599 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) { 600 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0; 601 assert(getRetainCountConvention() == Value && "bitfield too small"); 602 } 603 604 friend bool operator==(const FunctionInfo &, const FunctionInfo &); 605 606 private: 607 NullabilityKind getTypeInfo(unsigned index) const { 608 assert(NullabilityAudited && 609 "Checking the type adjustment on non-audited method."); 610 611 // If we don't have info about this parameter, return the default. 612 if (index > NumAdjustedNullable) 613 return NullabilityKind::NonNull; 614 auto nullability = NullabilityPayload >> (index * NullabilityKindSize); 615 return static_cast<NullabilityKind>(nullability & NullabilityKindMask); 616 } 617 618 public: 619 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 620 }; 621 622 inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { 623 return static_cast<const CommonEntityInfo &>(LHS) == RHS && 624 LHS.NullabilityAudited == RHS.NullabilityAudited && 625 LHS.NumAdjustedNullable == RHS.NumAdjustedNullable && 626 LHS.NullabilityPayload == RHS.NullabilityPayload && 627 LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params && 628 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention && 629 LHS.SwiftReturnOwnership == RHS.SwiftReturnOwnership; 630 } 631 632 inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { 633 return !(LHS == RHS); 634 } 635 636 /// Describes API notes data for an Objective-C method. 637 class ObjCMethodInfo : public FunctionInfo { 638 public: 639 /// Whether this is a designated initializer of its class. 640 LLVM_PREFERRED_TYPE(bool) 641 unsigned DesignatedInit : 1; 642 643 /// Whether this is a required initializer. 644 LLVM_PREFERRED_TYPE(bool) 645 unsigned RequiredInit : 1; 646 647 std::optional<ParamInfo> Self; 648 649 ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {} 650 651 friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &); 652 653 ObjCMethodInfo &operator|=(const ContextInfo &RHS) { 654 // Merge Nullability. 655 if (!NullabilityAudited) { 656 if (auto Nullable = RHS.getDefaultNullability()) { 657 NullabilityAudited = true; 658 addTypeInfo(0, *Nullable); 659 } 660 } 661 return *this; 662 } 663 664 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 665 }; 666 667 inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { 668 return static_cast<const FunctionInfo &>(LHS) == RHS && 669 LHS.DesignatedInit == RHS.DesignatedInit && 670 LHS.RequiredInit == RHS.RequiredInit && LHS.Self == RHS.Self; 671 } 672 673 inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { 674 return !(LHS == RHS); 675 } 676 677 /// Describes API notes data for a global variable. 678 class GlobalVariableInfo : public VariableInfo { 679 public: 680 GlobalVariableInfo() {} 681 }; 682 683 /// Describes API notes data for a global function. 684 class GlobalFunctionInfo : public FunctionInfo { 685 public: 686 GlobalFunctionInfo() {} 687 }; 688 689 /// Describes API notes data for a C/C++ record field. 690 class FieldInfo : public VariableInfo { 691 public: 692 FieldInfo() {} 693 }; 694 695 /// Describes API notes data for a C++ method. 696 class CXXMethodInfo : public FunctionInfo { 697 public: 698 CXXMethodInfo() {} 699 700 std::optional<ParamInfo> This; 701 702 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 703 }; 704 705 inline bool operator==(const CXXMethodInfo &LHS, const CXXMethodInfo &RHS) { 706 return static_cast<const FunctionInfo &>(LHS) == RHS && LHS.This == RHS.This; 707 } 708 709 inline bool operator!=(const CXXMethodInfo &LHS, const CXXMethodInfo &RHS) { 710 return !(LHS == RHS); 711 } 712 713 /// Describes API notes data for an enumerator. 714 class EnumConstantInfo : public CommonEntityInfo { 715 public: 716 EnumConstantInfo() {} 717 }; 718 719 /// Describes API notes data for a tag. 720 class TagInfo : public CommonTypeInfo { 721 LLVM_PREFERRED_TYPE(bool) 722 unsigned HasFlagEnum : 1; 723 LLVM_PREFERRED_TYPE(bool) 724 unsigned IsFlagEnum : 1; 725 726 LLVM_PREFERRED_TYPE(bool) 727 unsigned SwiftCopyableSpecified : 1; 728 LLVM_PREFERRED_TYPE(bool) 729 unsigned SwiftCopyable : 1; 730 731 LLVM_PREFERRED_TYPE(bool) 732 unsigned SwiftEscapableSpecified : 1; 733 LLVM_PREFERRED_TYPE(bool) 734 unsigned SwiftEscapable : 1; 735 736 public: 737 std::optional<std::string> SwiftImportAs; 738 std::optional<std::string> SwiftRetainOp; 739 std::optional<std::string> SwiftReleaseOp; 740 741 /// The Swift protocol that this type should be automatically conformed to. 742 std::optional<std::string> SwiftConformance; 743 744 std::optional<EnumExtensibilityKind> EnumExtensibility; 745 746 TagInfo() 747 : HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false), 748 SwiftCopyable(false), SwiftEscapableSpecified(false), 749 SwiftEscapable(false) {} 750 751 std::optional<bool> isFlagEnum() const { 752 if (HasFlagEnum) 753 return IsFlagEnum; 754 return std::nullopt; 755 } 756 void setFlagEnum(std::optional<bool> Value) { 757 HasFlagEnum = Value.has_value(); 758 IsFlagEnum = Value.value_or(false); 759 } 760 761 std::optional<bool> isSwiftCopyable() const { 762 return SwiftCopyableSpecified ? std::optional<bool>(SwiftCopyable) 763 : std::nullopt; 764 } 765 void setSwiftCopyable(std::optional<bool> Value) { 766 SwiftCopyableSpecified = Value.has_value(); 767 SwiftCopyable = Value.value_or(false); 768 } 769 770 std::optional<bool> isSwiftEscapable() const { 771 return SwiftEscapableSpecified ? std::optional<bool>(SwiftEscapable) 772 : std::nullopt; 773 } 774 775 void setSwiftEscapable(std::optional<bool> Value) { 776 SwiftEscapableSpecified = Value.has_value(); 777 SwiftEscapable = Value.value_or(false); 778 } 779 780 TagInfo &operator|=(const TagInfo &RHS) { 781 static_cast<CommonTypeInfo &>(*this) |= RHS; 782 783 if (!SwiftImportAs) 784 SwiftImportAs = RHS.SwiftImportAs; 785 if (!SwiftRetainOp) 786 SwiftRetainOp = RHS.SwiftRetainOp; 787 if (!SwiftReleaseOp) 788 SwiftReleaseOp = RHS.SwiftReleaseOp; 789 790 if (!SwiftConformance) 791 SwiftConformance = RHS.SwiftConformance; 792 793 if (!HasFlagEnum) 794 setFlagEnum(RHS.isFlagEnum()); 795 796 if (!EnumExtensibility) 797 EnumExtensibility = RHS.EnumExtensibility; 798 799 if (!SwiftCopyableSpecified) 800 setSwiftCopyable(RHS.isSwiftCopyable()); 801 802 if (!SwiftEscapableSpecified) 803 setSwiftEscapable(RHS.isSwiftEscapable()); 804 805 return *this; 806 } 807 808 friend bool operator==(const TagInfo &, const TagInfo &); 809 810 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 811 }; 812 813 inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) { 814 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 815 LHS.SwiftImportAs == RHS.SwiftImportAs && 816 LHS.SwiftRetainOp == RHS.SwiftRetainOp && 817 LHS.SwiftReleaseOp == RHS.SwiftReleaseOp && 818 LHS.SwiftConformance == RHS.SwiftConformance && 819 LHS.isFlagEnum() == RHS.isFlagEnum() && 820 LHS.isSwiftCopyable() == RHS.isSwiftCopyable() && 821 LHS.isSwiftEscapable() == RHS.isSwiftEscapable() && 822 LHS.EnumExtensibility == RHS.EnumExtensibility; 823 } 824 825 inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) { 826 return !(LHS == RHS); 827 } 828 829 /// Describes API notes data for a typedef. 830 class TypedefInfo : public CommonTypeInfo { 831 public: 832 std::optional<SwiftNewTypeKind> SwiftWrapper; 833 834 TypedefInfo() {} 835 836 TypedefInfo &operator|=(const TypedefInfo &RHS) { 837 static_cast<CommonTypeInfo &>(*this) |= RHS; 838 if (!SwiftWrapper) 839 SwiftWrapper = RHS.SwiftWrapper; 840 return *this; 841 } 842 843 friend bool operator==(const TypedefInfo &, const TypedefInfo &); 844 845 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 846 }; 847 848 inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) { 849 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 850 LHS.SwiftWrapper == RHS.SwiftWrapper; 851 } 852 853 inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) { 854 return !(LHS == RHS); 855 } 856 857 /// The file extension used for the source representation of API notes. 858 static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes"; 859 860 /// Opaque context ID used to refer to an Objective-C class or protocol or a C++ 861 /// namespace. 862 class ContextID { 863 public: 864 unsigned Value; 865 866 explicit ContextID(unsigned value) : Value(value) {} 867 }; 868 869 enum class ContextKind : uint8_t { 870 ObjCClass = 0, 871 ObjCProtocol = 1, 872 Namespace = 2, 873 Tag = 3, 874 }; 875 876 struct Context { 877 ContextID id; 878 ContextKind kind; 879 880 Context(ContextID id, ContextKind kind) : id(id), kind(kind) {} 881 }; 882 883 /// A temporary reference to an Objective-C selector, suitable for 884 /// referencing selector data on the stack. 885 /// 886 /// Instances of this struct do not store references to any of the 887 /// data they contain; it is up to the user to ensure that the data 888 /// referenced by the identifier list persists. 889 struct ObjCSelectorRef { 890 unsigned NumArgs; 891 llvm::ArrayRef<llvm::StringRef> Identifiers; 892 }; 893 } // namespace api_notes 894 } // namespace clang 895 896 #endif 897