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

1

2

3

4

5

6

7

8

9

10

11

12

25#include

26

27using namespace clang;

28

29namespace {

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

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

32

33struct VersionedInfoMetadata {

34

35 VersionTuple Version;

36 unsigned IsActive : 1;

37 unsigned IsReplacement : 1;

38

39 VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,

40 IsSubstitution_t Replacement)

41 : Version(Version), IsActive(Active == IsActive_t::Active),

42 IsReplacement(Replacement == IsSubstitution_t::Replacement) {}

43};

44}

45

46

55

57 VersionedInfoMetadata metadata) {

58 if (typeString.empty())

59

60 return;

61

62

63

65 auto *typeAttr = SwiftTypeAttr::CreateImplicit(S.Context, typeString);

66 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(

67 S.Context, metadata.Version, typeAttr, metadata.IsReplacement);

68 decl->addAttr(versioned);

69 } else {

70 if (!metadata.IsActive)

71 return;

73 }

74}

75

76

78 VersionedInfoMetadata metadata) {

79

80

82 SwiftNullabilityAttr::Kind attrNullabilityKind;

83 switch (nullability) {

85 attrNullabilityKind = SwiftNullabilityAttr::Kind::NonNull;

86 break;

88 attrNullabilityKind = SwiftNullabilityAttr::Kind::Nullable;

89 break;

91 attrNullabilityKind = SwiftNullabilityAttr::Kind::Unspecified;

92 break;

94 attrNullabilityKind = SwiftNullabilityAttr::Kind::NullableResult;

95 break;

96 }

97 auto *nullabilityAttr =

98 SwiftNullabilityAttr::CreateImplicit(S.Context, attrNullabilityKind);

99 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(

100 S.Context, metadata.Version, nullabilityAttr, metadata.IsReplacement);

101 decl->addAttr(versioned);

102 return;

103 } else {

104 if (!metadata.IsActive)

105 return;

106

108 }

109}

110

111

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

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

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

116}

117

122 0, false,

123 false});

124}

125

126namespace {

127template struct AttrKindFor {};

128

129#define ATTR(X) \

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

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

132 };

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

134

135

136

137

138

139

140template

141void handleAPINotedAttribute(

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

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

145 if (Metadata.IsActive) {

146 auto Existing = GetExistingAttr(D);

147 if (Existing != D->attr_end()) {

148

149

150 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(

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

152

153 D->getAttrs().erase(Existing);

155 }

156

157

158 if (IsAddition) {

159 if (auto Attr = CreateAttr())

161 }

162

163 return;

164 }

165 if (IsAddition) {

166 if (auto Attr = CreateAttr()) {

167 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(

169 Metadata.IsReplacement);

171 }

172 } else {

173

174

175

176 auto *Versioned = SwiftVersionedRemovalAttr::CreateImplicit(

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

178 Metadata.IsReplacement);

180 }

181}

182

183template

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

185 VersionedInfoMetadata Metadata,

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

187 handleAPINotedAttribute(

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

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

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

191 });

192}

193}

194

195template

197 bool ShouldAddAttribute,

198 VersionedInfoMetadata Metadata) {

199

200

201 handleAPINotedAttribute(

202 S, D, ShouldAddAttribute, Metadata,

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

206 return isa(Next) ||

207 isa(Next) ||

208 isa(Next) ||

209 isa(Next) ||

210 isa(Next);

211 });

212 });

213}

214

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

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

218 if (!Convention)

219 return;

220 switch (*Convention) {

224 S, D, true, Metadata);

225 } else {

227 S, D, false, Metadata);

228 }

229 break;

232 S, D, true, Metadata);

233 break;

236 S, D, true, Metadata);

237 break;

240 S, D, true, Metadata);

241 break;

244 S, D, true, Metadata);

245 break;

246 }

247}

248

251 VersionedInfoMetadata Metadata) {

252

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

258 });

259 }

260

