clang: lib/Sema/SemaAPINotes.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

24#include

25

26using namespace clang;

27

28namespace {

29enum class IsActive_t : bool { Inactive, Active };

30enum class IsSubstitution_t : bool { Original, Replacement };

31

32struct VersionedInfoMetadata {

33

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}

44

45

49 return false;

50

53}

54

55

57 VersionedInfoMetadata Metadata) {

58 if (!Metadata.IsActive)

59 return;

60

61 auto GetModified =

66 isa(D),

67 true);

68 return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)

69 : std::nullopt;

70 };

71

72 if (auto Function = dyn_cast(D)) {

73 if (auto Modified =

74 GetModified(D, Function->getReturnType(), Nullability)) {

76 if (const FunctionProtoType *proto = dyn_cast(FnType))

78 *Modified, proto->getParamTypes(), proto->getExtProtoInfo()));

79 else

82 }

83 } else if (auto Method = dyn_cast(D)) {

84 if (auto Modified = GetModified(D, Method->getReturnType(), Nullability)) {

85 Method->setReturnType(*Modified);

86

87

91 }

92 } else if (auto Value = dyn_cast(D)) {

93 if (auto Modified = GetModified(D, Value->getType(), Nullability)) {

94 Value->setType(*Modified);

95

96

97 if (auto Parm = dyn_cast(D)) {

101 }

102 }

103 } else if (auto Property = dyn_cast(D)) {

104 if (auto Modified = GetModified(D, Property->getType(), Nullability)) {

106

107

109 Property->setPropertyAttributes(

111 }

112 }

113}

114

115

117 void *mem = Ctx.Allocate(String.size(), alignof(char *));

118 memcpy(mem, String.data(), String.size());

119 return StringRef(static_cast<char *>(mem), String.size());

120}

121

126 0, false,

127 false});

128}

129

130namespace {

131template struct AttrKindFor {};

132

133#define ATTR(X) \

134 template <> struct AttrKindFor<X##Attr> { \

135 static const attr::Kind value = attr::X; \

136 };

137#include "clang/Basic/AttrList.inc"

138

139

140

141

142

143

144template

145void handleAPINotedAttribute(

146 Sema &S, Decl *D, bool IsAddition, VersionedInfoMetadata Metadata,

147 llvm::function_ref<A *()> CreateAttr,

149 if (Metadata.IsActive) {

150 auto Existing = GetExistingAttr(D);

152

153

154 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(

155 S.Context, Metadata.Version, *Existing, true);

156

159 }

160

161

162 if (IsAddition) {

163 if (auto Attr = CreateAttr())

165 }

166

167 return;

168 }

169 if (IsAddition) {

170 if (auto Attr = CreateAttr()) {

171 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(

173 Metadata.IsReplacement);

175 }

176 } else {

177

178

179

180 auto *Versioned = SwiftVersionedRemovalAttr::CreateImplicit(

181 S.Context, Metadata.Version, AttrKindFor::value,

182 Metadata.IsReplacement);

184 }

185}

186

187template

188void handleAPINotedAttribute(Sema &S, Decl *D, bool ShouldAddAttribute,

189 VersionedInfoMetadata Metadata,

190 llvm::function_ref<A *()> CreateAttr) {

191 handleAPINotedAttribute(

192 S, D, ShouldAddAttribute, Metadata, CreateAttr, [](const Decl *D) {

193 return llvm::find_if(D->attrs(),

194 [](const Attr *Next) { return isa(Next); });

195 });

196}

197}

198

199template

201 bool ShouldAddAttribute,

202 VersionedInfoMetadata Metadata) {

203

204

205 handleAPINotedAttribute(

206 S, D, ShouldAddAttribute, Metadata,

209 return llvm::find_if(D->attrs(), [](const Attr *Next) -> bool {

210 return isa(Next) ||

211 isa(Next) ||

212 isa(Next) ||

213 isa(Next) ||

214 isa(Next);

215 });

216 });

217}

218

220 Sema &S, Decl *D, VersionedInfoMetadata Metadata,

