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