262 handleAPINotedAttribute(

263 S, D, true, Metadata,

264 [&] {

265 return new (S.Context) AvailabilityAttr(

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

268 VersionTuple(),

269 true,

271 false,

272 StringRef(),

274 nullptr);

275 },

276 [](const Decl *D) {

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

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

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

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

281 return false;

282 });

283 });

284 }

285

286

288 handleAPINotedAttribute(

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

292 });

293 }

294

295

298 handleAPINotedAttribute(

300 [&] {

301 return SwiftAttrAttr::Create(

303 ? "safe"

304 : "unsafe");

305 },

306 [](const Decl *D) {

307 return llvm::find_if(D->attrs(), [](const Attr *attr) {

308 if (const auto *swiftAttr = dyn_cast(attr)) {

309 if (swiftAttr->getAttribute() == "safe" ||

310 swiftAttr->getAttribute() == "unsafe")

311 return true;

312 }

313 return false;

314 });

315 });

316 }

317

318

319 if (!Info.SwiftName.empty()) {

320 handleAPINotedAttribute(

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

327 nullptr, nullptr, nullptr, ParsedAttr::Form::GNU());

328

330 false))

331 return nullptr;

332

336 });

337 }

338}

339

342 VersionedInfoMetadata Metadata) {

343

345 handleAPINotedAttribute(

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

347 return new (S.Context)

348 SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),

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

350 });

351 }

352

353

355 handleAPINotedAttribute(

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

357 return new (S.Context)

358 NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),

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

360 });

361 }

362

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

366

368 Metadata);

369}

370

371

372

373

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

380 << ReplacementType << OrigType;

381 return true;

382 }

383

384 return false;

385}

386

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

395

400 }

401

403 Var->getType(), Type)) {

404 Var->setType(Type);

405 Var->setTypeSourceInfo(TypeInfo);

406 }

407 } else if (auto property = dyn_cast(D)) {

409 property->getType(), Type)) {

411 }

412 } else {

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

414 }

415 }

416 }

417}

418

420 auto GetModified =

422 NullabilityKind Nullability) -> std::optional {

426 true);

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

428 : std::nullopt;

429 };

430

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

432 if (auto Modified =

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

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

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

438 else

440 Context.getFunctionNoProtoType(*Modified, FnType->getExtInfo()));

441 }

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

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

444 Method->setReturnType(*Modified);

445

446

450 }

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

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

453 Value->setType(*Modified);

454

455

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

460 }

461 }

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

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

465

466

468 Property->setPropertyAttributes(

470 }

471 }

472}

473

474

477 VersionedInfoMetadata Metadata) {

478

480

481

484

485

487 Metadata);

488}

489

490

493 VersionedInfoMetadata Metadata) {

494

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

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

498 });

499

501 handleAPINotedAttribute(

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

505 });

506

507

510

511

513 Metadata);

514}

515

516

519 VersionedInfoMetadata metadata) {

520

522 metadata);

523}

524

525

528 VersionedInfoMetadata metadata) {

529

531 metadata);

532}

533

534

537 VersionedInfoMetadata Metadata) {

538

540 Metadata);

541

543 handleAPINotedAttribute(

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

545 return new (S.Context) SwiftImportPropertyAsAccessorsAttr(

547 });

548 }

549}

550

551namespace {

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

553}

554

555

558 VersionedInfoMetadata Metadata) {

559

560 FunctionDecl *FD = dyn_cast<FunctionDecl *>(AnyFunc);

561 Decl *D = FD;

563 if (!D) {

565 D = MD;

566 }

567

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

569

570

573

574

576

577 bool AnyTypeChanged = false;

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

580 QualType ParamTypeBefore = Param->getType();

581

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

584

585

588

589 if (ParamTypeBefore.getAsOpaquePtr() != Param->getType().getAsOpaquePtr())

590 AnyTypeChanged = true;

591 }

592

593

597

598

599 QualType OverriddenResultType;

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

606

607 if (MD) {

610 auto ResultTypeInfo =

614 }

617 OverriddenResultType = ResultType;

618 AnyTypeChanged = true;

619 }

620 }