221 std::optional<api_notes::RetainCountConventionKind> Convention) {

222 if (!Convention)

223 return;

224 switch (*Convention) {

225 case api_notes::RetainCountConventionKind::None:

226 if (isa(D)) {

227 handleAPINotedRetainCountAttribute(

228 S, D, true, Metadata);

229 } else {

230 handleAPINotedRetainCountAttribute(

231 S, D, false, Metadata);

232 }

233 break;

234 case api_notes::RetainCountConventionKind::CFReturnsRetained:

235 handleAPINotedRetainCountAttribute(

236 S, D, true, Metadata);

237 break;

238 case api_notes::RetainCountConventionKind::CFReturnsNotRetained:

239 handleAPINotedRetainCountAttribute(

240 S, D, true, Metadata);

241 break;

242 case api_notes::RetainCountConventionKind::NSReturnsRetained:

243 handleAPINotedRetainCountAttribute(

244 S, D, true, Metadata);

245 break;

246 case api_notes::RetainCountConventionKind::NSReturnsNotRetained:

247 handleAPINotedRetainCountAttribute(

248 S, D, true, Metadata);

249 break;

250 }

251}

252

255 VersionedInfoMetadata Metadata) {

256

258 handleAPINotedAttribute(S, D, true, Metadata, [&] {

262 });

263 }

264

266 handleAPINotedAttribute(

267 S, D, true, Metadata,

268 [&] {

269 return new (S.Context) AvailabilityAttr(

271 &S.Context.Idents.get("swift"), VersionTuple(), VersionTuple(),

272 VersionTuple(),

273 true,

275 false,

276 StringRef(),

278 nullptr);

279 },

280 [](const Decl *D) {

281 return llvm::find_if(D->attrs(), [](const Attr *next) -> bool {

282 if (const auto *AA = dyn_cast(next))

283 if (const auto *II = AA->getPlatform())

284 return II->isStr("swift");

285 return false;

286 });

287 });

288 }

289

290

292 handleAPINotedAttribute(

293 S, D, *SwiftPrivate, Metadata, [&] {

296 });

297 }

298

299

301 handleAPINotedAttribute(

302 S, D, true, Metadata, [&]() -> SwiftNameAttr * {

307 AP.create(&C.Idents.get("swift_name"), SourceRange(), nullptr,

309 ParsedAttr::Form::GNU());

310

312 false))

313 return nullptr;

314

318 });

319 }

320}

321

324 VersionedInfoMetadata Metadata) {

325

327 handleAPINotedAttribute(

328 S, D, !SwiftBridge->empty(), Metadata, [&] {

329 return new (S.Context)

330 SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),

331 ASTAllocateString(S.Context, *SwiftBridge));

332 });

333 }

334

335

337 handleAPINotedAttribute(

338 S, D, !NSErrorDomain->empty(), Metadata, [&] {

339 return new (S.Context)

340 NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),

341 &S.Context.Idents.get(*NSErrorDomain));

342 });

343 }

344

346 Metadata);

347}

348

349

350

351

357 S.Diag(Loc, diag::err_incompatible_replacement_type)

358 << ReplacementType << OrigType;

359 return true;

360 }

361

362 return false;

363}

364

365

368 VersionedInfoMetadata Metadata) {

369

370 if (Metadata.IsActive && !Info.getType().empty() &&

378

379 if (auto Var = dyn_cast(D)) {

380

381 if (isa(Var)) {

385 }

386

389 Var->setType(Type);

390 Var->setTypeSourceInfo(TypeInfo);

391 }

392 } else if (auto Property = dyn_cast(D)) {

396

397 } else

398 llvm_unreachable("API notes allowed a type on an unknown declaration");

399 }

400 }

401

402

405

406

408 Metadata);

409}

410

411

414 VersionedInfoMetadata Metadata) {

415

416 if (auto NoEscape = Info.isNoEscape())

417 handleAPINotedAttribute(S, D, *NoEscape, Metadata, [&] {

419 });

420

422 handleAPINotedAttribute(

423 S, D, *Lifetimebound, Metadata, [&] {

426 });

427

428

431

432

434 Metadata);

