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