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