435}

436

437

440 VersionedInfoMetadata metadata) {

441

443 metadata);

444}

445

446

449 VersionedInfoMetadata metadata) {

450

452 metadata);

453}

454

455

458 VersionedInfoMetadata Metadata) {

459

461 Metadata);

462

464 handleAPINotedAttribute(

465 S, D, *AsAccessors, Metadata, [&] {

466 return new (S.Context) SwiftImportPropertyAsAccessorsAttr(

468 });

469 }

470}

471

472namespace {

473typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;

474}

475

476

479 VersionedInfoMetadata Metadata) {

480

484 if (D) {

485 MD = cast<ObjCMethodDecl *>(AnyFunc);

486 D = MD;

487 }

488

489 assert((FD || MD) && "Expecting Function or ObjCMethod");

490

491

494

495

497

498 bool AnyTypeChanged = false;

499 for (unsigned I = 0; I != NumParams; ++I) {

502

503 if (I < Info.Params.size())

505

506

509

511 AnyTypeChanged = true;

512 }

513

514

518

519

520 QualType OverriddenResultType;

521 if (Metadata.IsActive && !Info.ResultType.empty() &&

527

528 if (MD) {

531 auto ResultTypeInfo =

535 }

538 OverriddenResultType = ResultType;

539 AnyTypeChanged = true;

540 }

541 }

542 }

543

544

545

546 if (FD && AnyTypeChanged) {

548 if (OverriddenResultType.isNull())

549 OverriddenResultType = fnProtoType->getReturnType();

550

553 ParamTypes.push_back(Param->getType());

554

556 fnProtoType->getExtProtoInfo()));

557 } else if (!OverriddenResultType.isNull()) {

560 OverriddenResultType, FnNoProtoType->getExtInfo()));

561 }

562 }

563

564

567

568

570 Metadata);

571}

572

573

576 VersionedInfoMetadata Metadata) {

577 if (Info.This && Info.This->isLifetimebound() &&

579 auto MethodType = Method->getType();

590 }

591

592 ProcessAPINotes(S, (FunctionOrMethod)Method, Info, Metadata);

593}

594

595

598 VersionedInfoMetadata Metadata) {

599

602}

603

604

607 VersionedInfoMetadata Metadata) {

608

610 Metadata);

611}

612

613

616 VersionedInfoMetadata Metadata) {

617

619 handleAPINotedAttribute(

620 S, D, true, Metadata, [&] {

622 IFace->setHasDesignatedInitializers();

623

624 return new (S.Context) ObjCDesignatedInitializerAttr(

626 });

627 }

628

629

632}

633

634

636 VersionedInfoMetadata Metadata) {

638 D->addAttr(SwiftAttrAttr::Create(S.Context, "import_" + ImportAs.value()));

639

641 D->addAttr(SwiftAttrAttr::Create(S.Context, "retain:" + RetainOp.value()));

642

645 SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value()));

646

649 SwiftAttrAttr::Create(S.Context, "conforms_to:" + ConformsTo.value()));

650

652 if (!*Copyable)

653 D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));

654 }

655

658 *Escapable ? "Escapable" : "~Escapable"));

659 }

660

663 bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);

664 handleAPINotedAttribute(

665 S, D, ShouldAddAttribute, Metadata, [&] {

666 EnumExtensibilityAttr::Kind kind;

667 switch (*Extensibility) {

668 case EnumExtensibilityKind::None:

669 llvm_unreachable("remove only");

670 case EnumExtensibilityKind::Open:

671 kind = EnumExtensibilityAttr::Open;

672 break;

673 case EnumExtensibilityKind::Closed:

674 kind = EnumExtensibilityAttr::Closed;

675 break;

676 }

679 });

680 }

681

682 if (auto FlagEnum = Info.isFlagEnum()) {

683 handleAPINotedAttribute(S, D, *FlagEnum, Metadata, [&] {

685 });

686 }

