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 Extensibility = Info.EnumExtensibility) {
599 bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
600 handleAPINotedAttribute<EnumExtensibilityAttr>(
601 S, D, ShouldAddAttribute, Metadata, [&] {
602 EnumExtensibilityAttr::Kind kind;
603 switch (*Extensibility) {
604 case EnumExtensibilityKind::None:
605 llvm_unreachable("remove only");
606 case EnumExtensibilityKind::Open:
607 kind = EnumExtensibilityAttr::Open;
608 break;
609 case EnumExtensibilityKind::Closed:
610 kind = EnumExtensibilityAttr::Closed;
611 break;
612 }
613 return new (S.Context)
614 EnumExtensibilityAttr(S.Context, getPlaceholderAttrInfo(), kind);
615 });
616 }
617
618 if (auto FlagEnum = Info.isFlagEnum()) {
619 handleAPINotedAttribute<FlagEnumAttr>(S, D, *FlagEnum, Metadata, [&] {
620 return new (S.Context) FlagEnumAttr(S.Context, getPlaceholderAttrInfo());
621 });
622 }
623
624 // Handle common type information.
625 ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
626 Metadata);
627}
628
629/// Process API notes for a typedef.
631 const api_notes::TypedefInfo &Info,
632 VersionedInfoMetadata Metadata) {
633 // swift_wrapper
634 using SwiftWrapperKind = api_notes::SwiftNewTypeKind;
635
636 if (auto SwiftWrapper = Info.SwiftWrapper) {
637 handleAPINotedAttribute<SwiftNewTypeAttr>(
638 S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {
639 SwiftNewTypeAttr::NewtypeKind Kind;
640 switch (*SwiftWrapper) {
641 case SwiftWrapperKind::None:
642 llvm_unreachable("Shouldn't build an attribute");
643
644 case SwiftWrapperKind::Struct:
645 Kind = SwiftNewTypeAttr::NK_Struct;
646 break;
647
648 case SwiftWrapperKind::Enum:
649 Kind = SwiftNewTypeAttr::NK_Enum;
650 break;
651 }
652 AttributeCommonInfo SyntaxInfo{
653 SourceRange(),
654 AttributeCommonInfo::AT_SwiftNewType,
655 {AttributeCommonInfo::AS_GNU, SwiftNewTypeAttr::GNU_swift_wrapper,
656 /*IsAlignas*/ false, /*IsRegularKeywordAttribute*/ false}};
657 return new (S.Context) SwiftNewTypeAttr(S.Context, SyntaxInfo, Kind);
658 });
659 }
660
661 // Handle common type information.
662 ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
663 Metadata);
664}
665
666/// Process API notes for an Objective-C class or protocol.
668 const api_notes::ObjCContextInfo &Info,
669 VersionedInfoMetadata Metadata) {
670 // Handle common type information.
671 ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info),
672 Metadata);
673}
674
675/// Process API notes for an Objective-C class.
677 const api_notes::ObjCContextInfo &Info,
678 VersionedInfoMetadata Metadata) {
679 if (auto AsNonGeneric = Info.getSwiftImportAsNonGeneric()) {
680 handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(
681 S, D, *AsNonGeneric, Metadata, [&] {
682 return new (S.Context)
683 SwiftImportAsNonGenericAttr(S.Context, getPlaceholderAttrInfo());
684 });
685 }
686
687 if (auto ObjcMembers = Info.getSwiftObjCMembers()) {
688 handleAPINotedAttribute<SwiftObjCMembersAttr>(
689 S, D, *ObjcMembers, Metadata, [&] {
690 return new (S.Context)
691 SwiftObjCMembersAttr(S.Context, getPlaceholderAttrInfo());
692 });
693 }
694
695 // Handle information common to Objective-C classes and protocols.
696 ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), Info,
697 Metadata);
698}
699
700/// If we're applying API notes with an active, non-default version, and the
701/// versioned API notes have a SwiftName but the declaration normally wouldn't
702/// have one, add a removal attribute to make it clear that the new SwiftName
703/// attribute only applies to the active version of \p D, not to all versions.
704///
705/// This must be run \em before processing API notes for \p D, because otherwise
706/// any existing SwiftName attribute will have been packaged up in a
707/// SwiftVersionedAdditionAttr.
708template <typename SpecificInfo>
710 Sema &S, Decl *D,
712 if (D->hasAttr<SwiftNameAttr>())
713 return;
714 if (!Info.getSelected())
715 return;
716
717 // Is the active slice versioned, and does it set a Swift name?
718 VersionTuple SelectedVersion;
719 SpecificInfo SelectedInfoSlice;
720 std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.getSelected()];
721 if (SelectedVersion.empty())
722 return;
723 if (SelectedInfoSlice.SwiftName.empty())
724 return;
725
726 // Does the unversioned slice /not/ set a Swift name?
727 for (const auto &VersionAndInfoSlice : Info) {
728 if (!VersionAndInfoSlice.first.empty())
729 continue;
730 if (!VersionAndInfoSlice.second.SwiftName.empty())
731 return;
732 }
733
734 // Then explicitly call that out with a removal attribute.
735 VersionedInfoMetadata DummyFutureMetadata(
736 SelectedVersion, IsActive_t::Inactive, IsSubstitution_t::Replacement);
737 handleAPINotedAttribute<SwiftNameAttr>(
738 S, D, /*add*/ false, DummyFutureMetadata, []() -> SwiftNameAttr * {
739 llvm_unreachable("should not try to add an attribute here");
740 });
741}
742
743/// Processes all versions of versioned API notes.
744///
745/// Just dispatches to the various ProcessAPINotes functions in this file.
746template <typename SpecificDecl, typename SpecificInfo>
748 Sema &S, SpecificDecl *D,
750
752
753 unsigned Selected = Info.getSelected().value_or(Info.size());
754
755 VersionTuple Version;
756 SpecificInfo InfoSlice;
757 for (unsigned i = 0, e = Info.size(); i != e; ++i) {
758 std::tie(Version, InfoSlice) = Info[i];
759 auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;
760 auto Replacement = IsSubstitution_t::Original;
761 if (Active == IsActive_t::Inactive && Version.empty()) {
762 Replacement = IsSubstitution_t::Replacement;
763 Version = Info[Selected].first;
764 }
765 ProcessAPINotes(S, D, InfoSlice,
766 VersionedInfoMetadata(Version, Active, Replacement));
767 }
768}
769
770/// Process API notes that are associated with this declaration, mapping them
771/// to attributes as appropriate.
773 if (!D)
774 return;
775
776 // Globals.
777 if (D->getDeclContext()->isFileContext() ||
778 D->getDeclContext()->isNamespace() ||
781 std::optional<api_notes::Context> APINotesContext;
782 if (auto NamespaceContext = dyn_cast<NamespaceDecl>(D->getDeclContext())) {
783 for (auto Reader :
784 APINotes.findAPINotes(NamespaceContext->getLocation())) {
785 // Retrieve the context ID for the parent namespace of the decl.
786 std::stack<NamespaceDecl *> NamespaceStack;
787 {
788 for (auto CurrentNamespace = NamespaceContext; CurrentNamespace;
789 CurrentNamespace =
790 dyn_cast<NamespaceDecl>(CurrentNamespace->getParent())) {
791 if (!CurrentNamespace->isInlineNamespace())
792 NamespaceStack.push(CurrentNamespace);
793 }
794 }
795 std::optional<api_notes::ContextID> NamespaceID;
796 while (!NamespaceStack.empty()) {
797 auto CurrentNamespace = NamespaceStack.top();
798 NamespaceStack.pop();
799 NamespaceID = Reader->lookupNamespaceID(CurrentNamespace->getName(),
800 NamespaceID);
801 if (!NamespaceID)
802 break;
803 }
804 if (NamespaceID)
805 APINotesContext = api_notes::Context(
807 }
808 }
809
810 // Global variables.
811 if (auto VD = dyn_cast<VarDecl>(D)) {
812 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
813 auto Info =
814 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
815 ProcessVersionedAPINotes(*this, VD, Info);
816 }
817
818 return;
819 }
820
821 // Global functions.
822 if (auto FD = dyn_cast<FunctionDecl>(D)) {
823 if (FD->getDeclName().isIdentifier()) {
824 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
825 auto Info =
826 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
827 ProcessVersionedAPINotes(*this, FD, Info);
828 }
829 }
830
831 return;
832 }
833
834 // Objective-C classes.
835 if (auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
836 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
837 auto Info = Reader->lookupObjCClassInfo(Class->getName());
838 ProcessVersionedAPINotes(*this, Class, Info);
839 }
840
841 return;
842 }
843
844 // Objective-C protocols.
845 if (auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
846 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
847 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
848 ProcessVersionedAPINotes(*this, Protocol, Info);
849 }
850
851 return;
852 }
853
854 // Tags
855 if (auto Tag = dyn_cast<TagDecl>(D)) {
856 std::string LookupName = Tag->getName().str();
857
858 // Use the source location to discern if this Tag is an OPTIONS macro.
859 // For now we would like to limit this trick of looking up the APINote tag
860 // using the EnumDecl's QualType in the case where the enum is anonymous.
861 // This is only being used to support APINotes lookup for C++
862 // NS/CF_OPTIONS when C++-Interop is enabled.
863 std::string MacroName =
864 LookupName.empty() && Tag->getOuterLocStart().isMacroID()
866 Tag->getOuterLocStart(),
867 Tag->getASTContext().getSourceManager(), LangOpts)
868 .str()
869 : "";
870
871 if (LookupName.empty() && isa<clang::EnumDecl>(Tag) &&
872 (MacroName == "CF_OPTIONS" || MacroName == "NS_OPTIONS" ||
873 MacroName == "OBJC_OPTIONS" || MacroName == "SWIFT_OPTIONS")) {
874
875 clang::QualType T = llvm::cast<clang::EnumDecl>(Tag)->getIntegerType();
877 T.split(), getASTContext().getPrintingPolicy());
878 }
879
880 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
881 auto Info = Reader->lookupTag(LookupName, APINotesContext);
882 ProcessVersionedAPINotes(*this, Tag, Info);
883 }
884
885 return;
886 }
887
888 // Typedefs
889 if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
890 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
891 auto Info = Reader->lookupTypedef(Typedef->getName(), APINotesContext);
892 ProcessVersionedAPINotes(*this, Typedef, Info);
893 }
894
895 return;
896 }
897 }
898
899 // Enumerators.
902 if (auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
903 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
904 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
905 ProcessVersionedAPINotes(*this, EnumConstant, Info);
906 }
907
908 return;
909 }
910 }
911
912 if (auto ObjCContainer = dyn_cast<ObjCContainerDecl>(D->getDeclContext())) {
913 // Location function that looks up an Objective-C context.
914 auto GetContext = [&](api_notes::APINotesReader *Reader)
915 -> std::optional<api_notes::ContextID> {
916 if (auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
917 if (auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
918 return *Found;
919
920 return std::nullopt;
921 }
922
923 if (auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
924 if (auto Cat = Impl->getCategoryDecl())
925 ObjCContainer = Cat->getClassInterface();
926 else
927 return std::nullopt;
928 }
929
930 if (auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
931 if (Category->getClassInterface())
932 ObjCContainer = Category->getClassInterface();
933 else
934 return std::nullopt;
935 }
936
937 if (auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
938 if (Impl->getClassInterface())
939 ObjCContainer = Impl->getClassInterface();
940 else
941 return std::nullopt;
942 }
943
944 if (auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
945 if (auto Found = Reader->lookupObjCClassID(Class->getName()))
946 return *Found;
947
948 return std::nullopt;
949 }
950
951 return std::nullopt;
952 };
953
954 // Objective-C methods.
955 if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
956 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
957 if (auto Context = GetContext(Reader)) {
958 // Map the selector.
959 Selector Sel = Method->getSelector();
961 if (Sel.isUnarySelector()) {
962 SelPieces.push_back(Sel.getNameForSlot(0));
963 } else {
964 for (unsigned i = 0, n = Sel.getNumArgs(); i != n; ++i)
965 SelPieces.push_back(Sel.getNameForSlot(i));
966 }
967
968 api_notes::ObjCSelectorRef SelectorRef;
969 SelectorRef.NumArgs = Sel.getNumArgs();
970 SelectorRef.Identifiers = SelPieces;
971
972 auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,
973 Method->isInstanceMethod());
974 ProcessVersionedAPINotes(*this, Method, Info);
975 }
976 }
977 }
978
979 // Objective-C properties.
980 if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
981 for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
982 if (auto Context = GetContext(Reader)) {
983 bool isInstanceProperty =
984 (Property->getPropertyAttributesAsWritten() &
986 auto Info = Reader->lookupObjCProperty(*Context, Property->getName(),
987 isInstanceProperty);
989 }
990 }
991
992 return;
993 }
994 }
995}
int Category
Definition: Format.cpp:2975
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:2329
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:1567
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:2138
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:2152
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:85
void addAttr(Attr *A)
Definition: DeclBase.cpp:975
attr_iterator attr_end() const
Definition: DeclBase.h:549
AttrVec::const_iterator attr_iterator
Definition: DeclBase.h:539
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
Definition: DeclBase.h:197
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
Definition: DeclBase.h:209
SourceLocation getLocation() const
Definition: DeclBase.h:446
DeclContext * getDeclContext()
Definition: DeclBase.h:455
attr_range attrs() const
Definition: DeclBase.h:542
AttrVec & getAttrs()
Definition: DeclBase.h:531
bool hasAttr() const
Definition: DeclBase.h:584
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:4401
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4446
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4046
ExtInfo getExtInfo() const
Definition: Type.h:4375
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:946
Represents an ObjC class declaration.
Definition: DeclObjC.h:1152
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:1210
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
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:738
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:805
std::string getAsString() const
void * getAsOpaquePtr() const
Definition: Type.h:785
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:3556
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)
Definition: SemaDecl.cpp:15318
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:1607
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7980
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:7450
bool isObjCObjectPointerType() const
Definition: Type.h:7534
bool isAnyPointerType() const
Definition: Type.h:7406
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7913
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:681
std::optional< std::string > SwiftRetainOp
Definition: Types.h:680
std::optional< std::string > SwiftImportAs
Definition: Types.h:679
std::optional< EnumExtensibilityKind > EnumExtensibility
Definition: Types.h:683
std::optional< bool > isFlagEnum() const
Definition: Types.h:687
Describes API notes data for a typedef.
Definition: Types.h:735
std::optional< SwiftNewTypeKind > SwiftWrapper
Definition: Types.h:737
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:793
llvm::ArrayRef< llvm::StringRef > Identifiers
Definition: Types.h:795