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