687

688

690 Metadata);

691}

692

693

696 VersionedInfoMetadata Metadata) {

697

699

701 handleAPINotedAttribute(

702 S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {

703 SwiftNewTypeAttr::NewtypeKind Kind;

704 switch (*SwiftWrapper) {

705 case SwiftWrapperKind::None:

706 llvm_unreachable("Shouldn't build an attribute");

707

708 case SwiftWrapperKind::Struct:

709 Kind = SwiftNewTypeAttr::NK_Struct;

710 break;

711

712 case SwiftWrapperKind::Enum:

713 Kind = SwiftNewTypeAttr::NK_Enum;

714 break;

715 }

718 AttributeCommonInfo::AT_SwiftNewType,

720 false, false}};

721 return new (S.Context) SwiftNewTypeAttr(S.Context, SyntaxInfo, Kind);

722 });

723 }

724

725

727 Metadata);

728}

729

730

733 VersionedInfoMetadata Metadata) {

734

736 Metadata);

737}

738

739

742 VersionedInfoMetadata Metadata) {

744 handleAPINotedAttribute(

745 S, D, *AsNonGeneric, Metadata, [&] {

748 });

749 }

750

752 handleAPINotedAttribute(

753 S, D, *ObjcMembers, Metadata, [&] {

756 });

757 }

758

759

761 Metadata);

762}

763

764

765

766

767

768

769

770

771

772template

776 if (D->hasAttr())

777 return;

779 return;

780

781

782 VersionTuple SelectedVersion;

783 SpecificInfo SelectedInfoSlice;

784 std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.getSelected()];

785 if (SelectedVersion.empty())

786 return;

787 if (SelectedInfoSlice.SwiftName.empty())

788 return;

789

790

791 for (const auto &VersionAndInfoSlice : Info) {

792 if (!VersionAndInfoSlice.first.empty())

793 continue;

794 if (!VersionAndInfoSlice.second.SwiftName.empty())

795 return;

796 }

797

798

799 VersionedInfoMetadata DummyFutureMetadata(

800 SelectedVersion, IsActive_t::Inactive, IsSubstitution_t::Replacement);

801 handleAPINotedAttribute(

802 S, D, false, DummyFutureMetadata, []() -> SwiftNameAttr * {

803 llvm_unreachable("should not try to add an attribute here");

804 });

805}

806

807

808

809

810template <typename SpecificDecl, typename SpecificInfo>

812 Sema &S, SpecificDecl *D,

814

816

817 unsigned Selected = Info.getSelected().value_or(Info.size());

818

819 VersionTuple Version;

820 SpecificInfo InfoSlice;

821 for (unsigned i = 0, e = Info.size(); i != e; ++i) {

822 std::tie(Version, InfoSlice) = Info[i];

823 auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;

824 auto Replacement = IsSubstitution_t::Original;

825 if (Active == IsActive_t::Inactive && Version.empty()) {

826 Replacement = IsSubstitution_t::Replacement;

827 Version = Info[Selected].first;

828 }

830 VersionedInfoMetadata(Version, Active, Replacement));

831 }

832}

833

834static std::optional<api_notes::Context>

836 if (auto NamespaceContext = dyn_cast(DC)) {

837 for (auto Reader : APINotes.findAPINotes(NamespaceContext->getLocation())) {

838

839 std::stack<NamespaceDecl *> NamespaceStack;

840 {

841 for (auto CurrentNamespace = NamespaceContext; CurrentNamespace;

842 CurrentNamespace =

843 dyn_cast(CurrentNamespace->getParent())) {

844 if (!CurrentNamespace->isInlineNamespace())

845 NamespaceStack.push(CurrentNamespace);

846 }

847 }

848 std::optional<api_notes::ContextID> NamespaceID;

849 while (!NamespaceStack.empty()) {

850 auto CurrentNamespace = NamespaceStack.top();

851 NamespaceStack.pop();

852 NamespaceID =

853 Reader->lookupNamespaceID(CurrentNamespace->getName(), NamespaceID);

854 if (!NamespaceID)

855 return std::nullopt;

856 }

857 if (NamespaceID)

859 api_notes::ContextKind::Namespace);

860 }

