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