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 unsigned Unavailable : 1; 59 60 /// Whether this entity is marked unavailable in Swift. 61 unsigned UnavailableInSwift : 1; 62 63 private: 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 70 public: 71 /// Swift name of this entity. 72 std::string SwiftName; 73 CommonEntityInfo()74 CommonEntityInfo() 75 : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0), 76 SwiftPrivate(0) {} 77 isSwiftPrivate()78 std::optional<bool> isSwiftPrivate() const { 79 return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate) 80 : std::nullopt; 81 } 82 setSwiftPrivate(std::optional<bool> Private)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 116 inline 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 125 inline bool operator!=(const CommonEntityInfo &LHS, 126 const CommonEntityInfo &RHS) { 127 return !(LHS == RHS); 128 } 129 130 /// Describes API notes for types. 131 class 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 140 public: CommonTypeInfo()141 CommonTypeInfo() {} 142 getSwiftBridge()143 const std::optional<std::string> &getSwiftBridge() const { 144 return SwiftBridge; 145 } 146 setSwiftBridge(std::optional<std::string> SwiftType)147 void setSwiftBridge(std::optional<std::string> SwiftType) { 148 SwiftBridge = SwiftType; 149 } 150 getNSErrorDomain()151 const std::optional<std::string> &getNSErrorDomain() const { 152 return NSErrorDomain; 153 } 154 setNSErrorDomain(const std::optional<std::string> & Domain)155 void setNSErrorDomain(const std::optional<std::string> &Domain) { 156 NSErrorDomain = Domain; 157 } 158 setNSErrorDomain(const std::optional<llvm::StringRef> & Domain)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 181 inline 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 187 inline 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. 192 class 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 208 public: ObjCContextInfo()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. getDefaultNullability()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. setDefaultNullability(NullabilityKind Kind)227 void setDefaultNullability(NullabilityKind Kind) { 228 HasDefaultNullability = true; 229 DefaultNullability = static_cast<unsigned>(Kind); 230 } 231 hasDesignatedInits()232 bool hasDesignatedInits() const { return HasDesignatedInits; } setHasDesignatedInits(bool Value)233 void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; } 234 getSwiftImportAsNonGeneric()235 std::optional<bool> getSwiftImportAsNonGeneric() const { 236 return SwiftImportAsNonGenericSpecified 237 ? std::optional<bool>(SwiftImportAsNonGeneric) 238 : std::nullopt; 239 } setSwiftImportAsNonGeneric(std::optional<bool> Value)240 void setSwiftImportAsNonGeneric(std::optional<bool> Value) { 241 SwiftImportAsNonGenericSpecified = Value.has_value(); 242 SwiftImportAsNonGeneric = Value.value_or(false); 243 } 244 getSwiftObjCMembers()245 std::optional<bool> getSwiftObjCMembers() const { 246 return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers) 247 : std::nullopt; 248 } setSwiftObjCMembers(std::optional<bool> Value)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. stripModuleLocalInfo()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 286 inline 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 294 inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { 295 return !(LHS == RHS); 296 } 297 298 /// API notes for a variable/property. 299 class 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 310 public: VariableInfo()311 VariableInfo() : NullabilityAudited(false), Nullable(0) {} 312 getNullability()313 std::optional<NullabilityKind> getNullability() const { 314 return NullabilityAudited ? std::optional<NullabilityKind>( 315 static_cast<NullabilityKind>(Nullable)) 316 : std::nullopt; 317 } 318 setNullabilityAudited(NullabilityKind kind)319 void setNullabilityAudited(NullabilityKind kind) { 320 NullabilityAudited = true; 321 Nullable = static_cast<unsigned>(kind); 322 } 323 getType()324 const std::string &getType() const { return Type; } setType(const std::string & 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 343 inline 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 349 inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) { 350 return !(LHS == RHS); 351 } 352 353 /// Describes API notes data for an Objective-C property. 354 class ObjCPropertyInfo : public VariableInfo { 355 unsigned SwiftImportAsAccessorsSpecified : 1; 356 unsigned SwiftImportAsAccessors : 1; 357 358 public: ObjCPropertyInfo()359 ObjCPropertyInfo() 360 : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {} 361 getSwiftImportAsAccessors()362 std::optional<bool> getSwiftImportAsAccessors() const { 363 return SwiftImportAsAccessorsSpecified 364 ? std::optional<bool>(SwiftImportAsAccessors) 365 : std::nullopt; 366 } setSwiftImportAsAccessors(std::optional<bool> Value)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 398 inline bool operator==(const ObjCPropertyInfo &LHS, 399 const ObjCPropertyInfo &RHS) { 400 return static_cast<const VariableInfo &>(LHS) == RHS && 401 LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors(); 402 } 403 404 inline bool operator!=(const ObjCPropertyInfo &LHS, 405 const ObjCPropertyInfo &RHS) { 406 return !(LHS == RHS); 407 } 408 409 /// Describes a function or method parameter. 410 class 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 422 public: ParamInfo()423 ParamInfo() 424 : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {} 425 isNoEscape()426 std::optional<bool> isNoEscape() const { 427 if (!NoEscapeSpecified) 428 return std::nullopt; 429 return NoEscape; 430 } setNoEscape(std::optional<bool> Value)431 void setNoEscape(std::optional<bool> Value) { 432 NoEscapeSpecified = Value.has_value(); 433 NoEscape = Value.value_or(false); 434 } 435 getRetainCountConvention()436 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 437 if (!RawRetainCountConvention) 438 return std::nullopt; 439 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 440 } 441 void setRetainCountConvention(std::optional<RetainCountConventionKind> Value)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 466 inline 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 473 inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) { 474 return !(LHS == RHS); 475 } 476 477 /// API notes for a function or method. 478 class FunctionInfo : public CommonEntityInfo { 479 private: 480 static constexpr const uint64_t NullabilityKindMask = 0x3; 481 static constexpr const unsigned NullabilityKindSize = 2; 482 483 static constexpr const unsigned ReturnInfoIndex = 0; 484 485 public: 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 FunctionInfo()512 FunctionInfo() 513 : NullabilityAudited(false), NumAdjustedNullable(0), 514 RawRetainCountConvention() {} 515 getMaxNullabilityIndex()516 static unsigned getMaxNullabilityIndex() { 517 return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize); 518 } 519 addTypeInfo(unsigned index,NullabilityKind kind)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. addReturnTypeInfo(NullabilityKind kind)539 void addReturnTypeInfo(NullabilityKind kind) { 540 addTypeInfo(ReturnInfoIndex, kind); 541 } 542 543 /// Adds the parameter type info. addParamTypeInfo(unsigned index,NullabilityKind kind)544 void addParamTypeInfo(unsigned index, NullabilityKind kind) { 545 addTypeInfo(index + 1, kind); 546 } 547 getParamTypeInfo(unsigned index)548 NullabilityKind getParamTypeInfo(unsigned index) const { 549 return getTypeInfo(index + 1); 550 } 551 getReturnTypeInfo()552 NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); } 553 getRetainCountConvention()554 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 555 if (!RawRetainCountConvention) 556 return std::nullopt; 557 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 558 } 559 void setRetainCountConvention(std::optional<RetainCountConventionKind> Value)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 567 private: getTypeInfo(unsigned index)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 579 public: 580 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 581 }; 582 583 inline 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 592 inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { 593 return !(LHS == RHS); 594 } 595 596 /// Describes API notes data for an Objective-C method. 597 class ObjCMethodInfo : public FunctionInfo { 598 public: 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 ObjCMethodInfo()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 623 inline 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 629 inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { 630 return !(LHS == RHS); 631 } 632 633 /// Describes API notes data for a global variable. 634 class GlobalVariableInfo : public VariableInfo { 635 public: GlobalVariableInfo()636 GlobalVariableInfo() {} 637 }; 638 639 /// Describes API notes data for a global function. 640 class GlobalFunctionInfo : public FunctionInfo { 641 public: GlobalFunctionInfo()642 GlobalFunctionInfo() {} 643 }; 644 645 /// Describes API notes data for an enumerator. 646 class EnumConstantInfo : public CommonEntityInfo { 647 public: EnumConstantInfo()648 EnumConstantInfo() {} 649 }; 650 651 /// Describes API notes data for a tag. 652 class TagInfo : public CommonTypeInfo { 653 unsigned HasFlagEnum : 1; 654 unsigned IsFlagEnum : 1; 655 656 public: 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 TagInfo()663 TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {} 664 isFlagEnum()665 std::optional<bool> isFlagEnum() const { 666 if (HasFlagEnum) 667 return IsFlagEnum; 668 return std::nullopt; 669 } setFlagEnum(std::optional<bool> Value)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 699 inline 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 708 inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) { 709 return !(LHS == RHS); 710 } 711 712 /// Describes API notes data for a typedef. 713 class TypedefInfo : public CommonTypeInfo { 714 public: 715 std::optional<SwiftNewTypeKind> SwiftWrapper; 716 TypedefInfo()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 731 inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) { 732 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 733 LHS.SwiftWrapper == RHS.SwiftWrapper; 734 } 735 736 inline 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. 741 static 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. 745 class ContextID { 746 public: 747 unsigned Value; 748 ContextID(unsigned value)749 explicit ContextID(unsigned value) : Value(value) {} 750 }; 751 752 enum class ContextKind : uint8_t { 753 ObjCClass = 0, 754 ObjCProtocol = 1, 755 Namespace = 2, 756 }; 757 758 struct Context { 759 ContextID id; 760 ContextKind kind; 761 ContextContext762 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. 771 struct ObjCSelectorRef { 772 unsigned NumArgs; 773 llvm::ArrayRef<llvm::StringRef> Identifiers; 774 }; 775 } // namespace api_notes 776 } // namespace clang 777 778 #endif 779