861 }

862 return std::nullopt;

863}

864

865static std::optional<api_notes::Context>

867 assert(DC && "tag context must not be null");

869

870 std::stack<TagDecl *> TagStack;

871 {

872 for (auto CurrentTag = DC; CurrentTag;

873 CurrentTag = dyn_cast(CurrentTag->getParent()))

874 TagStack.push(CurrentTag);

875 }

876 assert(!TagStack.empty());

877 std::optional<api_notes::Context> Ctx =

879 while (!TagStack.empty()) {

880 auto CurrentTag = TagStack.top();

881 TagStack.pop();

882 auto CtxID = Reader->lookupTagID(CurrentTag->getName(), Ctx);

883 if (!CtxID)

884 return std::nullopt;

886 }

887 return Ctx;

888 }

889 return std::nullopt;

890}

891

892

893

895 if (D)

896 return;

897

899

900 if (DC->isFileContext() || DC->isNamespace() || DC->isExternCContext() ||

901 DC->isExternCXXContext()) {

902 std::optional<api_notes::Context> APINotesContext =

904

905 if (auto VD = dyn_cast(D)) {

907 auto Info =

908 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);

910 }

911

912 return;

913 }

914

915

916 if (auto FD = dyn_cast(D)) {

917 if (FD->getDeclName().isIdentifier()) {

919 auto Info =

920 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);

922 }

923 }

924

925 return;

926 }

927

928

929 if (auto Class = dyn_cast(D)) {

931 auto Info = Reader->lookupObjCClassInfo(Class->getName());

933 }

934

935 return;

936 }

937

938

939 if (auto Protocol = dyn_cast(D)) {

941 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());

943 }

944

945 return;

946 }

947

948

949 if (auto Tag = dyn_cast(D)) {

950

951

952

953

955 if (auto typedefName = Tag->getTypedefNameForAnonDecl())

956 LookupName = typedefName->getName().str();

957 else

959

960

961

962

963

964

965 std::string MacroName =

966 LookupName.empty() && Tag->getOuterLocStart().isMacroID()

968 Tag->getOuterLocStart(),

969 Tag->getASTContext().getSourceManager(), LangOpts)

970 .str()

971 : "";

972

973 if (LookupName.empty() && isaclang::EnumDecl(Tag) &&

974 (MacroName == "CF_OPTIONS" || MacroName == "NS_OPTIONS" ||

975 MacroName == "OBJC_OPTIONS" || MacroName == "SWIFT_OPTIONS")) {

976

977 clang::QualType T = llvm::castclang::EnumDecl(Tag)->getIntegerType();

980 }

981

983 if (auto ParentTag = dyn_cast(Tag->getDeclContext()))

985 auto Info = Reader->lookupTag(LookupName, APINotesContext);

987 }

988

989 return;

990 }

991

992

993 if (auto Typedef = dyn_cast(D)) {

995 auto Info = Reader->lookupTypedef(Typedef->getName(), APINotesContext);

997 }

998

999 return;

1000 }

1001 }

1002

1003

1004 if (DC->getRedeclContext()->isFileContext() ||

1005 DC->getRedeclContext()->isExternCContext()) {

1006 if (auto EnumConstant = dyn_cast(D)) {

1008 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());

1010 }

1011

1012 return;

1013 }

1014 }

1015

