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 CommonEntityInfo()78 CommonEntityInfo() 79 : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0), 80 SwiftPrivate(0) {} 81 isSwiftPrivate()82 std::optional<bool> isSwiftPrivate() const { 83 return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate) 84 : std::nullopt; 85 } 86 setSwiftPrivate(std::optional<bool> Private)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: CommonTypeInfo()145 CommonTypeInfo() {} 146 getSwiftBridge()147 const std::optional<std::string> &getSwiftBridge() const { 148 return SwiftBridge; 149 } 150 setSwiftBridge(std::optional<std::string> SwiftType)151 void setSwiftBridge(std::optional<std::string> SwiftType) { 152 SwiftBridge = SwiftType; 153 } 154 getNSErrorDomain()155 const std::optional<std::string> &getNSErrorDomain() const { 156 return NSErrorDomain; 157 } 158 setNSErrorDomain(const std::optional<std::string> & Domain)159 void setNSErrorDomain(const std::optional<std::string> &Domain) { 160 NSErrorDomain = Domain; 161 } 162 setNSErrorDomain(const std::optional<llvm::StringRef> & Domain)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: ContextInfo()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. getDefaultNullability()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. setDefaultNullability(NullabilityKind Kind)239 void setDefaultNullability(NullabilityKind Kind) { 240 HasDefaultNullability = true; 241 DefaultNullability = static_cast<unsigned>(Kind); 242 } 243 hasDesignatedInits()244 bool hasDesignatedInits() const { return HasDesignatedInits; } setHasDesignatedInits(bool Value)245 void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; } 246 getSwiftImportAsNonGeneric()247 std::optional<bool> getSwiftImportAsNonGeneric() const { 248 return SwiftImportAsNonGenericSpecified 249 ? std::optional<bool>(SwiftImportAsNonGeneric) 250 : std::nullopt; 251 } setSwiftImportAsNonGeneric(std::optional<bool> Value)252 void setSwiftImportAsNonGeneric(std::optional<bool> Value) { 253 SwiftImportAsNonGenericSpecified = Value.has_value(); 254 SwiftImportAsNonGeneric = Value.value_or(false); 255 } 256 getSwiftObjCMembers()257 std::optional<bool> getSwiftObjCMembers() const { 258 return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers) 259 : std::nullopt; 260 } setSwiftObjCMembers(std::optional<bool> Value)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: VariableInfo()318 VariableInfo() : NullabilityAudited(false), Nullable(0) {} 319 getNullability()320 std::optional<NullabilityKind> getNullability() const { 321 return NullabilityAudited ? std::optional<NullabilityKind>( 322 static_cast<NullabilityKind>(Nullable)) 323 : std::nullopt; 324 } 325 setNullabilityAudited(NullabilityKind kind)326 void setNullabilityAudited(NullabilityKind kind) { 327 NullabilityAudited = true; 328 Nullable = static_cast<unsigned>(kind); 329 } 330 getType()331 const std::string &getType() const { return Type; } setType(const std::string & 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: ObjCPropertyInfo()368 ObjCPropertyInfo() 369 : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {} 370 getSwiftImportAsAccessors()371 std::optional<bool> getSwiftImportAsAccessors() const { 372 return SwiftImportAsAccessorsSpecified 373 ? std::optional<bool>(SwiftImportAsAccessors) 374 : std::nullopt; 375 } setSwiftImportAsAccessors(std::optional<bool> Value)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 /// A biased RetainCountConventionKind, where 0 means "unspecified". 429 /// 430 /// Only relevant for out-parameters. 431 unsigned RawRetainCountConvention : 3; 432 433 public: ParamInfo()434 ParamInfo() 435 : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {} 436 isNoEscape()437 std::optional<bool> isNoEscape() const { 438 if (!NoEscapeSpecified) 439 return std::nullopt; 440 return NoEscape; 441 } setNoEscape(std::optional<bool> Value)442 void setNoEscape(std::optional<bool> Value) { 443 NoEscapeSpecified = Value.has_value(); 444 NoEscape = Value.value_or(false); 445 } 446 getRetainCountConvention()447 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 448 if (!RawRetainCountConvention) 449 return std::nullopt; 450 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 451 } 452 void setRetainCountConvention(std::optional<RetainCountConventionKind> Value)453 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) { 454 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0; 455 assert(getRetainCountConvention() == Value && "bitfield too small"); 456 } 457 458 ParamInfo &operator|=(const ParamInfo &RHS) { 459 static_cast<VariableInfo &>(*this) |= RHS; 460 461 if (!NoEscapeSpecified && RHS.NoEscapeSpecified) { 462 NoEscapeSpecified = true; 463 NoEscape = RHS.NoEscape; 464 } 465 466 if (!RawRetainCountConvention) 467 RawRetainCountConvention = RHS.RawRetainCountConvention; 468 469 return *this; 470 } 471 472 friend bool operator==(const ParamInfo &, const ParamInfo &); 473 474 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 475 }; 476 477 inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) { 478 return static_cast<const VariableInfo &>(LHS) == RHS && 479 LHS.NoEscapeSpecified == RHS.NoEscapeSpecified && 480 LHS.NoEscape == RHS.NoEscape && 481 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; 482 } 483 484 inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) { 485 return !(LHS == RHS); 486 } 487 488 /// API notes for a function or method. 489 class FunctionInfo : public CommonEntityInfo { 490 private: 491 static constexpr const uint64_t NullabilityKindMask = 0x3; 492 static constexpr const unsigned NullabilityKindSize = 2; 493 494 static constexpr const unsigned ReturnInfoIndex = 0; 495 496 public: 497 // If yes, we consider all types to be non-nullable unless otherwise noted. 498 // If this flag is not set, the pointer types are considered to have 499 // unknown nullability. 500 501 /// Whether the signature has been audited with respect to nullability. 502 LLVM_PREFERRED_TYPE(bool) 503 unsigned NullabilityAudited : 1; 504 505 /// Number of types whose nullability is encoded with the NullabilityPayload. 506 unsigned NumAdjustedNullable : 8; 507 508 /// A biased RetainCountConventionKind, where 0 means "unspecified". 509 unsigned RawRetainCountConvention : 3; 510 511 // NullabilityKindSize bits are used to encode the nullability. The info 512 // about the return type is stored at position 0, followed by the nullability 513 // of the parameters. 514 515 /// Stores the nullability of the return type and the parameters. 516 uint64_t NullabilityPayload = 0; 517 518 /// The result type of this function, as a C type. 519 std::string ResultType; 520 521 /// The function parameters. 522 std::vector<ParamInfo> Params; 523 FunctionInfo()524 FunctionInfo() 525 : NullabilityAudited(false), NumAdjustedNullable(0), 526 RawRetainCountConvention() {} 527 getMaxNullabilityIndex()528 static unsigned getMaxNullabilityIndex() { 529 return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize); 530 } 531 addTypeInfo(unsigned index,NullabilityKind kind)532 void addTypeInfo(unsigned index, NullabilityKind kind) { 533 assert(index <= getMaxNullabilityIndex()); 534 assert(static_cast<unsigned>(kind) < NullabilityKindMask); 535 536 NullabilityAudited = true; 537 if (NumAdjustedNullable < index + 1) 538 NumAdjustedNullable = index + 1; 539 540 // Mask the bits. 541 NullabilityPayload &= 542 ~(NullabilityKindMask << (index * NullabilityKindSize)); 543 544 // Set the value. 545 unsigned kindValue = (static_cast<unsigned>(kind)) 546 << (index * NullabilityKindSize); 547 NullabilityPayload |= kindValue; 548 } 549 550 /// Adds the return type info. addReturnTypeInfo(NullabilityKind kind)551 void addReturnTypeInfo(NullabilityKind kind) { 552 addTypeInfo(ReturnInfoIndex, kind); 553 } 554 555 /// Adds the parameter type info. addParamTypeInfo(unsigned index,NullabilityKind kind)556 void addParamTypeInfo(unsigned index, NullabilityKind kind) { 557 addTypeInfo(index + 1, kind); 558 } 559 getParamTypeInfo(unsigned index)560 NullabilityKind getParamTypeInfo(unsigned index) const { 561 return getTypeInfo(index + 1); 562 } 563 getReturnTypeInfo()564 NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); } 565 getRetainCountConvention()566 std::optional<RetainCountConventionKind> getRetainCountConvention() const { 567 if (!RawRetainCountConvention) 568 return std::nullopt; 569 return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1); 570 } 571 void setRetainCountConvention(std::optional<RetainCountConventionKind> Value)572 setRetainCountConvention(std::optional<RetainCountConventionKind> Value) { 573 RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0; 574 assert(getRetainCountConvention() == Value && "bitfield too small"); 575 } 576 577 friend bool operator==(const FunctionInfo &, const FunctionInfo &); 578 579 private: getTypeInfo(unsigned index)580 NullabilityKind getTypeInfo(unsigned index) const { 581 assert(NullabilityAudited && 582 "Checking the type adjustment on non-audited method."); 583 584 // If we don't have info about this parameter, return the default. 585 if (index > NumAdjustedNullable) 586 return NullabilityKind::NonNull; 587 auto nullability = NullabilityPayload >> (index * NullabilityKindSize); 588 return static_cast<NullabilityKind>(nullability & NullabilityKindMask); 589 } 590 591 public: 592 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 593 }; 594 595 inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { 596 return static_cast<const CommonEntityInfo &>(LHS) == RHS && 597 LHS.NullabilityAudited == RHS.NullabilityAudited && 598 LHS.NumAdjustedNullable == RHS.NumAdjustedNullable && 599 LHS.NullabilityPayload == RHS.NullabilityPayload && 600 LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params && 601 LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; 602 } 603 604 inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { 605 return !(LHS == RHS); 606 } 607 608 /// Describes API notes data for an Objective-C method. 609 class ObjCMethodInfo : public FunctionInfo { 610 public: 611 /// Whether this is a designated initializer of its class. 612 LLVM_PREFERRED_TYPE(bool) 613 unsigned DesignatedInit : 1; 614 615 /// Whether this is a required initializer. 616 LLVM_PREFERRED_TYPE(bool) 617 unsigned RequiredInit : 1; 618 ObjCMethodInfo()619 ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {} 620 621 friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &); 622 623 ObjCMethodInfo &operator|=(const ContextInfo &RHS) { 624 // Merge Nullability. 625 if (!NullabilityAudited) { 626 if (auto Nullable = RHS.getDefaultNullability()) { 627 NullabilityAudited = true; 628 addTypeInfo(0, *Nullable); 629 } 630 } 631 return *this; 632 } 633 634 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 635 }; 636 637 inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { 638 return static_cast<const FunctionInfo &>(LHS) == RHS && 639 LHS.DesignatedInit == RHS.DesignatedInit && 640 LHS.RequiredInit == RHS.RequiredInit; 641 } 642 643 inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { 644 return !(LHS == RHS); 645 } 646 647 /// Describes API notes data for a global variable. 648 class GlobalVariableInfo : public VariableInfo { 649 public: GlobalVariableInfo()650 GlobalVariableInfo() {} 651 }; 652 653 /// Describes API notes data for a global function. 654 class GlobalFunctionInfo : public FunctionInfo { 655 public: GlobalFunctionInfo()656 GlobalFunctionInfo() {} 657 }; 658 659 /// Describes API notes data for a C++ method. 660 class CXXMethodInfo : public FunctionInfo { 661 public: CXXMethodInfo()662 CXXMethodInfo() {} 663 }; 664 665 /// Describes API notes data for an enumerator. 666 class EnumConstantInfo : public CommonEntityInfo { 667 public: EnumConstantInfo()668 EnumConstantInfo() {} 669 }; 670 671 /// Describes API notes data for a tag. 672 class TagInfo : public CommonTypeInfo { 673 LLVM_PREFERRED_TYPE(bool) 674 unsigned HasFlagEnum : 1; 675 LLVM_PREFERRED_TYPE(bool) 676 unsigned IsFlagEnum : 1; 677 678 LLVM_PREFERRED_TYPE(bool) 679 unsigned SwiftCopyableSpecified : 1; 680 LLVM_PREFERRED_TYPE(bool) 681 unsigned SwiftCopyable : 1; 682 683 public: 684 std::optional<std::string> SwiftImportAs; 685 std::optional<std::string> SwiftRetainOp; 686 std::optional<std::string> SwiftReleaseOp; 687 688 std::optional<EnumExtensibilityKind> EnumExtensibility; 689 TagInfo()690 TagInfo() 691 : HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false), 692 SwiftCopyable(false) {} 693 isFlagEnum()694 std::optional<bool> isFlagEnum() const { 695 if (HasFlagEnum) 696 return IsFlagEnum; 697 return std::nullopt; 698 } setFlagEnum(std::optional<bool> Value)699 void setFlagEnum(std::optional<bool> Value) { 700 HasFlagEnum = Value.has_value(); 701 IsFlagEnum = Value.value_or(false); 702 } 703 isSwiftCopyable()704 std::optional<bool> isSwiftCopyable() const { 705 return SwiftCopyableSpecified ? std::optional<bool>(SwiftCopyable) 706 : std::nullopt; 707 } setSwiftCopyable(std::optional<bool> Value)708 void setSwiftCopyable(std::optional<bool> Value) { 709 SwiftCopyableSpecified = Value.has_value(); 710 SwiftCopyable = Value.value_or(false); 711 } 712 713 TagInfo &operator|=(const TagInfo &RHS) { 714 static_cast<CommonTypeInfo &>(*this) |= RHS; 715 716 if (!SwiftImportAs) 717 SwiftImportAs = RHS.SwiftImportAs; 718 if (!SwiftRetainOp) 719 SwiftRetainOp = RHS.SwiftRetainOp; 720 if (!SwiftReleaseOp) 721 SwiftReleaseOp = RHS.SwiftReleaseOp; 722 723 if (!HasFlagEnum) 724 setFlagEnum(RHS.isFlagEnum()); 725 726 if (!EnumExtensibility) 727 EnumExtensibility = RHS.EnumExtensibility; 728 729 if (!SwiftCopyableSpecified) 730 setSwiftCopyable(RHS.isSwiftCopyable()); 731 732 return *this; 733 } 734 735 friend bool operator==(const TagInfo &, const TagInfo &); 736 737 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); 738 }; 739 740 inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) { 741 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 742 LHS.SwiftImportAs == RHS.SwiftImportAs && 743 LHS.SwiftRetainOp == RHS.SwiftRetainOp && 744 LHS.SwiftReleaseOp == RHS.SwiftReleaseOp && 745 LHS.isFlagEnum() == RHS.isFlagEnum() && 746 LHS.isSwiftCopyable() == RHS.isSwiftCopyable() && 747 LHS.EnumExtensibility == RHS.EnumExtensibility; 748 } 749 750 inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) { 751 return !(LHS == RHS); 752 } 753 754 /// Describes API notes data for a typedef. 755 class TypedefInfo : public CommonTypeInfo { 756 public: 757 std::optional<SwiftNewTypeKind> SwiftWrapper; 758 TypedefInfo()759 TypedefInfo() {} 760 761 TypedefInfo &operator|=(const TypedefInfo &RHS) { 762 static_cast<CommonTypeInfo &>(*this) |= RHS; 763 if (!SwiftWrapper) 764 SwiftWrapper = RHS.SwiftWrapper; 765 return *this; 766 } 767 768 friend bool operator==(const TypedefInfo &, const TypedefInfo &); 769 770 LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const; 771 }; 772 773 inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) { 774 return static_cast<const CommonTypeInfo &>(LHS) == RHS && 775 LHS.SwiftWrapper == RHS.SwiftWrapper; 776 } 777 778 inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) { 779 return !(LHS == RHS); 780 } 781 782 /// The file extension used for the source representation of API notes. 783 static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes"; 784 785 /// Opaque context ID used to refer to an Objective-C class or protocol or a C++ 786 /// namespace. 787 class ContextID { 788 public: 789 unsigned Value; 790 ContextID(unsigned value)791 explicit ContextID(unsigned value) : Value(value) {} 792 }; 793 794 enum class ContextKind : uint8_t { 795 ObjCClass = 0, 796 ObjCProtocol = 1, 797 Namespace = 2, 798 Tag = 3, 799 }; 800 801 struct Context { 802 ContextID id; 803 ContextKind kind; 804 ContextContext805 Context(ContextID id, ContextKind kind) : id(id), kind(kind) {} 806 }; 807 808 /// A temporary reference to an Objective-C selector, suitable for 809 /// referencing selector data on the stack. 810 /// 811 /// Instances of this struct do not store references to any of the 812 /// data they contain; it is up to the user to ensure that the data 813 /// referenced by the identifier list persists. 814 struct ObjCSelectorRef { 815 unsigned NumArgs; 816 llvm::ArrayRef<llvm::StringRef> Identifiers; 817 }; 818 } // namespace api_notes 819 } // namespace clang 820 821 #endif 822