clang  19.0.0git
SemaAPINotes.cpp
Go to the documentation of this file.
1 //===--- SemaAPINotes.cpp - API Notes Handling ----------------------------===//
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 // This file implements the mapping from API notes to declaration attributes.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclObjC.h"
17 #include "clang/Lex/Lexer.h"
19 #include "clang/Sema/SemaObjC.h"
20 
21 using namespace clang;
22 
23 namespace {
24 enum class IsActive_t : bool { Inactive, Active };
25 enum class IsSubstitution_t : bool { Original, Replacement };
26 
27 struct VersionedInfoMetadata {
28  /// An empty version refers to unversioned metadata.
29  VersionTuple Version;
30  unsigned IsActive : 1;
31  unsigned IsReplacement : 1;
32 
33  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
34  IsSubstitution_t Replacement)
35  : Version(Version), IsActive(Active == IsActive_t::Active),
36  IsReplacement(Replacement == IsSubstitution_t::Replacement) {}
37 };
38 } // end anonymous namespace
39 
40 /// Determine whether this is a multi-level pointer type.
42  QualType Pointee = Type->getPointeeType();
43  if (Pointee.isNull())
44  return false;
45 
46  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
47  Pointee->isMemberPointerType();
48 }
49 
50 /// Apply nullability to the given declaration.
52  VersionedInfoMetadata Metadata) {
53  if (!Metadata.IsActive)
54  return;
55 
56  auto GetModified =
57  [&](Decl *D, QualType QT,
58  NullabilityKind Nullability) -> std::optional<QualType> {
59  QualType Original = QT;
61  isa<ParmVarDecl>(D),
62  /*OverrideExisting=*/true);
63  return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
64  : std::nullopt;
65  };
66 
67  if (auto Function = dyn_cast<FunctionDecl>(D)) {
68  if (auto Modified =
69  GetModified(D, Function->getReturnType(), Nullability)) {
70  const FunctionType *FnType = Function->getType()->castAs<FunctionType>();
71  if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(FnType))
72  Function->setType(S.Context.getFunctionType(
73  *Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
74  else
75  Function->setType(
76  S.Context.getFunctionNoProtoType(*Modified, FnType->getExtInfo()));
77  }
78  } else if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
79  if (auto Modified = GetModified(D, Method->getReturnType(), Nullability)) {
80  Method->setReturnType(*Modified);
81 
82  // Make it a context-sensitive keyword if we can.
83  if (!isIndirectPointerType(*Modified))
84  Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
85  Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
86  }
87  } else if (auto Value = dyn_cast<ValueDecl>(D)) {
88  if (auto Modified = GetModified(D, Value->getType(), Nullability)) {
89  Value->setType(*Modified);
90 
91  // Make it a context-sensitive keyword if we can.
92  if (auto Parm = dyn_cast<ParmVarDecl>(D)) {
93  if (Parm->isObjCMethodParameter() && !isIndirectPointerType(*Modified))
94  Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
95  Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
96  }
97  }
98  } else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
99  if (auto Modified = GetModified(D, Property->getType(), Nullability)) {
100  Property->setType(*Modified, Property->getTypeSourceInfo());
101 
102  // Make it a property attribute if we can.
103  if (!isIndirectPointerType(*Modified))
104  Property->setPropertyAttributes(
106  }
107  }
108 }
109 
110 /// Copy a string into ASTContext-allocated memory.
111 static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String) {
112  void *mem = Ctx.Allocate(String.size(), alignof(char *));
113  memcpy(mem, String.data(), String.size());
114  return StringRef(static_cast<char *>(mem), String.size());
115 }
116 
121  /*Spelling*/ 0, /*IsAlignas*/ false,
122  /*IsRegularKeywordAttribute*/ false});
123 }
124 
125 namespace {
126 template <typename A> struct AttrKindFor {};
127 
128 #define ATTR(X) \
129  template <> struct AttrKindFor<X##Attr> { \
130  static const attr::Kind value = attr::X; \
131  };
132 #include "clang/Basic/AttrList.inc"
133 
134 /// Handle an attribute introduced by API notes.
135 ///
136 /// \param IsAddition Whether we should add a new attribute
137 /// (otherwise, we might remove an existing attribute).
138 /// \param CreateAttr Create the new attribute to be added.
139 template <typename A>
140 void handleAPINotedAttribute(
141  Sema &S, Decl *D, bool IsAddition, VersionedInfoMetadata Metadata,
142  llvm::function_ref<A *()> CreateAttr,
143  llvm::function_ref<Decl::attr_iterator(const Decl *)> GetExistingAttr) {
144  if (Metadata.IsActive) {
145  auto Existing = GetExistingAttr(D);
146  if (Existing != D->attr_end()) {
147  // Remove the existing attribute, and treat it as a superseded
148  // non-versioned attribute.
149  auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
150  S.Context, Metadata.Version, *Existing, /*IsReplacedByActive*/ true);
151 
152  D->getAttrs().erase(Existing);
153  D->addAttr(Versioned);
154  }
155 
156  // If we're supposed to add a new attribute, do so.
157  if (IsAddition) {
158  if (auto Attr = CreateAttr())
159  D->addAttr(Attr);
160  }
161 
162  return;
163  }
164  if (IsAddition) {
165  if (auto Attr = CreateAttr()) {
166  auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
167  S.Context, Metadata.Version, Attr,
168  /*IsReplacedByActive*/ Metadata.IsReplacement);
169  D->addAttr(Versioned);
170  }
171  } else {
172  // FIXME: This isn't preserving enough information for things like
173  // availability, where we're trying to remove a /specific/ kind of
174  // attribute.
175  auto *Versioned = SwiftVersionedRemovalAttr::CreateImplicit(
176  S.Context, Metadata.Version, AttrKindFor<A>::value,
177  /*IsReplacedByActive*/ Metadata.IsReplacement);
178  D->addAttr(Versioned);
179  }
180 }
181 
182 template <typename A>
183 void handleAPINotedAttribute(Sema &S, Decl *D, bool ShouldAddAttribute,
184  VersionedInfoMetadata Metadata,
185  llvm::function_ref<A *()> CreateAttr) {
186  handleAPINotedAttribute<A>(
187  S, D, ShouldAddAttribute, Metadata, CreateAttr, [](const Decl *D) {
188  return llvm::find_if(D->attrs(),
189  [](const Attr *Next) { return isa<A>(Next); });
190  });
191 }
192 } // namespace
193 
194 template <typename A>
196  bool ShouldAddAttribute,
197  VersionedInfoMetadata Metadata) {
198  // The template argument has a default to make the "removal" case more
199  // concise; it doesn't matter /which/ attribute is being removed.
200  handleAPINotedAttribute<A>(
201  S, D, ShouldAddAttribute, Metadata,
202  [&] { return new (S.Context) A(S.Context, getPlaceholderAttrInfo()); },
203  [](const Decl *D) -> Decl::attr_iterator {
204  return llvm::find_if(D->attrs(), [](const Attr *Next) -> bool {
205  return isa<CFReturnsRetainedAttr>(Next) ||
206  isa<CFReturnsNotRetainedAttr>(Next) ||
207  isa<NSReturnsRetainedAttr>(Next) ||
208  isa<NSReturnsNotRetainedAttr>(Next) ||
209  isa<CFAuditedTransferAttr>(Next);
210  });
211  });
212 }
213 
215  Sema &S, Decl *D, VersionedInfoMetadata Metadata,
216  std::optional<api_notes::RetainCountConventionKind> Convention) {
217  if (!Convention)
218  return;
219  switch (*Convention) {
221  if (isa<FunctionDecl>(D)) {
222  handleAPINotedRetainCountAttribute<CFUnknownTransferAttr>(
223  S, D, /*shouldAddAttribute*/ true, Metadata);
224  } else {
225  handleAPINotedRetainCountAttribute<CFReturnsRetainedAttr>(
226  S, D, /*shouldAddAttribute*/ false, Metadata);
227  }
228  break;
230  handleAPINotedRetainCountAttribute<CFReturnsRetainedAttr>(
231  S, D, /*shouldAddAttribute*/ true, Metadata);
232  break;
234  handleAPINotedRetainCountAttribute<CFReturnsNotRetainedAttr>(
235  S, D, /*shouldAddAttribute*/ true, Metadata);
236  break;
238  handleAPINotedRetainCountAttribute<NSReturnsRetainedAttr>(
239  S, D, /*shouldAddAttribute*/ true, Metadata);
240  break;
242  handleAPINotedRetainCountAttribute<NSReturnsNotRetainedAttr>(
243  S, D, /*shouldAddAttribute*/ true, Metadata);
244  break;
245  }
246 }
247 
248 static void ProcessAPINotes(Sema &S, Decl *D,
249  const api_notes::CommonEntityInfo &Info,
250  VersionedInfoMetadata Metadata) {
251  // Availability
252  if (Info.Unavailable) {
253  handleAPINotedAttribute<UnavailableAttr>(S, D, true, Metadata, [&] {
254  return new (S.Context)
255  UnavailableAttr(S.Context, getPlaceholderAttrInfo(),
257  });
258  }
259 
260  if (Info.UnavailableInSwift) {
261  handleAPINotedAttribute<AvailabilityAttr>(
262  S, D, true, Metadata,
263  [&] {
264  return new (S.Context) AvailabilityAttr(
266  &S.Context.Idents.get("swift"), VersionTuple(), VersionTuple(),
267  VersionTuple(),
268  /*Unavailable=*/true,
270  /*Strict=*/false,
271  /*Replacement=*/StringRef(),
272  /*Priority=*/Sema::AP_Explicit,
273  /*Environment=*/nullptr);
274  },
275  [](const Decl *D) {
276  return llvm::find_if(D->attrs(), [](const Attr *next) -> bool {
277  if (const auto *AA = dyn_cast<AvailabilityAttr>(next))
278  if (const auto *II = AA->getPlatform())
279  return II->isStr("swift");
280  return false;
281  });
282  });
283  }
284 
285  // swift_private
286  if (auto SwiftPrivate = Info.isSwiftPrivate()) {
287  handleAPINotedAttribute<SwiftPrivateAttr>(
288  S, D, *SwiftPrivate, Metadata, [&] {
289  return new (S.Context)
290  SwiftPrivateAttr(S.Context, getPlaceholderAttrInfo());
291  });
292  }
293 
294  // swift_name
295  if (!Info.SwiftName.empty()) {
296  handleAPINotedAttribute<SwiftNameAttr>(
297  S, D, true, Metadata, [&]() -> SwiftNameAttr * {
298  AttributeFactory AF{};
299  AttributePool AP{AF};
300  auto &C = S.getASTContext();
301  ParsedAttr *SNA =
302  AP.create(&C.Idents.get("swift_name"), SourceRange(), nullptr,
303  SourceLocation(), nullptr, nullptr, nullptr,
305 
306  if (!S.DiagnoseSwiftName(D, Info.SwiftName, D->getLocation(), *SNA,
307  /*IsAsync=*/false))
308  return nullptr;
309 
310  return new (S.Context)
311  SwiftNameAttr(S.Context, getPlaceholderAttrInfo(),
313  });
314  }
315 }
316 
317 static void ProcessAPINotes(Sema &S, Decl *D,
318  const api_notes::CommonTypeInfo &Info,
319  VersionedInfoMetadata Metadata) {
320  // swift_bridge
321  if (auto SwiftBridge = Info.getSwiftBridge()) {
322  handleAPINotedAttribute<SwiftBridgeAttr>(
323  S, D, !SwiftBridge->empty(), Metadata, [&] {
324  return new (S.Context)
325  SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),
326  ASTAllocateString(S.Context, *SwiftBridge));
327  });
328  }
329 
330  // ns_error_domain
331  if (auto NSErrorDomain = Info.getNSErrorDomain()) {
332  handleAPINotedAttribute<NSErrorDomainAttr>(
333  S, D, !NSErrorDomain->empty(), Metadata, [&] {
334  return new (S.Context)
335  NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),
336  &S.Context.Idents.get(*NSErrorDomain));
337  });
338  }
339 
340  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
341  Metadata);
342 }
343 
344 /// Check that the replacement type provided by API notes is reasonable.
345 ///
346 /// This is a very weak form of ABI check.
348  QualType OrigType,
349  QualType ReplacementType) {
350  if (S.Context.getTypeSize(OrigType) !=
351  S.Context.getTypeSize(ReplacementType)) {
352  S.Diag(Loc, diag::err_incompatible_replacement_type)
353  << ReplacementType << OrigType;
354  return true;
355  }
356 
357  return false;
358 }
359 
360 /// Process API notes for a variable or property.
361 static void ProcessAPINotes(Sema &S, Decl *D,
362  const api_notes::VariableInfo &Info,
363  VersionedInfoMetadata Metadata) {
364  // Type override.
365  if (Metadata.IsActive && !Info.getType().empty() &&
368  Info.getType(), "<API Notes>", D->getLocation());
369  if (ParsedType.isUsable()) {
371  auto TypeInfo =
373 
374  if (auto Var = dyn_cast<VarDecl>(D)) {
375  // Make adjustments to parameter types.
376  if (isa<ParmVarDecl>(Var)) {
378  Type, D->getLocation(), TypeInfo);
380  }
381 
382  if (!checkAPINotesReplacementType(S, Var->getLocation(), Var->getType(),
383  Type)) {
384  Var->setType(Type);
385  Var->setTypeSourceInfo(TypeInfo);
386  }
387  } else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
388  if (!checkAPINotesReplacementType(S, Property->getLocation(),
389  Property->getType(), Type))
390  Property->setType(Type, TypeInfo);
391 
392  } else
393  llvm_unreachable("API notes allowed a type on an unknown declaration");
394  }
395  }
396 
397  // Nullability.
398  if (auto Nullability = Info.getNullability())
399  applyNullability(S, D, *Nullability, Metadata);
400 
401  // Handle common entity information.
402  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
403  Metadata);
404 }
405 
406 /// Process API notes for a parameter.
407 static void ProcessAPINotes(Sema &S, ParmVarDecl *D,
408  const api_notes::ParamInfo &Info,
409  VersionedInfoMetadata Metadata) {
410  // noescape
411  if (auto NoEscape = Info.isNoEscape())
412  handleAPINotedAttribute<NoEscapeAttr>(S, D, *NoEscape, Metadata, [&] {
413  return new (S.Context) NoEscapeAttr(S.Context, getPlaceholderAttrInfo());
414  });
415 
416  // Retain count convention
418  Info.getRetainCountConvention());
419 
420  // Handle common entity information.
421  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info),
422  Metadata);
423 }
424 
425 /// Process API notes for a global variable.
426 static void ProcessAPINotes(Sema &S, VarDecl *D,
427  const api_notes::GlobalVariableInfo &Info,
428  VersionedInfoMetadata metadata) {
429  // Handle common entity information.
430  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info),
431  metadata);
432 }
433 
434 /// Process API notes for an Objective-C property.
436  const api_notes::ObjCPropertyInfo &Info,
437  VersionedInfoMetadata Metadata) {
438  // Handle common entity information.
439  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info),
440  Metadata);
441 
442  if (auto AsAccessors = Info.getSwiftImportAsAccessors()) {
443  handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(
444  S, D, *AsAccessors, Metadata, [&] {
445  return new (S.Context) SwiftImportPropertyAsAccessorsAttr(
447  });
448  }
449 }
450 
451 namespace {
452 typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
453 }
454 
455 /// Process API notes for a function or method.
456 static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
457  const api_notes::FunctionInfo &Info,
458  VersionedInfoMetadata Metadata) {
459  // Find the declaration itself.
460  FunctionDecl *FD = AnyFunc.dyn_cast<FunctionDecl *>();
461  Decl *D = FD;
462  ObjCMethodDecl *MD = nullptr;
463  if (!D) {
464  MD = AnyFunc.get<ObjCMethodDecl *>();
465  D = MD;
466  }
467 
468  assert((FD || MD) && "Expecting Function or ObjCMethod");
469 
470  // Nullability of return type.
471  if (Info.NullabilityAudited)
472  applyNullability(S, D, Info.getReturnTypeInfo(), Metadata);
473 
474  // Parameters.
475  unsigned NumParams = FD ? FD->getNumParams() : MD->param_size();
476 
477  bool AnyTypeChanged = false;
478  for (unsigned I = 0; I != NumParams; ++I) {
479  ParmVarDecl *Param = FD ? FD->getParamDecl(I) : MD->param_begin()[I];
480  QualType ParamTypeBefore = Param->getType();
481 
482  if (I < Info.Params.size())
483  ProcessAPINotes(S, Param, Info.Params[I], Metadata);
484 
485  // Nullability.
486  if (Info.NullabilityAudited)
487  applyNullability(S, Param, Info.getParamTypeInfo(I), Metadata);
488 
489  if (ParamTypeBefore.getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
490  AnyTypeChanged = true;
491  }
492 
493  // Result type override.
494  QualType OverriddenResultType;
495  if (Metadata.IsActive && !Info.ResultType.empty() &&
498  Info.ResultType, "<API Notes>", D->getLocation());
499  if (ParsedType.isUsable()) {
501 
502  if (MD) {
503  if (!checkAPINotesReplacementType(S, D->getLocation(),
504  MD->getReturnType(), ResultType)) {
505  auto ResultTypeInfo =
506  S.Context.getTrivialTypeSourceInfo(ResultType, D->getLocation());
507  MD->setReturnType(ResultType);
508  MD->setReturnTypeSourceInfo(ResultTypeInfo);
509  }
510  } else if (!checkAPINotesReplacementType(
511  S, FD->getLocation(), FD->getReturnType(), ResultType)) {
512  OverriddenResultType = ResultType;
513  AnyTypeChanged = true;
514  }
515  }
516  }
517 
518  // If the result type or any of the parameter types changed for a function
519  // declaration, we have to rebuild the type.
520  if (FD && AnyTypeChanged) {
521  if (const auto *fnProtoType = FD->getType()->getAs<FunctionProtoType>()) {
522  if (OverriddenResultType.isNull())
523  OverriddenResultType = fnProtoType->getReturnType();
524 
525  SmallVector<QualType, 4> ParamTypes;
526  for (auto Param : FD->parameters())
527  ParamTypes.push_back(Param->getType());
528 
529  FD->setType(S.Context.getFunctionType(OverriddenResultType, ParamTypes,
530  fnProtoType->getExtProtoInfo()));
531  } else if (!OverriddenResultType.isNull()) {
532  const auto *FnNoProtoType = FD->getType()->castAs<FunctionNoProtoType>();
534  OverriddenResultType, FnNoProtoType->getExtInfo()));
535  }
536  }
537 
538  // Retain count convention
540  Info.getRetainCountConvention());
541 
542  // Handle common entity information.
543  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
544  Metadata);
545 }
546 
547 /// Process API notes for a global function.
548 static void ProcessAPINotes(Sema &S, FunctionDecl *D,
549  const api_notes::GlobalFunctionInfo &Info,
550  VersionedInfoMetadata Metadata) {
551  // Handle common function information.
552  ProcessAPINotes(S, FunctionOrMethod(D),
553  static_cast<const api_notes::FunctionInfo &>(Info), Metadata);
554 }
555 
556 /// Process API notes for an enumerator.
558  const api_notes::EnumConstantInfo &Info,
559  VersionedInfoMetadata Metadata) {
560  // Handle common information.
561  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
562  Metadata);
563 }
564 
565 /// Process API notes for an Objective-C method.
567  const api_notes::ObjCMethodInfo &Info,
568  VersionedInfoMetadata Metadata) {
569  // Designated initializers.
570  if (Info.DesignatedInit) {
571  handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(
572  S, D, true, Metadata, [&] {
573  if (ObjCInterfaceDecl *IFace = D->getClassInterface())
574  IFace->setHasDesignatedInitializers();
575 
576  return new (S.Context) ObjCDesignatedInitializerAttr(
578  });
579  }
580 
581  // Handle common function information.
582  ProcessAPINotes(S, FunctionOrMethod(D),
583  static_cast<const api_notes::FunctionInfo &>(Info), Metadata);
584 }
585 
586 /// Process API notes for a tag.
587 static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
588  VersionedInfoMetadata Metadata) {
589  if (auto ImportAs = Info.SwiftImportAs)
590  D->addAttr(SwiftAttrAttr::Create(S.Context, "import_" + ImportAs.value()));
591 
592  if (auto RetainOp = Info.SwiftRetainOp)
593  D->addAttr(SwiftAttrAttr::Create(S.Context, "retain:" + RetainOp.value()));
594 
595  if (auto ReleaseOp = Info.SwiftReleaseOp)
596  D->addAttr(
597  SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value()));
598 
599  if (auto Copyable = Info.isSwiftCopyable()) {
600  if (!*Copyable)
601  D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));
602  }
603 
604  if (auto Extensibility = Info.EnumExtensibility) {
606  bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
607  handleAPINotedAttribute<EnumExtensibilityAttr>(
608  S, D, ShouldAddAttribute, Metadata, [&] {
610  switch (*Extensibility) {
612  llvm_unreachable("remove only");
613  case EnumExtensibilityKind::Open:
614  kind = EnumExtensibilityAttr::Open;
615  break;
616  case EnumExtensibilityKind::Closed:
617  kind = EnumExtensibilityAttr::Closed;
618  break;
619  }
620  return new (S.Context)
621  EnumExtensibilityAttr(S.Context, getPlaceholderAttrInfo(), kind);
622  });
623  }
624 
625  if (auto FlagEnum = Info.isFlagEnum()) {
626  handleAPINotedAttribute<FlagEnumAttr>(S, D, *FlagEnum, Metadata, [&] {
627  return new (S.Context) FlagEnumAttr(S.Context, getPlaceholderAttrInfo());
628  });
629  }
630 
631  // Handle common type information.
632  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
633  Metadata);
634 }
635 
636 /// Process API notes for a typedef.
638  const api_notes::TypedefInfo &Info,
639  VersionedInfoMetadata Metadata) {
640  // swift_wrapper
641  using SwiftWrapperKind = api_notes::SwiftNewTypeKind;
642 
643  if (auto SwiftWrapper = Info.SwiftWrapper) {
644  handleAPINotedAttribute<SwiftNewTypeAttr>(
645  S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {
646  SwiftNewTypeAttr::NewtypeKind Kind;
647  switch (*SwiftWrapper) {
649  llvm_unreachable("Shouldn't build an attribute");
650 
651  case SwiftWrapperKind::Struct:
652  Kind = SwiftNewTypeAttr::NK_Struct;
653  break;
654 
655  case SwiftWrapperKind::Enum:
656  Kind = SwiftNewTypeAttr::NK_Enum;
657  break;
658  }
659  AttributeCommonInfo SyntaxInfo{
660  SourceRange(),
661  AttributeCommonInfo::AT_SwiftNewType,
662  {AttributeCommonInfo::AS_GNU, SwiftNewTypeAttr::GNU_swift_wrapper,
663  /*IsAlignas*/ false, /*IsRegularKeywordAttribute*/ false}};
664  return new (S.Context) SwiftNewTypeAttr(S.Context, SyntaxInfo, Kind);
665  });
666  }
667 
668  // Handle common type information.
669  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
670  Metadata);
671 }
672 
673 /// Process API notes for an Objective-C class or protocol.
675  const api_notes::ObjCContextInfo &Info,
676  VersionedInfoMetadata Metadata) {
677  // Handle common type information.
678  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
679  Metadata);
680 }
681 
682 /// Process API notes for an Objective-C class.
684  const api_notes::ObjCContextInfo &Info,
685  VersionedInfoMetadata Metadata) {
686  if (auto AsNonGeneric = Info.getSwiftImportAsNonGeneric()) {
687  handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(
688  S, D, *AsNonGeneric, Metadata, [&] {
689  return new (S.Context)
690  SwiftImportAsNonGenericAttr(S.Context, getPlaceholderAttrInfo());
691  });
692  }
693 
694  if (auto ObjcMembers = Info.getSwiftObjCMembers()) {
695  handleAPINotedAttribute<SwiftObjCMembersAttr>(
696  S, D, *ObjcMembers, Metadata, [&] {
697  return new (S.Context)
698  SwiftObjCMembersAttr(S.Context, getPlaceholderAttrInfo());
699  });
700  }
701 
702  // Handle information common to Objective-C classes and protocols.
703  ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), Info,
704  Metadata);
705 }
706 
707 /// If we're applying API notes with an active, non-default version, and the
708 /// versioned API notes have a SwiftName but the declaration normally wouldn't
709 /// have one, add a removal attribute to make it clear that the new SwiftName
710 /// attribute only applies to the active version of \p D, not to all versions.
711 ///
712 /// This must be run \em before processing API notes for \p D, because otherwise
713 /// any existing SwiftName attribute will have been packaged up in a
714 /// SwiftVersionedAdditionAttr.
715 template <typename SpecificInfo>
717  Sema &S, Decl *D,
719  if (D->hasAttr<SwiftNameAttr>())
720  return;
721  if (!Info.getSelected())
722  return;
723 
724  // Is the active slice versioned, and does it set a Swift name?
725  VersionTuple SelectedVersion;
726  SpecificInfo SelectedInfoSlice;
727  std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.getSelected()];
728  if (SelectedVersion.empty())
729  return;
730  if (SelectedInfoSlice.SwiftName.empty())
731  return;
732 
733  // Does the unversioned slice /not/ set a Swift name?
734  for (const auto &VersionAndInfoSlice : Info) {
735  if (!VersionAndInfoSlice.first.empty())
736  continue;
737  if (!VersionAndInfoSlice.second.SwiftName.empty())
738  return;
739  }
740 
741  // Then explicitly call that out with a removal attribute.
742  VersionedInfoMetadata DummyFutureMetadata(
743  SelectedVersion, IsActive_t::Inactive, IsSubstitution_t::Replacement);
744  handleAPINotedAttribute<SwiftNameAttr>(
745  S, D, /*add*/ false, DummyFutureMetadata, []() -> SwiftNameAttr * {
746  llvm_unreachable("should not try to add an attribute here");
747  });
748 }
749 
750 /// Processes all versions of versioned API notes.
751 ///
752 /// Just dispatches to the various ProcessAPINotes functions in this file.
753 template <typename SpecificDecl, typename SpecificInfo>
755  Sema &S, SpecificDecl *D,
757 
759 
760  unsigned Selected = Info.getSelected().value_or(Info.size());
761 
762  VersionTuple Version;
763  SpecificInfo InfoSlice;
764  for (unsigned i = 0, e = Info.size(); i != e; ++i) {
765  std::tie(Version, InfoSlice) = Info[i];
766  auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;
767  auto Replacement = IsSubstitution_t::Original;
768  if (Active == IsActive_t::Inactive && Version.empty()) {
769  Replacement = IsSubstitution_t::Replacement;
770  Version = Info[Selected].first;
771  }
772  ProcessAPINotes(S, D, InfoSlice,
773  VersionedInfoMetadata(Version, Active, Replacement));
774  }
775 }
776 
777 /// Process API notes that are associated with this declaration, mapping them
778 /// to attributes as appropriate.
780  if (!D)
781  return;
782 
783  // Globals.
784  if (D->getDeclContext()->isFileContext() ||
785  D->getDeclContext()->isNamespace() ||
788  std::optional<api_notes::Context> APINotesContext;
789  if (auto NamespaceContext = dyn_cast<NamespaceDecl>(D->getDeclContext())) {
790  for (auto Reader :
791  APINotes.findAPINotes(NamespaceContext->getLocation())) {
792  // Retrieve the context ID for the parent namespace of the decl.
793  std::stack<NamespaceDecl *> NamespaceStack;
794  {
795  for (auto CurrentNamespace = NamespaceContext; CurrentNamespace;
796  CurrentNamespace =
797  dyn_cast<NamespaceDecl>(CurrentNamespace->getParent())) {
798  if (!CurrentNamespace->isInlineNamespace())
799  NamespaceStack.push(CurrentNamespace);
800  }
801  }
802  std::optional<api_notes::ContextID> NamespaceID;
803  while (!NamespaceStack.empty()) {
804  auto CurrentNamespace = NamespaceStack.top();
805  NamespaceStack.pop();
806  NamespaceID = Reader->lookupNamespaceID(CurrentNamespace->getName(),
807  NamespaceID);
808  if (!NamespaceID)
809  break;
810  }
811  if (NamespaceID)
812  APINotesContext = api_notes::Context(
813  *NamespaceID, api_notes::ContextKind::Namespace);
814  }
815  }
816 
817  // Global variables.
818  if (auto VD = dyn_cast<VarDecl>(D)) {
819  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
820  auto Info =
821  Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
822  ProcessVersionedAPINotes(*this, VD, Info);
823  }
824 
825  return;
826  }
827 
828  // Global functions.
829  if (auto FD = dyn_cast<FunctionDecl>(D)) {
830  if (FD->getDeclName().isIdentifier()) {
831  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
832  auto Info =
833  Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
834  ProcessVersionedAPINotes(*this, FD, Info);
835  }
836  }
837 
838  return;
839  }
840 
841  // Objective-C classes.
842  if (auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
843  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
844  auto Info = Reader->lookupObjCClassInfo(Class->getName());
845  ProcessVersionedAPINotes(*this, Class, Info);
846  }
847 
848  return;
849  }
850 
851  // Objective-C protocols.
852  if (auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
853  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
854  auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
855  ProcessVersionedAPINotes(*this, Protocol, Info);
856  }
857 
858  return;
859  }
860 
861  // Tags
862  if (auto Tag = dyn_cast<TagDecl>(D)) {
863  std::string LookupName = Tag->getName().str();
864 
865  // Use the source location to discern if this Tag is an OPTIONS macro.
866  // For now we would like to limit this trick of looking up the APINote tag
867  // using the EnumDecl's QualType in the case where the enum is anonymous.
868  // This is only being used to support APINotes lookup for C++
869  // NS/CF_OPTIONS when C++-Interop is enabled.
870  std::string MacroName =
871  LookupName.empty() && Tag->getOuterLocStart().isMacroID()
873  Tag->getOuterLocStart(),
874  Tag->getASTContext().getSourceManager(), LangOpts)
875  .str()
876  : "";
877 
878  if (LookupName.empty() && isa<clang::EnumDecl>(Tag) &&
879  (MacroName == "CF_OPTIONS" || MacroName == "NS_OPTIONS" ||
880  MacroName == "OBJC_OPTIONS" || MacroName == "SWIFT_OPTIONS")) {
881 
882  clang::QualType T = llvm::cast<clang::EnumDecl>(Tag)->getIntegerType();
884  T.split(), getASTContext().getPrintingPolicy());
885  }
886 
887  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
888  auto Info = Reader->lookupTag(LookupName, APINotesContext);
889  ProcessVersionedAPINotes(*this, Tag, Info);
890  }
891 
892  return;
893  }
894 
895  // Typedefs
896  if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
897  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
898  auto Info = Reader->lookupTypedef(Typedef->getName(), APINotesContext);
899  ProcessVersionedAPINotes(*this, Typedef, Info);
900  }
901 
902  return;
903  }
904  }
905 
906  // Enumerators.
909  if (auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
910  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
911  auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
912  ProcessVersionedAPINotes(*this, EnumConstant, Info);
913  }
914 
915  return;
916  }
917  }
918 
919  if (auto ObjCContainer = dyn_cast<ObjCContainerDecl>(D->getDeclContext())) {
920  // Location function that looks up an Objective-C context.
921  auto GetContext = [&](api_notes::APINotesReader *Reader)
922  -> std::optional<api_notes::ContextID> {
923  if (auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
924  if (auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
925  return *Found;
926 
927  return std::nullopt;
928  }
929 
930  if (auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
931  if (auto Cat = Impl->getCategoryDecl())
932  ObjCContainer = Cat->getClassInterface();
933  else
934  return std::nullopt;
935  }
936 
937  if (auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
938  if (Category->getClassInterface())
939  ObjCContainer = Category->getClassInterface();
940  else
941  return std::nullopt;
942  }
943 
944  if (auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
945  if (Impl->getClassInterface())
946  ObjCContainer = Impl->getClassInterface();
947  else
948  return std::nullopt;
949  }
950 
951  if (auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
952  if (auto Found = Reader->lookupObjCClassID(Class->getName()))
953  return *Found;
954 
955  return std::nullopt;
956  }
957 
958  return std::nullopt;
959  };
960 
961  // Objective-C methods.
962  if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
963  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
964  if (auto Context = GetContext(Reader)) {
965  // Map the selector.
966  Selector Sel = Method->getSelector();
967  SmallVector<StringRef, 2> SelPieces;
968  if (Sel.isUnarySelector()) {
969  SelPieces.push_back(Sel.getNameForSlot(0));
970  } else {
971  for (unsigned i = 0, n = Sel.getNumArgs(); i != n; ++i)
972  SelPieces.push_back(Sel.getNameForSlot(i));
973  }
974 
975  api_notes::ObjCSelectorRef SelectorRef;
976  SelectorRef.NumArgs = Sel.getNumArgs();
977  SelectorRef.Identifiers = SelPieces;
978 
979  auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,
980  Method->isInstanceMethod());
981  ProcessVersionedAPINotes(*this, Method, Info);
982  }
983  }
984  }
985 
986  // Objective-C properties.
987  if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
988  for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
989  if (auto Context = GetContext(Reader)) {
990  bool isInstanceProperty =
991  (Property->getPropertyAttributesAsWritten() &
993  auto Info = Reader->lookupObjCProperty(*Context, Property->getName(),
994  isInstanceProperty);
995  ProcessVersionedAPINotes(*this, Property, Info);
996  }
997  }
998 
999  return;
1000  }
1001  }
1002 }
int Category
Definition: Format.cpp:2979
static void ProcessVersionedAPINotes(Sema &S, SpecificDecl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info)
Processes all versions of versioned API notes.
static bool checkAPINotesReplacementType(Sema &S, SourceLocation Loc, QualType OrigType, QualType ReplacementType)
Check that the replacement type provided by API notes is reasonable.
static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability, VersionedInfoMetadata Metadata)
Apply nullability to the given declaration.
static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String)
Copy a string into ASTContext-allocated memory.
static void handleAPINotedRetainCountConvention(Sema &S, Decl *D, VersionedInfoMetadata Metadata, std::optional< api_notes::RetainCountConventionKind > Convention)
static void handleAPINotedRetainCountAttribute(Sema &S, Decl *D, bool ShouldAddAttribute, VersionedInfoMetadata Metadata)
static AttributeCommonInfo getPlaceholderAttrInfo()
static void ProcessAPINotes(Sema &S, Decl *D, const api_notes::CommonEntityInfo &Info, VersionedInfoMetadata Metadata)
static void maybeAttachUnversionedSwiftName(Sema &S, Decl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info)
If we're applying API notes with an active, non-default version, and the versioned API notes have a S...
static bool isIndirectPointerType(QualType Type)
Determine whether this is a multi-level pointer type.
SourceLocation Loc
Definition: SemaObjC.cpp:755
This file declares semantic analysis for Objective-C.
Defines the clang::SourceLocation class and associated facilities.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:721
IdentifierTable & Idents
Definition: ASTContext.h:647
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2355
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1583
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
Attr - This represents one attribute.
Definition: Attr.h:46
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:644
bool isFileContext() const
Definition: DeclBase.h:2137
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1348
bool isNamespace() const
Definition: DeclBase.h:2151
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1938
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1333
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
void addAttr(Attr *A)
Definition: DeclBase.cpp:991
attr_iterator attr_end() const
Definition: DeclBase.h:548
AttrVec::const_iterator attr_iterator
Definition: DeclBase.h:538
AttrVec & getAttrs()
Definition: DeclBase.h:530
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
Definition: DeclBase.h:198
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
Definition: DeclBase.h:210
SourceLocation getLocation() const
Definition: DeclBase.h:445
attr_range attrs() const
Definition: DeclBase.h:541
bool hasAttr() const
Definition: DeclBase.h:583
DeclContext * getDeclContext()
Definition: DeclBase.h:454
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3300
Represents a function declaration or definition.
Definition: Decl.h:1972
QualType getReturnType() const
Definition: Decl.h:2757
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2686
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3696
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2709
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4623
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4668
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4268
ExtInfo getExtInfo() const
Definition: Type.h:4597
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
Definition: Lexer.cpp:1060
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
unsigned param_size() const
Definition: DeclObjC.h:347
void setReturnTypeSourceInfo(TypeSourceInfo *TInfo)
Definition: DeclObjC.h:344
param_const_iterator param_begin() const
Definition: DeclObjC.h:354
void setReturnType(QualType T)
Definition: DeclObjC.h:330
QualType getReturnType() const
Definition: DeclObjC.h:329
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1211
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
PtrTy get() const
Definition: Ownership.h:80
Represents a parameter to a function.
Definition: Decl.h:1762
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:129
A (possibly-)qualified type.
Definition: Type.h:940
void * getAsOpaquePtr() const
Definition: Type.h:987
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
std::string getAsString() const
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isUnarySelector() const
unsigned getNumArgs() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:57
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:462
SemaObjC & ObjC()
Definition: Sema.h:1012
ASTContext & Context
Definition: Sema.h:857
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:774
api_notes::APINotesManager APINotes
Definition: Sema.h:861
const LangOptions & LangOpts
Definition: Sema.h:855
std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback
Callback to the parser to parse a type expressed as a string.
Definition: Sema.h:915
bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc, const ParsedAttr &AL, bool IsAsync)
Do a check to make sure Name looks like a legal argument for the swift_name attribute applied to decl...
ASTContext & getASTContext() const
Definition: Sema.h:526
bool CheckImplicitNullabilityTypeSpecifier(QualType &Type, NullabilityKind Nullability, SourceLocation DiagLoc, bool AllowArrayTypes, bool OverrideExisting)
Check whether a nullability type specifier can be added to the given type through some means not writ...
Definition: SemaType.cpp:7391
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
Definition: Sema.h:3542
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2820
Encodes a location in the source.
A trivial tuple used to represent a source range.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3587
The base class of the type hierarchy.
Definition: Type.h:1813
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8227
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isMemberPointerType() const
Definition: Type.h:7672
bool isObjCObjectPointerType() const
Definition: Type.h:7760
bool isAnyPointerType() const
Definition: Type.h:7628
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3435
void setType(QualType newType)
Definition: Decl.h:719
QualType getType() const
Definition: Decl.h:718
QualType getType() const
Definition: Value.cpp:234
Represents a variable declaration or definition.
Definition: Decl.h:919
llvm::SmallVector< APINotesReader *, 2 > findAPINotes(SourceLocation Loc)
Find the API notes readers that correspond to the given source location.
Captures the completed versioned information for a particular part of API notes, including both unver...
unsigned size() const
Return the number of versioned results we know about.
std::optional< unsigned > getSelected() const
Retrieve the selected index in the result set.
A class that reads API notes data from a binary file that was written by the APINotesWriter.
Describes API notes data for any entity.
Definition: Types.h:52
unsigned UnavailableInSwift
Whether this entity is marked unavailable in Swift.
Definition: Types.h:63
unsigned Unavailable
Whether this entity is marked unavailable.
Definition: Types.h:59
std::string SwiftName
Swift name of this entity.
Definition: Types.h:76
std::optional< bool > isSwiftPrivate() const
Definition: Types.h:82
std::string UnavailableMsg
Message to use when this entity is unavailable.
Definition: Types.h:55
Describes API notes for types.
Definition: Types.h:135
const std::optional< std::string > & getNSErrorDomain() const
Definition: Types.h:155
const std::optional< std::string > & getSwiftBridge() const
Definition: Types.h:147
Describes API notes data for an enumerator.
Definition: Types.h:666
API notes for a function or method.
Definition: Types.h:495
std::optional< RetainCountConventionKind > getRetainCountConvention() const
Definition: Types.h:572
std::vector< ParamInfo > Params
The function parameters.
Definition: Types.h:528
NullabilityKind getReturnTypeInfo() const
Definition: Types.h:570
NullabilityKind getParamTypeInfo(unsigned index) const
Definition: Types.h:566
std::string ResultType
The result type of this function, as a C type.
Definition: Types.h:525
unsigned NullabilityAudited
Whether the signature has been audited with respect to nullability.
Definition: Types.h:509
Describes API notes data for a global function.
Definition: Types.h:660
Describes API notes data for a global variable.
Definition: Types.h:654
Describes API notes data for an Objective-C class or protocol.
Definition: Types.h:196
std::optional< bool > getSwiftObjCMembers() const
Definition: Types.h:256
std::optional< bool > getSwiftImportAsNonGeneric() const
Definition: Types.h:246
Describes API notes data for an Objective-C method.
Definition: Types.h:615
unsigned DesignatedInit
Whether this is a designated initializer of its class.
Definition: Types.h:619
Describes API notes data for an Objective-C property.
Definition: Types.h:367
std::optional< bool > getSwiftImportAsAccessors() const
Definition: Types.h:377
Describes a function or method parameter.
Definition: Types.h:425
std::optional< RetainCountConventionKind > getRetainCountConvention() const
Definition: Types.h:453
std::optional< bool > isNoEscape() const
Definition: Types.h:443
Describes API notes data for a tag.
Definition: Types.h:672
std::optional< std::string > SwiftReleaseOp
Definition: Types.h:686
std::optional< std::string > SwiftRetainOp
Definition: Types.h:685
std::optional< std::string > SwiftImportAs
Definition: Types.h:684
std::optional< bool > isFlagEnum() const
Definition: Types.h:694
std::optional< EnumExtensibilityKind > EnumExtensibility
Definition: Types.h:688
std::optional< bool > isSwiftCopyable() const
Definition: Types.h:704
Describes API notes data for a typedef.
Definition: Types.h:755
std::optional< SwiftNewTypeKind > SwiftWrapper
Definition: Types.h:757
API notes for a variable/property.
Definition: Types.h:310
const std::string & getType() const
Definition: Types.h:337
std::optional< NullabilityKind > getNullability() const
Definition: Types.h:326
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
SwiftNewTypeKind
The kind of a swift_wrapper/swift_newtype.
Definition: Types.h:43
EnumExtensibilityKind
The payload for an enum_extensibility attribute.
Definition: Types.h:36
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:65
The JSON file list parser is used to communicate input to InstallAPI.
NullabilityKind
Describes the nullability of a particular type.
Definition: Specifiers.h:333
@ Property
The type of a property.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
#define bool
Definition: stdbool.h:24
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
Definition: Types.h:813
llvm::ArrayRef< llvm::StringRef > Identifiers
Definition: Types.h:815