1016 if (auto ObjCContainer = dyn_cast(DC)) {

1017

1019 -> std::optional<api_notes::ContextID> {

1020 if (auto Protocol = dyn_cast(ObjCContainer)) {

1021 if (auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))

1023

1024 return std::nullopt;

1025 }

1026

1027 if (auto Impl = dyn_cast(ObjCContainer)) {

1028 if (auto Cat = Impl->getCategoryDecl())

1029 ObjCContainer = Cat->getClassInterface();

1030 else

1031 return std::nullopt;

1032 }

1033

1034 if (auto Category = dyn_cast(ObjCContainer)) {

1035 if (Category->getClassInterface())

1036 ObjCContainer = Category->getClassInterface();

1037 else

1038 return std::nullopt;

1039 }

1040

1041 if (auto Impl = dyn_cast(ObjCContainer)) {

1042 if (Impl->getClassInterface())

1043 ObjCContainer = Impl->getClassInterface();

1044 else

1045 return std::nullopt;

1046 }

1047

1048 if (auto Class = dyn_cast(ObjCContainer)) {

1049 if (auto Found = Reader->lookupObjCClassID(Class->getName()))

1051

1052 return std::nullopt;

1053 }

1054

1055 return std::nullopt;

1056 };

1057

1058

1059 if (auto Method = dyn_cast(D)) {

1061 if (auto Context = GetContext(Reader)) {

1062

1063 Selector Sel = Method->getSelector();

1067 } else {

1068 for (unsigned i = 0, n = Sel.getNumArgs(); i != n; ++i)

1070 }

1071

1075

1076 auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,

1077 Method->isInstanceMethod());

1079 }

1080 }

1081 }

1082

1083

1084 if (auto Property = dyn_cast(D)) {

1086 if (auto Context = GetContext(Reader)) {

1087 bool isInstanceProperty =

1088 (Property->getPropertyAttributesAsWritten() &

1090 auto Info = Reader->lookupObjCProperty(*Context, Property->getName(),

1091 isInstanceProperty);

1093 }

1094 }

1095

1096 return;

1097 }

1098 }

1099

1100 if (auto TagContext = dyn_cast(DC)) {

1101 if (auto CXXMethod = dyn_cast(D)) {

1102 if (!isa(CXXMethod) &&

1103 !isa(CXXMethod) &&

1104 !isa(CXXMethod) &&

1105 !CXXMethod->isOverloadedOperator()) {

1108 auto Info =

1109 Reader->lookupCXXMethod(Context->id, CXXMethod->getName());

1111 }

1112 }

1113 }

1114 }

1115

1116 if (auto Field = dyn_cast(D)) {

1117 if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {

1120 auto Info = Reader->lookupField(Context->id, Field->getName());

1122 }

1123 }

1124 }

1125 }

1126

1127 if (auto Tag = dyn_cast(D)) {

1130 auto Info = Reader->lookupTag(Tag->getName(), Context);

1132 }

1133 }

1134 }

1135 }

1136}

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

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.

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 ...

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()'.

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.

void * Allocate(size_t Size, unsigned Align=8) const

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

QualType getAdjustedParameterType(QualType T) const

Perform adjustment on the parameter type of a function.

Attr - This represents one attribute.

A factory, from which one makes pools, from which one creates individual attributes which are dealloc...

Type source information for an attributed type.

void setAttr(const Attr *A)

An attributed type is a type to which a type attribute has been applied.

Represents a static or instance method of a struct/union/class.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

Decl - This represents one declaration (or definition), e.g.

attr_iterator attr_end() const

AttrVec::const_iterator attr_iterator

ObjCDeclQualifier

ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...

@ OBJC_TQ_CSNullability

The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...

SourceLocation getLocation() const

DeclContext * getDeclContext()

void setTypeSourceInfo(TypeSourceInfo *TI)

TypeSourceInfo * getTypeSourceInfo() const

An instance of this object exists for each enum constant that is defined.

Represents a member of a struct/union/class.

Represents a function declaration or definition.

const ParmVarDecl * getParamDecl(unsigned i) const

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

unsigned getNumParams() const

Return the number of parameters this function must have based on its FunctionType.

Represents a K&R-style 'int foo()' function, which has no information available about its arguments.

Represents a prototype with parameter type info, e.g.

FunctionType - C99 6.7.5.3 - Function Declarators.

ExtInfo getExtInfo() const

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.

ObjCContainerDecl - Represents a container for method declarations.

Represents an ObjC class declaration.