621 }

622

623

624

625 if (FD && AnyTypeChanged) {

627 if (OverriddenResultType.isNull())

628 OverriddenResultType = fnProtoType->getReturnType();

629

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

633

635 fnProtoType->getExtProtoInfo()));

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

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

640 }

641 }

642

643

646

647

649 Metadata);

650}

651

652

655 VersionedInfoMetadata Metadata) {

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

658 auto MethodType = Method->getType();

664 TLB.pushFullCopy(Method->getTypeSourceInfo()->getTypeLoc());

667 Method->setType(AttributedType);

669 }

670

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

672}

673

674

677 VersionedInfoMetadata Metadata) {

678

681}

682

683

686 VersionedInfoMetadata Metadata) {

687

689 Metadata);

690}

691

692

695 VersionedInfoMetadata Metadata) {

696

698 handleAPINotedAttribute(

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

701 IFace->setHasDesignatedInitializers();

702

703 return new (S.Context) ObjCDesignatedInitializerAttr(

705 });

706 }

707

708

711}

712

713

715 VersionedInfoMetadata Metadata) {

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

718

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

721

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

727 SwiftAttrAttr::Create(S.Context, "destroy:" + DestroyOp.value()));

729 D->addAttr(SwiftAttrAttr::Create(

730 S.Context, "returned_as_" + DefaultOwnership.value() + "_by_default"));

731

733 if (!*Copyable)

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

735 }

736

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

740 }

741

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

745 handleAPINotedAttribute(

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

747 EnumExtensibilityAttr::Kind kind;

748 switch (*Extensibility) {

749 case EnumExtensibilityKind::None:

750 llvm_unreachable("remove only");

751 case EnumExtensibilityKind::Open:

752 kind = EnumExtensibilityAttr::Open;

753 break;

754 case EnumExtensibilityKind::Closed:

755 kind = EnumExtensibilityAttr::Closed;

756 break;

757 }

760 });

761 }

762

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

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

766 });

767 }

768

769

771 Metadata);

772}

773

774

777 VersionedInfoMetadata Metadata) {

778

780

782 handleAPINotedAttribute(

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

784 SwiftNewTypeAttr::NewtypeKind Kind;

785 switch (*SwiftWrapper) {

786 case SwiftWrapperKind::None:

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

788

789 case SwiftWrapperKind::Struct:

790 Kind = SwiftNewTypeAttr::NK_Struct;

791 break;

792

793 case SwiftWrapperKind::Enum:

794 Kind = SwiftNewTypeAttr::NK_Enum;

795 break;

796 }

799 AttributeCommonInfo::AT_SwiftNewType,

801 false, false}};

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

803 });

804 }

805

806

808 Metadata);

809}

810

811

814 VersionedInfoMetadata Metadata) {

815

817 Metadata);

818}

819

820

823 VersionedInfoMetadata Metadata) {

825 handleAPINotedAttribute(

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

829 });

830 }

831

833 handleAPINotedAttribute(

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

837 });

838 }

839

840

842 Metadata);

843}

844

845

846

847

848

849

850

851

852

853template

857 if (D->hasAttr())

858 return;

860 return;

861

862

863 VersionTuple SelectedVersion;

864 SpecificInfo SelectedInfoSlice;

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

866 if (SelectedVersion.empty())

867 return;

868 if (SelectedInfoSlice.SwiftName.empty())

869 return;

870

871

872 for (const auto &VersionAndInfoSlice : Info) {

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

874 continue;

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

876 return;

877 }

878

879

880 VersionedInfoMetadata DummyFutureMetadata(

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

882 handleAPINotedAttribute(

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

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

885 });

886}

887

888

889

890

891template <typename SpecificDecl, typename SpecificInfo>

893 Sema &S, SpecificDecl *D,

895

898

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

900

901 VersionTuple Version;

902 SpecificInfo InfoSlice;

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

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

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

906 auto Replacement = IsSubstitution_t::Original;

907

908

909

910

912 Active = IsActive_t::Inactive;

