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
21using namespace clang;
22
23namespace {
24enum class IsActive_t : bool { Inactive, Active };
25enum class IsSubstitution_t : bool { Original, Replacement };
26
27struct 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.
51static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
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))
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.
111static 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
125namespace {
126template <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.
139template <typename A>
140void 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
182template <typename A>
183void 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
194template <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) {
220 case api_notes::RetainCountConventionKind::None:
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;
229 case api_notes::RetainCountConventionKind::CFReturnsRetained:
230 handleAPINotedRetainCountAttribute<CFReturnsRetainedAttr>(
231 S, D, /*shouldAddAttribute*/ true, Metadata);
232 break;
233 case api_notes::RetainCountConventionKind::CFReturnsNotRetained:
234 handleAPINotedRetainCountAttribute<CFReturnsNotRetainedAttr>(
235 S, D, /*shouldAddAttribute*/ true, Metadata);
236 break;
237 case api_notes::RetainCountConventionKind::NSReturnsRetained:
238 handleAPINotedRetainCountAttribute<NSReturnsRetainedAttr>(
239 S, D, /*shouldAddAttribute*/ true, Metadata);
240 break;
241 case api_notes::RetainCountConventionKind::NSReturnsNotRetained:
242 handleAPINotedRetainCountAttribute<NSReturnsNotRetainedAttr>(
243 S, D, /*shouldAddAttribute*/ true, Metadata);
244 break;
245 }
246}
247
248static 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,
304 ParsedAttr::Form::GNU());
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
317static 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.
361static 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.
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
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.
426static void ProcessAPINotes(Sema &S, VarDecl *D,
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
451namespace {
452typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
453}
454
455/// Process API notes for a function or method.
456static 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 }
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
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.
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.
587static 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, [&] {
609 EnumExtensibilityAttr::Kind kind;
610 switch (*Extensibility) {
611 case EnumExtensibilityKind::None:
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) {
648 case SwiftWrapperKind::None:
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.
715template <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.
753template <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(
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();
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);
996 }
997 }
998
999 return;
1000 }
1001 }
1002}
int Category
Definition: Format.cpp:2978
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: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:2341
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:1569
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:639
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
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:3297
Represents a function declaration or definition.
Definition: Decl.h:1971
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2706
QualType getReturnType() const
Definition: Decl.h:2754
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2683
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:4611
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4656
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4256
ExtInfo getExtInfo() const
Definition: Type.h:4585
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:129
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
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:451
ASTContext & Context
Definition: Sema.h:848
SemaObjC & ObjC()
Definition: Sema.h:1003
ASTContext & getASTContext() const
Definition: Sema.h:517
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:765
api_notes::APINotesManager APINotes
Definition: Sema.h:852
const LangOptions & LangOpts
Definition: Sema.h:846
std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback
Callback to the parser to parse a type expressed as a string.
Definition: Sema.h:906
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:7305
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
Definition: Sema.h:3520
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:2805
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:3584
The base class of the type hierarchy.
Definition: Type.h:1813
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8193
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:695
bool isMemberPointerType() const
Definition: Type.h:7660
bool isObjCObjectPointerType() const
Definition: Type.h:7744
bool isAnyPointerType() const
Definition: Type.h:7616
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8126
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3432
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