ObjCMethodDecl - Represents an instance or class method declaration.

unsigned param_size() const

void setReturnTypeSourceInfo(TypeSourceInfo *TInfo)

param_const_iterator param_begin() const

void setReturnType(QualType T)

QualType getReturnType() const

Represents one property declaration in an Objective-C interface.

Represents a parameter to a function.

ParsedAttr - Represents a syntactic attribute.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

std::string getAsString() const

void * getAsOpaquePtr() const

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.

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...

Sema - This implements semantic analysis and AST building for C.

ASTContext & getASTContext() const

PrintingPolicy getPrintingPolicy() const

Retrieve a suitable printing policy for diagnostics.

api_notes::APINotesManager APINotes

const LangOptions & LangOpts

std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback

Callback to the parser to parse a type expressed as a string.

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...

@ AP_Explicit

The availability attribute was specified explicitly next to the 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)

Encodes a location in the source.

A trivial tuple used to represent a source range.

Represents the declaration of a struct/union/class/enum.

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.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

The base class of the type hierarchy.

const T * castAs() const

Member-template castAs.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isMemberPointerType() const

bool isObjCObjectPointerType() const

bool isAnyPointerType() const

const T * getAs() const

Member-template getAs'.

Base class for declarations which introduce a typedef-name.

void setType(QualType newType)

Represents a variable declaration or definition.

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.

std::optional< ParamInfo > This

Describes API notes data for any entity.

unsigned UnavailableInSwift

Whether this entity is marked unavailable in Swift.

unsigned Unavailable

Whether this entity is marked unavailable.

std::string SwiftName

Swift name of this entity.

std::string UnavailableMsg

Message to use when this entity is unavailable.

std::optional< bool > isSwiftPrivate() const

Describes API notes for types.

const std::optional< std::string > & getSwiftBridge() const

const std::optional< std::string > & getNSErrorDomain() const

Describes API notes data for an Objective-C class or protocol or a C++ namespace.

std::optional< bool > getSwiftImportAsNonGeneric() const

std::optional< bool > getSwiftObjCMembers() const

Describes API notes data for an enumerator.

Describes API notes data for a C/C++ record field.

API notes for a function or method.

std::string SwiftReturnOwnership

Ownership convention for return value.

std::optional< RetainCountConventionKind > getRetainCountConvention() const

std::vector< ParamInfo > Params

The function parameters.

NullabilityKind getReturnTypeInfo() const

NullabilityKind getParamTypeInfo(unsigned index) const

std::string ResultType

The result type of this function, as a C type.

unsigned NullabilityAudited

Whether the signature has been audited with respect to nullability.

Describes API notes data for a global function.

Describes API notes data for a global variable.

Describes API notes data for an Objective-C method.

unsigned DesignatedInit

Whether this is a designated initializer of its class.

Describes API notes data for an Objective-C property.

std::optional< bool > getSwiftImportAsAccessors() const

Describes a function or method parameter.

std::optional< bool > isNoEscape() const

std::optional< bool > isLifetimebound() const

std::optional< RetainCountConventionKind > getRetainCountConvention() const

Describes API notes data for a tag.

std::optional< std::string > SwiftReleaseOp

std::optional< std::string > SwiftRetainOp

std::optional< std::string > SwiftImportAs

std::optional< EnumExtensibilityKind > EnumExtensibility

std::optional< bool > isFlagEnum() const

std::optional< bool > isSwiftCopyable() const

std::optional< bool > isSwiftEscapable() const

std::optional< std::string > SwiftConformance

The Swift protocol that this type should be automatically conformed to.

Describes API notes data for a typedef.

std::optional< SwiftNewTypeKind > SwiftWrapper

API notes for a variable/property.

std::optional< NullabilityKind > getNullability() const

const std::string & getType() const

SwiftNewTypeKind

The kind of a swift_wrapper/swift_newtype.

EnumExtensibilityKind

The payload for an enum_extensibility attribute.

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

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.

@ 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...

llvm::ArrayRef< llvm::StringRef > Identifiers