913 Replacement = IsSubstitution_t::Original;

914 } else if (Active == IsActive_t::Inactive && Version.empty()) {

915 Replacement = IsSubstitution_t::Replacement;

916 Version = Info[Selected].first;

917 }

918

920 VersionedInfoMetadata(Version, Active, Replacement));

921 }

922}

923

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

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

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

928

929 std::stack<NamespaceDecl *> NamespaceStack;

930 {

931 for (auto CurrentNamespace = NamespaceContext; CurrentNamespace;

932 CurrentNamespace =

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

934 if (!CurrentNamespace->isInlineNamespace())

935 NamespaceStack.push(CurrentNamespace);

936 }

937 }

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

939 while (!NamespaceStack.empty()) {

940 auto CurrentNamespace = NamespaceStack.top();

941 NamespaceStack.pop();

942 NamespaceID =

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

944 if (!NamespaceID)

945 return std::nullopt;

946 }

947 if (NamespaceID)

950 }

951 }

952 return std::nullopt;

953}

954

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

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

959

960 std::stack<TagDecl *> TagStack;

961 {

962 for (auto CurrentTag = DC; CurrentTag;

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

964 TagStack.push(CurrentTag);

965 }

966 assert(!TagStack.empty());

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

969 while (!TagStack.empty()) {

970 auto CurrentTag = TagStack.top();

971 TagStack.pop();

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

973 if (!CtxID)

974 return std::nullopt;

976 }

977 return Ctx;

978 }

979 return std::nullopt;

980}

981

982

983

985 if (!D)

986 return;

987

989

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

991 DC->isExternCXXContext()) {

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

994

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

997 auto Info =

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

1000 }

1001

1002 return;

1003 }

1004

1005

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

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

1009 auto Info =

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

1012 }

1013 }

1014

1015 return;

1016 }

1017

1018

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

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

1023 }

1024

1025 return;

1026 }

1027

1028

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

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

1033 }

1034

1035 return;

1036 }

1037

1038

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

1040

1041

1042

1043

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

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

1047 else

1049

1050

1051

1052

1053

1054

1055 std::string MacroName =

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

1058 Tag->getOuterLocStart(),

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

1060 .str()

1061 : "";

1062

1064 (MacroName == "CF_OPTIONS" || MacroName == "NS_OPTIONS" ||

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

1066

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

1070 }

1071

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

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

1077 }

1078

1079 return;

1080 }

1081

1082

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

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

1087 }

1088

1089 return;

1090 }

1091 }

1092

1093

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

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

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

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

1100 }

1101

1102 return;

1103 }

1104 }

1105

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

1107

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

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

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

1113

1114 return std::nullopt;

1115 }

1116

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

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

1119 ObjCContainer = Cat->getClassInterface();

1120 else

1121 return std::nullopt;

1122 }

1123

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

1125 if (Category->getClassInterface())

1126 ObjCContainer = Category->getClassInterface();

1127 else

1128 return std::nullopt;

1129 }

1130

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

1132 if (Impl->getClassInterface())

1133 ObjCContainer = Impl->getClassInterface();

1134 else

1135 return std::nullopt;

1136 }

1137

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

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

1141

1142 return std::nullopt;

1143 }

1144

1145 return std::nullopt;

1146 };

1147

1148

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

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

1152

1157 } else {

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

1160 }

1161

1165

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

1167 Method->isInstanceMethod());

1169 }

1170 }

1171 }

1172

1173

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

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

1177 bool isInstanceProperty =

1178 (Property->getPropertyAttributesAsWritten() &

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

1181 isInstanceProperty);

1183 }

1184 }

1185

1186 return;

1187 }

1188 }

1189

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

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

1195 !CXXMethod->isOverloadedOperator()) {

1198 auto Info =

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

1201 }

1202 }

1203 }

1204 }

1205

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

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

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

1212 }

1213 }

1214 }

1215 }

1216

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

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

1222 }

1223 }

1224 }

1225 }

1226}

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

FormatToken * Next

The next token in the unwrapped line.

static std::optional< api_notes::Context > UnwindNamespaceContext(DeclContext *DC, api_notes::APINotesManager &APINotes)

Definition SemaAPINotes.cpp:925

static void ProcessVersionedAPINotes(Sema &S, SpecificDecl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info)

Processes all versions of versioned API notes.

Definition SemaAPINotes.cpp:892

static bool checkAPINotesReplacementType(Sema &S, SourceLocation Loc, QualType OrigType, QualType ReplacementType)

Check that the replacement type provided by API notes is reasonable.

Definition SemaAPINotes.cpp:374

static std::optional< api_notes::Context > UnwindTagContext(TagDecl *DC, api_notes::APINotesManager &APINotes)

Definition SemaAPINotes.cpp:956

static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String)

Copy a string into ASTContext-allocated memory.

Definition SemaAPINotes.cpp:112

static void applyAPINotesType(Sema &S, Decl *decl, StringRef typeString, VersionedInfoMetadata metadata)

Definition SemaAPINotes.cpp:56

static void handleAPINotedRetainCountConvention(Sema &S, Decl *D, VersionedInfoMetadata Metadata, std::optional< api_notes::RetainCountConventionKind > Convention)

Definition SemaAPINotes.cpp:215

static void handleAPINotedRetainCountAttribute(Sema &S, Decl *D, bool ShouldAddAttribute, VersionedInfoMetadata Metadata)

Definition SemaAPINotes.cpp:196

static AttributeCommonInfo getPlaceholderAttrInfo()

Definition SemaAPINotes.cpp:118

static void ProcessAPINotes(Sema &S, Decl *D, const api_notes::CommonEntityInfo &Info, VersionedInfoMetadata Metadata)

Definition SemaAPINotes.cpp:249

static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability, VersionedInfoMetadata metadata)

Apply nullability to the given declaration.

Definition SemaAPINotes.cpp:77

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

Definition SemaAPINotes.cpp:854

static bool isIndirectPointerType(QualType Type)

Determine whether this is a multi-level pointer type.

Definition SemaAPINotes.cpp:47

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.

Attr - This represents one attribute.

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

ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())

Type source information for an attributed type.

void setAttr(const Attr *A)

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

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

ObjCInterfaceDecl * getClassInterface()

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)

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.

bool captureSwiftVersionIndependentAPINotes()

Whether APINotes should be gathered for all applicable Swift language versions, without being applied...

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.

void ApplyNullability(Decl *D, NullabilityKind Nullability)

Apply the 'Nullability:' annotation to the specified declaration.

Definition SemaAPINotes.cpp:419

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 ApplyAPINotesType(Decl *D, StringRef TypeString)

Apply the 'Type:' annotation to the specified declaration.

Definition SemaAPINotes.cpp:387

void ProcessAPINotes(Decl *D)

Map any API notes provided for this declaration to attributes on the declaration.

Definition SemaAPINotes.cpp:984

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.

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 UnavailableMsg

Message to use when this entity is unavailable.

std::optional< SwiftSafetyKind > getSwiftSafety() const

std::optional< bool > isSwiftPrivate() const

Describes API notes for types.

std::optional< std::string > getSwiftConformance() const

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< std::string > SwiftDefaultOwnership

std::optional< EnumExtensibilityKind > EnumExtensibility

std::optional< std::string > SwiftDestroyOp

std::optional< bool > isFlagEnum() const

std::optional< bool > isSwiftCopyable() const

std::optional< bool > isSwiftEscapable() const

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< Decl > decl

Matches declarations.

bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD)

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

NullabilityKind

Describes the nullability of a particular type.

@ Nullable

Values of this type can be null.

@ Unspecified

Whether values of this type can be null is (explicitly) unspecified.

@ NonNull

Values of this type can never be null.

@ Property

The type of a property.

const FunctionProtoType * T

U cast(CodeGen::Address addr)

OpaquePtr< QualType > ParsedType

An opaque type for threading parsed type information through the parser.

@ 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