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

1

2

3

4

5

6

7

8

9

10

11

12

25#include "llvm/Support/ConvertUTF.h"

26

28

30 : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr),

31 NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),

32 ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),

33 ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),

34 DictionaryWithObjectsMethod(nullptr) {}

35

41

44

48 if (!DS->isSingleDecl())

49 return StmtError(Diag((*DS->decl_begin())->getLocation(),

50 diag::err_toomany_element_decls));

51

52 VarDecl *D = dyn_cast(DS->getSingleDecl());

53 if (D || D->isInvalidDecl())

55

56 FirstType = D->getType();

57

58

59

60 if (D->hasLocalStorage())

62 Diag(D->getLocation(), diag::err_non_local_variable_decl_in_for));

63

64

68 Expr *DeducedInit = &OpaqueId;

72 D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info);

76 if (FirstType.isNull()) {

77 D->setInvalidDecl();

79 }

80

81 D->setType(FirstType);

82

85 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();

86 Diag(Loc, diag::warn_auto_var_is_id) << D->getDeclName();

87 }

88 }

89

90 } else {

94 Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue)

95 << First->getSourceRange());

96

97 FirstType = static_cast<Expr *>(First)->getType();

99 Diag(ForLoc, diag::err_selector_element_const_type)

100 << FirstType << First->getSourceRange();

101 }

105 return StmtError(Diag(ForLoc, diag::err_selector_element_type)

106 << FirstType << First->getSourceRange());

107 }

108

109 if (CollectionExprResult.isInvalid())

111

113 false);

114 if (CollectionExprResult.isInvalid())

116

118 nullptr, ForLoc, RParenLoc);

119}

120

122 Expr *collection) {

124 if (!collection)

126

130 collection = result.get();

131

132

134 return collection;

135

136

140 collection = result.get();

141

142

143

147 return Diag(forLoc, diag::err_collection_expr_type)

149

150

151

154

155

156

157 if (iface &&

160 diag::err_arc_collection_forward,

161 collection)

163

164

165 } else if (iface || !objectType->qual_empty()) {

167 &Context.Idents.get("countByEnumeratingWithState"),

168 &Context.Idents.get("objects"), &Context.Idents.get("count")};

169 Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);

170

172

173

174 if (iface) {

176 if (!method)

178 }

179

180

181 if (!method)

183 true);

184

185

186 if (!method) {

187 Diag(forLoc, diag::warn_collection_expr_type)

189 }

190

191

192 }

193

194

195 return collection;

196}

197

199 if (!S || !B)

202

204 return S;

205}

206

209 Stmt *Body) {

211 VarDecl *Var = cast_or_null(Parm);

214

215 return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);

216}

217

221}

222

225 Stmt *Finally) {

228 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try";

229

230

233 Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1;

234 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";

235 }

236

238 unsigned NumCatchStmts = CatchStmts.size();

240 NumCatchStmts, Finally);

241}

242

245 if (Throw) {

247 if (Result.isInvalid())

249

252 if (Result.isInvalid())

254 Throw = Result.get();

255

257

262 return StmtError(Diag(AtLoc, diag::err_objc_throw_expects_object)

264 }

265 }

266

268}

269

271 Scope *CurScope) {

273 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw";

274

275 if (!Throw) {

276

277

278 Scope *AtCatchParent = CurScope;

279 while (AtCatchParent && !AtCatchParent->isAtCatchScope())

280 AtCatchParent = AtCatchParent->getParent();

281 if (!AtCatchParent)

282 return StmtError(Diag(AtLoc, diag::err_rethrow_used_outside_catch));

283 }

285}

286

288 Expr *operand) {

292 operand = result.get();

293

294

296 if (type->isDependentType() && type->isObjCObjectPointerType()) {

301 diag::err_incomplete_receiver_type))

302 return Diag(atLoc, diag::err_objc_synchronized_expects_object)

304

310 return Diag(atLoc, diag::err_objc_synchronized_expects_object)

312

313 operand = result.get();

314 } else {

315 return Diag(atLoc, diag::err_objc_synchronized_expects_object)

317 }

318 }

319 }

320

321

323}

324

326 Expr *SyncExpr,

327 Stmt *SyncBody) {

329

332}

333

335 Stmt *Body) {

339}

340

345

347 Context.ObjCBuiltinIdTy, {},

349 protocols.size()),

350 false);

351 Result = Context.getObjCObjectPointerType(Result);

352

355

358

359 auto ObjCObjectTL =

362 ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation());

363

364

367

368

369 ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc);

370 ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc);

371 for (unsigned i = 0, n = protocols.size(); i != n; ++i)

372 ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]);

373

374

376}

377

387 if (T.isNull())

388 return true;

389

390

391 if (!BaseTypeInfo)

392 BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc);

393

394

396 for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) {

399 if (TypeArg.isNull()) {

400 ActualTypeArgInfos.clear();

401 break;

402 }

403

404 assert(TypeArgInfo && "No type source info?");

405 ActualTypeArgInfos.push_back(TypeArgInfo);

406 }

407

408

411 TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc,

412 ProtocolLAngleLoc,

414 Protocols.size()),

415 ProtocolLocs, ProtocolRAngleLoc,

416 false,

417 false);

418

420 return BaseType;

421

422

425

426

427

429

431 ResultTL = ObjCObjectPointerTL.getPointeeLoc();

432 }

433

435

436 if (OTPTL.getNumProtocols() > 0) {

437 assert(OTPTL.getNumProtocols() == Protocols.size());

438 OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);

439 OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);

440 for (unsigned i = 0, n = Protocols.size(); i != n; ++i)

441 OTPTL.setProtocolLoc(i, ProtocolLocs[i]);

442 }

443

444

446 }

447

449

450

451 if (ObjCObjectTL.getNumTypeArgs() > 0) {

452 assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size());

453 ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc);

454 ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc);

455 for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i)

456 ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]);

457 } else {

460 }

461

462

463 if (ObjCObjectTL.getNumProtocols() > 0) {

464 assert(ObjCObjectTL.getNumProtocols() == Protocols.size());

465 ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc);

466 ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc);

467 for (unsigned i = 0, n = Protocols.size(); i != n; ++i)

468 ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]);

469 } else {

472 }

473

474

475 ObjCObjectTL.setHasBaseTypeAsWritten(true);

476 if (ObjCObjectTL.getType() == T)

477 ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc());

478 else

479 ObjCObjectTL.getBaseLoc().initialize(Context, Loc);

480

481

483}

484

489 bool FailOnError) {

492 if (!Protocols.empty()) {

493 bool HasError;

494 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError);

495 if (HasError) {

497 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);

498 if (FailOnError)

500 }

501 if (FailOnError && Result.isNull())

503 }

504

506}

507

508

511 SourceRange typeArgsRange, bool failOnError,

512 bool rebuilding) {

513

515 if (!objcObjectType || !objcObjectType->getInterface()) {

516 S.Diag(loc, diag::err_objc_type_args_non_class) << type << typeArgsRange;

517

518 if (failOnError)

521 }

522

523

526 if (!typeParams) {

527 S.Diag(loc, diag::err_objc_type_args_non_parameterized_class)

529

530 if (failOnError)

532

534 }

535

536

537 if (objcObjectType->isSpecialized()) {

538 S.Diag(loc, diag::err_objc_type_args_specialized_class)

540

541 if (failOnError)

543

545 }

546

547

549 unsigned numTypeParams = typeParams->size();

550 bool anyPackExpansions = false;

551 for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) {

554

555

556

557

559 bool diagnosed = false;

562 rangeToRemove = attr.getLocalSourceRange();

563 if (attr.getTypePtr()->getImmediateNullability()) {

564 typeArg = attr.getTypePtr()->getModifiedType();

566 diag::err_objc_type_arg_explicit_nullability)

568 diagnosed = true;

569 }

570 }

571

572

573

574 if (!rebuilding && !diagnosed) {

575 S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified)

578 }

579 }

580

581

583

584 finalTypeArgs.push_back(typeArg);

585

587 anyPackExpansions = true;

588

589

591 if (!anyPackExpansions) {

592 if (i < numTypeParams) {

593 typeParam = typeParams->begin()[i];

594 } else {

595

596 S.Diag(loc, diag::err_objc_type_args_wrong_arity)

598 << numTypeParams;

599 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass;

600

601 if (failOnError)

603

605 }

606 }

607

608

610

611

612

613 if (!typeParam) {

614 assert(anyPackExpansions && "Too many arguments?");

615 continue;

616 }

617

618

621

622

623 if (typeArgObjC->isObjCIdType()) {

624

625

626 if (boundObjC->isObjCIdType())

627 continue;

629

630 continue;

631 }

632

633

635 diag::err_objc_type_arg_does_not_match_bound)

636 << typeArg << bound << typeParam->getDeclName();

637 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)

639

640 if (failOnError)

642

644 }

645

646

648

649

650

651 if (!typeParam) {

652 assert(anyPackExpansions && "Too many arguments?");

653 continue;

654 }

655

656

659 continue;

660

661

663 diag::err_objc_type_arg_does_not_match_bound)

664 << typeArg << bound << typeParam->getDeclName();

665 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)

667

668 if (failOnError)

670

672 }

673

674

676 continue;

677 }

678

679

681 continue;

682 }

683

684

686 diag::err_objc_type_arg_not_id_compatible)

688

689 if (failOnError)

691

693 }

694

695

696 if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) {

697 S.Diag(loc, diag::err_objc_type_args_wrong_arity)

698 << (typeArgs.size() < typeParams->size()) << objcClass->getDeclName()

699 << (unsigned)finalTypeArgs.size() << (unsigned)numTypeParams;

700 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass;

701

702 if (failOnError)

704

706 }

707

708

710}

711

717 bool FailOnError, bool Rebuilding) {

720 if (!TypeArgs.empty()) {

723 SourceRange(TypeArgsLAngleLoc, TypeArgsRAngleLoc),

724 FailOnError, Rebuilding);

725 if (FailOnError && Result.isNull())

727 }

728

729 if (!Protocols.empty()) {

730 bool HasError;

731 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError);

732 if (HasError) {

733 Diag(Loc, diag::err_invalid_protocol_qualifiers)

734 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);

735 if (FailOnError)

737 }

738 if (FailOnError && Result.isNull())

740 }

741

743}

744

747 QualType T = Context.getObjCInstanceType();

750}

751

752

753

754namespace {

755

756struct RetainCycleOwner {

757 VarDecl *Variable = nullptr;

761

762 RetainCycleOwner() = default;

763

764 void setLocsFrom(Expr *e) {

765 Loc = e->getExprLoc();

766 Range = e->getSourceRange();

767 }

768};

769

770}

771

772

773

775

776

777

779 return false;

780

781 owner.Variable = var;

782 if (ref)

783 owner.setLocsFrom(ref);

784 return true;

785}

786

788 while (true) {

790 if (CastExpr *cast = dyn_cast(e)) {

791 switch (cast->getCastKind()) {

792 case CK_BitCast:

793 case CK_LValueBitCast:

794 case CK_LValueToRValue:

795 case CK_ARCReclaimReturnedObject:

796 e = cast->getSubExpr();

797 continue;

798

799 default:

800 return false;

801 }

802 }

803

804 if (ObjCIvarRefExpr *ref = dyn_cast(e)) {

807 return false;

808

809

811 return false;

812

813 if (ref->isFreeIvar())

814 owner.setLocsFrom(ref);

815 owner.Indirect = true;

816 return true;

817 }

818

819 if (DeclRefExpr *ref = dyn_cast(e)) {

820 VarDecl *var = dyn_cast(ref->getDecl());

821 if (!var)

822 return false;

824 }

825

826 if (MemberExpr *member = dyn_cast(e)) {

827 if (member->isArrow())

828 return false;

829

830

831 e = member->getBase();

832 continue;

833 }

834

835 if (PseudoObjectExpr *pseudo = dyn_cast(e)) {

836

838 pseudo->getSyntacticForm()->IgnoreParens());

839 if (!pre)

840 return false;

842 return false;

844 if (!property->isRetaining() &&

845 !(property->getPropertyIvarDecl() &&

846 property->getPropertyIvarDecl()->getType().getObjCLifetime() ==

848 return false;

849

850 owner.Indirect = true;

853 if (!owner.Variable)

854 return false;

857 return true;

858 }

859 e = const_cast<Expr *>(

860 cast(pre->getBase())->getSourceExpr());

861 continue;

862 }

863

864

865

866 return false;

867 }

868}

869

870namespace {

871

872struct FindCaptureVisitor : EvaluatedExprVisitor {

873 VarDecl *Variable;

876

877 FindCaptureVisitor(ASTContext &Context, VarDecl *variable)

878 : EvaluatedExprVisitor(Context), Variable(variable) {}

879

880 void VisitDeclRefExpr(DeclRefExpr *ref) {

881 if (ref->getDecl() == Variable && !Capturer)

883 }

884

885 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) {

886 if (Capturer)

887 return;

888 Visit(ref->getBase());

889 if (Capturer && ref->isFreeIvar())

891 }

892

893 void VisitBlockExpr(BlockExpr *block) {

894

895 if (block->getBlockDecl()->capturesVariable(Variable))

896 Visit(block->getBlockDecl()->getBody());

897 }

898

899 void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) {

900 if (Capturer)

901 return;

902 if (OVE->getSourceExpr())

903 Visit(OVE->getSourceExpr());

904 }

905

906 void VisitBinaryOperator(BinaryOperator *BinOp) {

907 if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)

908 return;

909 Expr *LHS = BinOp->getLHS();

910 if (const DeclRefExpr *DRE = dyn_cast_or_null(LHS)) {

911 if (DRE->getDecl() != Variable)

912 return;

913 if (Expr *RHS = BinOp->getRHS()) {

914 RHS = RHS->IgnoreParenCasts();

915 std::optionalllvm::APSInt Value;

917 (RHS && (Value = RHS->getIntegerConstantExpr(Context)) &&

919 }

920 }

921 }

922};

923

924}

925

926

927

929 assert(owner.Variable && owner.Loc.isValid());

930

932

933

934 if (ObjCMessageExpr *ME = dyn_cast(e)) {

936 if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") {

937 e = ME->getInstanceReceiver();

938 if (!e)

939 return nullptr;

941 }

942 } else if (CallExpr *CE = dyn_cast(e)) {

943 if (CE->getNumArgs() == 1) {

944 FunctionDecl *Fn = dyn_cast_or_null(CE->getCalleeDecl());

945 if (Fn) {

947 if (FnI && FnI->isStr("_Block_copy")) {

949 }

950 }

951 }

952 }

953

954 BlockExpr *block = dyn_cast(e);

956 return nullptr;

957

958 FindCaptureVisitor visitor(S.Context, owner.Variable);

960 return visitor.VarWillBeReased ? nullptr : visitor.Capturer;

961}

962

964 RetainCycleOwner &owner) {

965 assert(capturer);

966 assert(owner.Variable && owner.Loc.isValid());

967

968 S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle)

970 S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner)

971 << owner.Indirect << owner.Range;

972}

973

974

975

978 return false;

979

981 str = str.ltrim('_');

982 if (str.starts_with("set"))

983 str = str.substr(3);

984 else if (str.starts_with("add")) {

985

986 if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock"))

987 return false;

988 str = str.substr(3);

989 } else

990 return false;

991

992 if (str.empty())

993 return true;

995}

996

997static std::optional

999 bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass(

1001 if (!IsMutableArray) {

1002 return std::nullopt;

1003 }

1004

1005 Selector Sel = Message->getSelector();

1006

1007 std::optionalNSAPI::NSArrayMethodKind MKOpt =

1008 S.NSAPIObj->getNSArrayMethodKind(Sel);

1009 if (!MKOpt) {

1010 return std::nullopt;

1011 }

1012

1014

1015 switch (MK) {

1019 return 0;

1021 return 1;

1022

1023 default:

1024 return std::nullopt;

1025 }

1026

1027 return std::nullopt;

1028}

1029

1030static std::optional

1032 bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass(

1034 if (!IsMutableDictionary) {

1035 return std::nullopt;

1036 }

1037

1038 Selector Sel = Message->getSelector();

1039

1040 std::optionalNSAPI::NSDictionaryMethodKind MKOpt =

1041 S.NSAPIObj->getNSDictionaryMethodKind(Sel);

1042 if (!MKOpt) {

1043 return std::nullopt;

1044 }

1045

1047

1048 switch (MK) {

1052 return 0;

1053

1054 default:

1055 return std::nullopt;

1056 }

1057

1058 return std::nullopt;

1059}

1060

1063 bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass(

1065

1066 bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass(

1068 if (!IsMutableSet && !IsMutableOrderedSet) {

1069 return std::nullopt;

1070 }

1071

1072 Selector Sel = Message->getSelector();

1073

1074 std::optionalNSAPI::NSSetMethodKind MKOpt =

1075 S.NSAPIObj->getNSSetMethodKind(Sel);

1076 if (!MKOpt) {

1077 return std::nullopt;

1078 }

1079

1081

1082 switch (MK) {

1087 return 0;

1089 return 1;

1090 }

1091

1092 return std::nullopt;

1093}

1094

1096 if (!Message->isInstanceMessage()) {

1097 return;

1098 }

1099

1100 std::optional ArgOpt;

1101

1105 return;

1106 }

1107

1108 int ArgIndex = *ArgOpt;

1109

1110 Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts();

1111 if (OpaqueValueExpr *OE = dyn_cast(Arg)) {

1113 }

1114

1116 if (DeclRefExpr *ArgRE = dyn_cast(Arg)) {

1117 if (ArgRE->isObjCSelfExpr()) {

1118 Diag(Message->getSourceRange().getBegin(),

1119 diag::warn_objc_circular_container)

1120 << ArgRE->getDecl() << StringRef("'super'");

1121 }

1122 }

1123 } else {

1124 Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts();

1125

1126 if (OpaqueValueExpr *OE = dyn_cast(Receiver)) {

1128 }

1129

1130 if (DeclRefExpr *ReceiverRE = dyn_cast(Receiver)) {

1131 if (DeclRefExpr *ArgRE = dyn_cast(Arg)) {

1132 if (ReceiverRE->getDecl() == ArgRE->getDecl()) {

1134 Diag(Message->getSourceRange().getBegin(),

1135 diag::warn_objc_circular_container)

1137 if (!ArgRE->isObjCSelfExpr()) {

1139 diag::note_objc_circular_container_declared_here)

1141 }

1142 }

1143 }

1144 } else if (ObjCIvarRefExpr *IvarRE = dyn_cast(Receiver)) {

1145 if (ObjCIvarRefExpr *IvarArgRE = dyn_cast(Arg)) {

1146 if (IvarRE->getDecl() == IvarArgRE->getDecl()) {

1148 Diag(Message->getSourceRange().getBegin(),

1149 diag::warn_objc_circular_container)

1152 diag::note_objc_circular_container_declared_here)

1154 }

1155 }

1156 }

1157 }

1158}

1159

1160

1162

1164 return;

1165

1166

1167 RetainCycleOwner owner;

1170 return;

1171 } else {

1176 }

1177

1178

1180 for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) {

1182

1183 if (MD && MD->parameters()[i]->hasAttr())

1184 continue;

1186 }

1187 }

1188}

1189

1190

1192 RetainCycleOwner owner;

1194 return;

1195

1198}

1199

1201 RetainCycleOwner Owner;

1203 return;

1204

1205

1206

1209

1212}

1213

1214

1215

1216

1217

1220 StringLiteral *Literal = dyn_cast(Arg);

1221

1222 if (!Literal || !Literal->isOrdinary()) {

1223 Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)

1225 return true;

1226 }

1227

1228 if (Literal->containsNonAsciiOrNull()) {

1229 StringRef String = Literal->getString();

1230 unsigned NumBytes = String.size();

1232 const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data();

1233 llvm::UTF16 *ToPtr = &ToBuf[0];

1234

1235 llvm::ConversionResult Result =

1236 llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr,

1237 ToPtr + NumBytes, llvm::strictConversion);

1238

1239 if (Result != llvm::conversionOK)

1242 }

1243 return false;

1244}

1245

1250

1251 SemaRef.checkCall(Method, nullptr, nullptr, Args,

1252 false, lbrac, Method->getSourceRange(),

1253 CallType);

1254

1256

1257 return false;

1258}

1259

1262

1263 if (const ObjCCategoryDecl *CatD = dyn_cast(DC))

1264 DC = CatD->getClassInterface();

1265 return DC;

1266}

1267

1268

1270 if (!Ident_NSError)

1272

1273 return Ident_NSError;

1274}

1275

1277 assert(

1279 "The next DeclContext should be lexically contained in the current one.");

1281}

1282

1284

1286}

1287

1290 assert(ObjCCtx == SemaRef.CurContext && "Mismatch of container contexts");

1293}

1294

1298}

1299

1300

1306 return cast_or_null(D);

1307}

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1322 Context.hasSameUnqualifiedType(FromType, ToType))

1323 return false;

1324

1325

1329 else

1330 return false;

1331

1336 return false;

1337

1338

1342 else

1343 return false;

1344

1349 return false;

1350

1351

1354 return false;

1355

1356

1357

1358

1360

1361

1363 bool IncompatibleObjC;

1364 if (Context.typesAreCompatible(FromPointee, ToPointee))

1365 FromPointee = ToPointee;

1367 IncompatibleObjC))

1368 return false;

1369

1370

1371

1372 FromPointee = Context.getQualifiedType(FromPointee, FromQuals);

1373 ConvertedType = Context.getPointerType(FromPointee);

1374 return true;

1375}

1376

1377

1378

1380

1384

1385

1386

1389

1390

1393

1395 if (isa(IndexExpr))

1396 Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)

1398 else

1399 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) << T;

1401 }

1402

1403

1405 diag::err_objc_index_incomplete_class_type,

1406 FromE))

1408

1409

1410

1411 int NoIntegrals = 0, NoObjCIdPointers = 0;

1413

1415 ->getVisibleConversionFunctions()) {

1417 dyn_cast(D->getUnderlyingDecl())) {

1418 QualType CT = Conversion->getConversionType().getNonReferenceType();

1420 ++NoIntegrals;

1421 ConversionDecls.push_back(Conversion);

1423 ++NoObjCIdPointers;

1424 ConversionDecls.push_back(Conversion);

1425 }

1426 }

1427 }

1428 if (NoIntegrals == 1 && NoObjCIdPointers == 0)

1430 if (NoIntegrals == 0 && NoObjCIdPointers == 1)

1432 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {

1433

1434 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)

1437 }

1438 Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)

1440 for (unsigned int i = 0; i < ConversionDecls.size(); i++)

1441 Diag(ConversionDecls[i]->getLocation(),

1442 diag::note_conv_function_declared_at);

1443

1445}

1446

1452 if (Loc.isValid())

1453 return;

1454

1455

1456 if (D->hasAttr() ||

1457 D->hasAttr())

1458 return;

1459

1462 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));

1463}

1464

1466

1469

1470

1471

1472

1473

1476 if (auto bridgeAttr = RD->getAttr())

1477 bridgedType = bridgeAttr->getBridgedType();

1478 else if (auto bridgeAttr = RD->getAttr())

1479 bridgedType = bridgeAttr->getBridgedType();

1480

1483 return true;

1484 }

1485 }

1486

1487 return false;

1488}

1489

1492 if (!PT)

1493 return false;

1494

1496 if (!Cls)

1497 return false;

1498

1500

1501 if (AllowNSAttributedString &&

1503 return true;

1504

1507}

1508

1511 if (!PT)

1512 return false;

1513

1515 if (!RT)

1516 return false;

1517

1518 const RecordDecl *RD = RT->getDecl();

1520 return false;

1521

1523}

1524

1526

1527

1528

1529 if (const auto *VD = dyn_cast(D)) {

1531 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)

1532 << AL << VD->getType() << 0;

1533 return false;

1534 }

1535 } else if (const auto *PD = dyn_cast(D)) {

1537 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)

1538 << AL << PD->getType() << 1;

1539 return false;

1540 }

1541 } else {

1542 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;

1543 return false;

1544 }

1545

1546 return true;

1547}

1548

1551 return;

1552

1554}

1555

1557

1559

1561 Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;

1562 return;

1563 }

1564

1566 return;

1567

1569

1572 else {

1574 Context.Idents.get("NSObject"), AL.getLoc(),

1576 if (!PT) {

1577 Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";

1578 return;

1579 }

1580 }

1581

1584 if (!QTLoc)

1585 QTLoc = Context.getTrivialTypeSourceInfo(QT, AL.getLoc());

1586

1587

1588

1589

1590

1593 ? diag::err_iboutletcollection_builtintype

1594 : diag::err_iboutletcollection_type)

1595 << QT;

1596 return;

1597 }

1598

1599 D->addAttr(::new (Context) IBOutletCollectionAttr(Context, AL, QTLoc));

1600}

1601

1603 if (!cast(D)->isThisDeclarationADefinition()) {

1604 Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)

1606 return;

1607 }

1608

1610 ObjCExplicitProtocolImplAttr(getASTContext(), AL));

1611}

1612

1614

1615 if (isa(D->getDeclContext())) {

1616 Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;

1617 return;

1618 }

1619

1621 handleSimpleAttribute(*this, D, AL);

1622 } else {

1623 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;

1624 }

1625}

1626

1629 handleSimpleAttribute(*this, D, AL);

1630 } else {

1631 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;

1632 }

1633}

1634

1636 const auto *M = cast(D);

1638 Diag(AL.getLoc(), diag::err_attribute_argument_n_type)

1640 return;

1641 }

1642

1644 ObjCMethodFamilyAttr::FamilyKind F;

1645 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {

1646 Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;

1647 return;

1648 }

1649

1650 if (F == ObjCMethodFamilyAttr::OMF_init &&

1651 !M->getReturnType()->isObjCObjectPointerType()) {

1652 Diag(M->getLocation(), diag::err_init_method_bad_return_type)

1653 << M->getReturnType();

1654

1655 return;

1656 }

1657

1660}

1661

1663 if (const auto *TD = dyn_cast(D)) {

1664 QualType T = TD->getUnderlyingType();

1666 Diag(TD->getLocation(), diag::err_nsobject_attribute);

1667 return;

1668 }

1669 } else if (const auto *PD = dyn_cast(D)) {

1672 Diag(PD->getLocation(), diag::err_nsobject_attribute);

1673 return;

1674 }

1675 } else {

1676

1677

1678

1679

1680

1681

1682 Diag(D->getLocation(), diag::warn_nsobject_attribute);

1683 }

1685}

1686

1688 if (const auto *TD = dyn_cast(D)) {

1689 QualType T = TD->getUnderlyingType();

1691 Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);

1692 return;

1693 }

1694 } else {

1695 Diag(D->getLocation(), diag::warn_independentclass_attribute);

1696 return;

1697 }

1700}

1701

1704 Diag(AL.getLoc(), diag::err_attribute_argument_n_type)

1706 return;

1707 }

1708

1710 BlocksAttr::BlockType type;

1711 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {

1712 Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;

1713 return;

1714 }

1715

1717}

1718

1721}

1722

1726}

1727

1731}

1732

1735 return true;

1738}

1739

1742 bool IsTemplateInstantiation) {

1744 switch (K) {

1746 handleSimpleAttributeOrDiagnose(

1748 diag::warn_ns_attribute_wrong_parameter_type,

1749 CI.getRange(), "os_consumed", 1);

1750 return;

1752 handleSimpleAttributeOrDiagnose(

1754

1755

1756

1757

1758

1759 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)

1760 ? diag::err_ns_attribute_wrong_parameter_type

1761 : diag::warn_ns_attribute_wrong_parameter_type),

1762 CI.getRange(), "ns_consumed", 0);

1763 return;

1765 handleSimpleAttributeOrDiagnose(

1767 diag::warn_ns_attribute_wrong_parameter_type,

1768 CI.getRange(), "cf_consumed", 1);

1769 return;

1770 }

1771}

1772

1776 case ParsedAttr::AT_CFConsumed:

1777 case ParsedAttr::AT_CFReturnsRetained:

1778 case ParsedAttr::AT_CFReturnsNotRetained:

1780 case ParsedAttr::AT_OSConsumesThis:

1781 case ParsedAttr::AT_OSConsumed:

1782 case ParsedAttr::AT_OSReturnsRetained:

1783 case ParsedAttr::AT_OSReturnsNotRetained:

1784 case ParsedAttr::AT_OSReturnsRetainedOnZero:

1785 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:

1787 case ParsedAttr::AT_NSConsumesSelf:

1788 case ParsedAttr::AT_NSConsumed:

1789 case ParsedAttr::AT_NSReturnsRetained:

1790 case ParsedAttr::AT_NSReturnsNotRetained:

1791 case ParsedAttr::AT_NSReturnsAutoreleased:

1793 default:

1794 llvm_unreachable("Wrong argument supplied");

1795 }

1796}

1797

1801 return false;

1802

1803 Diag(Loc, diag::warn_ns_attribute_wrong_return_type)

1804 << "'ns_returns_retained'" << 0 << 0;

1805 return true;

1806}

1807

1808

1810 const auto *PVD = dyn_cast(D);

1811 if (!PVD)

1812 return false;

1813 QualType QT = PVD->getType();

1816}

1817

1821

1822 if (const auto *MD = dyn_cast(D)) {

1823 ReturnType = MD->getReturnType();

1825 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) {

1826 return;

1827 } else if (const auto *PD = dyn_cast(D)) {

1828 ReturnType = PD->getType();

1829 } else if (const auto *FD = dyn_cast(D)) {

1830 ReturnType = FD->getReturnType();

1831 } else if (const auto *Param = dyn_cast(D)) {

1832

1833

1835 ? 2

1836 : 3;

1838 if (ReturnType.isNull()) {

1839 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)

1840 << AL << DiagID << AL.getRange();

1841 return;

1842 }

1844 return;

1845 } else {

1848 default:

1849 llvm_unreachable("invalid ownership attribute");

1850 case ParsedAttr::AT_NSReturnsRetained:

1851 case ParsedAttr::AT_NSReturnsAutoreleased:

1852 case ParsedAttr::AT_NSReturnsNotRetained:

1854 break;

1855

1856 case ParsedAttr::AT_OSReturnsRetained:

1857 case ParsedAttr::AT_OSReturnsNotRetained:

1858 case ParsedAttr::AT_CFReturnsRetained:

1859 case ParsedAttr::AT_CFReturnsNotRetained:

1861 break;

1862 }

1863 Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)

1865 << ExpectedDeclKind;

1866 return;

1867 }

1868

1869 bool TypeOK;

1870 bool Cf;

1871 unsigned ParmDiagID = 2;

1873 default:

1874 llvm_unreachable("invalid ownership attribute");

1875 case ParsedAttr::AT_NSReturnsRetained:

1877 Cf = false;

1878 break;

1879

1880 case ParsedAttr::AT_NSReturnsAutoreleased:

1881 case ParsedAttr::AT_NSReturnsNotRetained:

1883 Cf = false;

1884 break;

1885

1886 case ParsedAttr::AT_CFReturnsRetained:

1887 case ParsedAttr::AT_CFReturnsNotRetained:

1889 Cf = true;

1890 break;

1891

1892 case ParsedAttr::AT_OSReturnsRetained:

1893 case ParsedAttr::AT_OSReturnsNotRetained:

1895 Cf = true;

1896 ParmDiagID = 3;

1897 break;

1898 }

1899

1900 if (!TypeOK) {

1902 return;

1903

1904 if (isa(D)) {

1905 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)

1906 << AL << ParmDiagID << AL.getRange();

1907 } else {

1908

1910 if (isa(D))

1911 SubjectKind = Method;

1912 else if (isa(D))

1914 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)

1915 << AL << SubjectKind << Cf << AL.getRange();

1916 }

1917 return;

1918 }

1919

1921 default:

1922 llvm_unreachable("invalid ownership attribute");

1923 case ParsedAttr::AT_NSReturnsAutoreleased:

1924 handleSimpleAttribute(*this, D, AL);

1925 return;

1926 case ParsedAttr::AT_CFReturnsNotRetained:

1927 handleSimpleAttribute(*this, D, AL);

1928 return;

1929 case ParsedAttr::AT_NSReturnsNotRetained:

1930 handleSimpleAttribute(*this, D, AL);

1931 return;

1932 case ParsedAttr::AT_CFReturnsRetained:

1933 handleSimpleAttribute(*this, D, AL);

1934 return;

1935 case ParsedAttr::AT_NSReturnsRetained:

1936 handleSimpleAttribute(*this, D, AL);

1937 return;

1938 case ParsedAttr::AT_OSReturnsRetained:

1939 handleSimpleAttribute(*this, D, AL);

1940 return;

1941 case ParsedAttr::AT_OSReturnsNotRetained:

1942 handleSimpleAttribute(*this, D, AL);

1943 return;

1944 };

1945}

1946

1948 const int EP_ObjCMethod = 1;

1949 const int EP_ObjCProperty = 2;

1950

1953 if (isa(D))

1954 resultType = cast(D)->getReturnType();

1955 else

1956 resultType = cast(D)->getType();

1957

1960 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)

1962 << (isa(D) ? EP_ObjCMethod : EP_ObjCProperty)

1963 << 2;

1964

1965

1966 return;

1967 }

1968

1970 ObjCReturnsInnerPointerAttr(getASTContext(), Attrs));

1971}

1972

1974 const auto *Method = cast(D);

1975

1976 const DeclContext *DC = Method->getDeclContext();

1977 if (const auto *PDecl = dyn_cast_if_present(DC)) {

1978 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol)

1979 << Attrs << 0;

1980 Diag(PDecl->getLocation(), diag::note_protocol_decl);

1981 return;

1982 }

1983 if (Method->getMethodFamily() == OMF_dealloc) {

1984 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol)

1985 << Attrs << 1;

1986 return;

1987 }

1988

1991}

1992

1994 if (!isa(D)) {

1995 Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;

1996 return;

1997 }

1998

2000 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;

2001 if (!IdentLoc || !IdentLoc->Ident) {

2002

2004 if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))

2005 Loc = Attr.getArgAsExpr(0)->getBeginLoc();

2006

2007 Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;

2008 return;

2009 }

2010

2011

2017 Diag(IdentLoc->Loc, diag::err_nserrordomain_invalid_decl)

2018 << 1 << IdentLoc->Ident;

2019 return;

2020 }

2021

2024}

2025

2028

2029 if (!Parm) {

2030 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;

2031 return;

2032 }

2033

2034

2035 if (const auto *TD = dyn_cast(D)) {

2037 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL;

2038 return;

2039 }

2040

2041

2042 QualType T = TD->getUnderlyingType();

2044 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);

2045 return;

2046 }

2047 }

2048

2051}

2052

2055

2056 if (!Parm) {

2057 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;

2058 return;

2059 }

2060

2063}

2064

2068 if (!RelatedClass) {

2069 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;

2070 return;

2071 }

2076 D->addAttr(::new (getASTContext()) ObjCBridgeRelatedAttr(

2077 getASTContext(), AL, RelatedClass, ClassMethod, InstanceMethod));

2078}

2079

2082

2083

2084

2085 if (!isa(Ctx) &&

2086 !(isa(Ctx) &&

2087 cast(Ctx)->IsClassExtension())) {

2088 Diag(D->getLocation(), diag::err_designated_init_attr_non_init);

2089 return;

2090 }

2091

2093 if (auto *CatDecl = dyn_cast(Ctx))

2094 IFace = CatDecl->getClassInterface();

2095 else

2096 IFace = cast(Ctx);

2097

2098 if (!IFace)

2099 return;

2100

2103 ObjCDesignatedInitializerAttr(getASTContext(), AL));

2104}

2105

2107 StringRef MetaDataName;

2109 return;

2111 ObjCRuntimeNameAttr(getASTContext(), AL, MetaDataName));

2112}

2113

2114

2115

2116

2117

2119 bool notify = false;

2120

2121 auto *RD = dyn_cast(D);

2122 if (RD && RD->getDefinition()) {

2123 RD = RD->getDefinition();

2124 notify = true;

2125 }

2126

2127 if (RD) {

2128 ObjCBoxableAttr *BoxableAttr =

2130 RD->addAttr(BoxableAttr);

2131 if (notify) {

2132

2133

2135 L->AddedAttributeToRecord(BoxableAttr, RD);

2136 }

2137 }

2138}

2139

2142 return;

2143

2144 Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type)

2147}

2148

2150 const auto *VD = cast(D);

2151 QualType QT = VD->getType();

2152

2154 Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type) << QT;

2155 return;

2156 }

2157

2159

2160

2161

2164

2165 switch (Lifetime) {

2168 "didn't infer lifetime for non-dependent type?");

2169 break;

2170

2173 break;

2174

2177 Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless)

2179 break;

2180 }

2181

2184}

2185

2187 bool DiagnoseFailure) {

2190 if (DiagnoseFailure) {

2191 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)

2192 << 0;

2193 }

2194 return false;

2195 }

2196

2198

2199

2200

2201

2204

2205

2206

2208 if (DiagnoseFailure) {

2209 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained)

2210 << 1;

2211 }

2212 return false;

2213 }

2214

2215

2216

2217

2220 return true;

2221}

2222

2224 if (auto *VD = dyn_cast(D)) {

2225 assert(!isa(VD) && "should be diagnosed automatically");

2226 if (!VD->hasLocalStorage()) {

2227 Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained) << 0;

2228 return;

2229 }

2230

2232 return;

2233

2234 handleSimpleAttribute(*this, D, AL);

2235 return;

2236 }

2237

2238

2239

2240 unsigned NumParams =

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

2244 QualType Ty = PVD->getType();

2245

2246

2247

2248

2249

2252 continue;

2253

2255 }

2256 handleSimpleAttribute(*this, D, AL);

2257}

2258

2264 return true;

2265 }

2266 return false;

2267}

2268

2269

2270

2272 Expr **Args,

2273 unsigned NumArgs) {

2274 unsigned Idx = 0;

2275 bool Format = false;

2278 Idx = 2;

2279 Format = true;

2280 } else

2281 for (const auto *I : FDecl->specific_attrs()) {

2283 Format = true;

2284 break;

2285 }

2286 }

2287 if (!Format || NumArgs <= Idx)

2288 return;

2289 const Expr *FormatExpr = Args[Idx];

2290 if (const CStyleCastExpr *CSCE = dyn_cast(FormatExpr))

2291 FormatExpr = CSCE->getSubExpr();

2295 FormatString = OSL->getString();

2296 else

2297 FormatString = dyn_cast(FormatExpr->IgnoreParenImpCasts());

2298 if (!FormatString)

2299 return;

2301 Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)

2302 << "%s" << 1 << 1;

2303 Diag(FDecl->getLocation(), diag::note_entity_declared_at)

2305 }

2306}

2307

2310 NSAPIObj->isObjCBOOLType(Ty);

2311}

2312

2316 if (const auto *OVE = dyn_cast(Ignored))

2317 Ignored = OVE->getSourceExpr();

2318 bool NeedsParens = isa(Ignored) ||

2319 isa(Ignored) ||

2320 isa(Ignored);

2322 if (NeedsParens)

2326}

2327

2328

2329

2331 Expr *Element, unsigned ElementKind) {

2332

2333 if (auto ICE = dyn_cast(Element)) {

2334 if (ICE->getCastKind() == CK_BitCast &&

2336 Element = ICE->getSubExpr();

2337 }

2338

2339 QualType ElementType = Element->getType();

2344 S.Diag(Element->getBeginLoc(), diag::warn_objc_collection_literal_element)

2345 << ElementType << ElementKind << TargetElementType

2346 << Element->getSourceRange();

2347 }

2348

2349 if (auto ArrayLiteral = dyn_cast(Element))

2351 else if (auto DictionaryLiteral = dyn_cast(Element))

2353}

2354

2355

2356

2360 return;

2361

2363 if (!TargetObjCPtr)

2364 return;

2365

2366 if (TargetObjCPtr->isUnspecialized() ||

2367 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=

2369 return;

2370

2371 auto TypeArgs = TargetObjCPtr->getTypeArgs();

2372 if (TypeArgs.size() != 1)

2373 return;

2374

2375 QualType TargetElementType = TypeArgs[0];

2376 for (unsigned I = 0, N = ArrayLiteral->getNumElements(); I != N; ++I) {

2379 }

2380}

2381

2385 return;

2386

2388 if (!TargetObjCPtr)

2389 return;

2390

2391 if (TargetObjCPtr->isUnspecialized() ||

2392 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() !=

2394 return;

2395

2396 auto TypeArgs = TargetObjCPtr->getTypeArgs();

2397 if (TypeArgs.size() != 2)

2398 return;

2399

2400 QualType TargetKeyType = TypeArgs[0];

2401 QualType TargetObjectType = TypeArgs[1];

2402 for (unsigned I = 0, N = DictionaryLiteral->getNumElements(); I != N; ++I) {

2406 }

2407}

2408

2409}

Defines the clang::Preprocessor interface.

RedeclarationKind

Specifies whether (or how) name lookup is being performed for a redeclaration (vs.

This file declares semantic analysis for Objective-C.

Defines the Objective-C statement AST node classes.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)

canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...

QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const

Legacy interface: cannot provide type arguments or __kindof.

An abstract interface that should be implemented by listeners that want to be notified when an AST en...

Attr - This represents one attribute.

SourceRange getRange() const

bool isRegularKeywordAttribute() const

SourceLocation getLoc() const

Type source information for an attributed type.

Stmt * getBody() const override

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

bool capturesVariable(const VarDecl *var) const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

const BlockDecl * getBlockDecl() const

CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....

Represents a C++ conversion function within a class.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

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

DeclContext * getLexicalParent()

getLexicalParent - Returns the containing lexical DeclContext.

A reference to a declared variable, function, enum, etc.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

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

bool isInvalidDecl() const

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const

SourceLocation getLocation() const

The name of a declaration.

SourceLocation getBeginLoc() const LLVM_READONLY

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

bool isTypeDependent() const

Determines whether the type of this expression depends on.

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Expr * IgnoreImplicit() LLVM_READONLY

Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

static FixItHint CreateRemoval(CharSourceRange RemoveRange)

Create a code modification hint that removes the given source range.

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

ForStmt - This represents a 'for (init;cond;inc)' stmt.

Represents a function declaration or definition.

One of these records is kept for each identifier that is lexed.

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

Represents the results of name lookup.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

@ ClassId_NSMutableOrderedSet

@ ClassId_NSMutableDictionary

NSSetMethodKind

Enumerates the NSMutableSet/NSOrderedSet methods used to apply some checks.

@ NSOrderedSet_setObjectAtIndex

@ NSOrderedSet_replaceObjectAtIndexWithObject

@ NSOrderedSet_setObjectAtIndexedSubscript

@ NSOrderedSet_insertObjectAtIndex

NSDictionaryMethodKind

Enumerates the NSDictionary/NSMutableDictionary methods used to generate literals and to apply some c...

@ NSMutableDict_setValueForKey

@ NSMutableDict_setObjectForKey

@ NSMutableDict_setObjectForKeyedSubscript

NSArrayMethodKind

Enumerates the NSArray/NSMutableArray methods used to generate literals and to apply some checks.

@ NSMutableArr_setObjectAtIndexedSubscript

@ NSMutableArr_insertObjectAtIndex

@ NSMutableArr_replaceObjectAtIndex

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

ObjCStringFormatFamily getObjCFStringFormattingFamily() const

ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...

Expr * getElement(unsigned Index)

getElement - Return the Element at the specified index.

unsigned getNumElements() const

getNumElements - Return number of elements of objective-c array literal.

Represents Objective-C's @catch statement.

Represents Objective-C's @finally statement.

Represents Objective-C's @synchronized statement.

Represents Objective-C's @throw statement.

static ObjCAtTryStmt * Create(const ASTContext &Context, SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt)

Represents Objective-C's @autoreleasepool Statement.

ObjCCategoryDecl - Represents a category declaration.

ObjCContainerDecl - Represents a container for method declarations.

ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...

unsigned getNumElements() const

getNumElements - Return number of elements of objective-c dictionary literal.

ObjCDictionaryElement getKeyValueElement(unsigned Index) const

Represents Objective-C's collection statement.

Represents an ObjC class declaration.

ObjCTypeParamList * getTypeParamList() const

Retrieve the type parameters of this class.

ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const

Lookup an instance method for a given selector.

ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const

Lookup a method in the classes implementation hierarchy.

ObjCInterfaceDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this Objective-C class.

void setHasDesignatedInitializers()

Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCIvarRefExpr - A reference to an ObjC instance variable.

An expression that sends a message to the given Objective-C object or class.

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

Expr * getInstanceReceiver()

Returns the object expression (receiver) for an instance message, or null for a message that is not a...

SourceLocation getSuperLoc() const

Retrieve the location of the 'super' keyword for a class or instance message to 'super',...

Selector getSelector() const

@ SuperInstance

The receiver is the instance of the superclass object.

@ Instance

The receiver is an object instance.

bool isInstanceMessage() const

Determine whether this is an instance message to either a computed object or to super.

const ObjCMethodDecl * getMethodDecl() const

ReceiverKind getReceiverKind() const

Determine the kind of receiver that this message is being sent to.

unsigned getNumArgs() const

Return the number of actual arguments in this message, not counting the receiver.

ObjCMethodDecl - Represents an instance or class method declaration.

ImplicitParamDecl * getSelfDecl() const

ArrayRef< ParmVarDecl * > parameters() const

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Wraps an ObjCPointerType with source location information.

void setStarLoc(SourceLocation Loc)

Represents a pointer to an Objective C object.

ArrayRef< QualType > getTypeArgs() const

Retrieve the type arguments for this type.

void setHasBaseTypeAsWritten(bool HasBaseType)

Represents a class type in Objective C.

ObjCInterfaceDecl * getInterface() const

Gets the interface declaration for this object type, if the base type really is an interface.

Represents one property declaration in an Objective-C interface.

ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.

ObjCPropertyDecl * getExplicitProperty() const

const Expr * getBase() const

bool isImplicitProperty() const

SourceLocation getLocation() const

bool isSuperReceiver() const

Represents an Objective-C protocol declaration.

The basic abstraction for the target Objective-C runtime.

bool allowsDirectDispatch() const

Does this runtime supports direct dispatch.

ObjCStringLiteral, used for Objective-C string literals i.e.

Represents the declaration of an Objective-C type parameter.

Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...

unsigned size() const

Determine the number of type parameters in this list.

ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for protocol qualifiers are stored aft...

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

Represents a pack expansion of types.

Represents a parameter to a function.

ParsedAttr - Represents a syntactic attribute.

IdentifierLoc * getArgAsIdent(unsigned Arg) const

bool hasParsedType() const

const ParsedType & getTypeArg() const

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this attribute.

bool isArgIdent(unsigned Arg) const

bool isUsedAsTypeAttr() const

AttributeCommonInfo::Kind getKind() const

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

std::pair< IdentifierInfo *, SourceLocation > getPragmaARCCFCodeAuditedInfo() const

The location of the currently-active #pragma clang arc_cf_code_audited begin.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

PseudoObjectExpr - An expression which accesses a pseudo-object l-value.

A (possibly-)qualified type.

QualType withConst() const

QualType getLocalUnqualifiedType() const

Return this type with all of the instance-specific qualifiers removed, but without removing any quali...

bool isNull() const

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

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

bool isConstQualified() const

Determine whether this type is const-qualified.

The collection of all-type qualifiers we support.

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const

Determines if these qualifiers compatibly include another set.

ObjCLifetime getObjCLifetime() const

Qualifiers withoutObjCLifetime() const

std::string getAsString() const

void setObjCLifetime(ObjCLifetime type)

Represents a struct/union/class.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

Scope - A scope is a transient data structure that is used while parsing the program.

bool isAtCatchScope() const

isAtCatchScope - Return true if this scope is @catch.

const Scope * getParent() const

getParent - Return the scope that this is nested in.

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

A generic diagnostic builder for errors which may or may not be deferred.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

bool isCFError(RecordDecl *D)

void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx)

void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx)

Invoked when we must temporarily exit the objective-c container scope for parsing/looking-up C constr...

void handleRuntimeName(Decl *D, const ParsedAttr &AL)

void handleNSObject(Decl *D, const ParsedAttr &AL)

bool isValidOSObjectOutParameter(const Decl *D)

StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)

StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)

FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.

void handleNSErrorDomain(Decl *D, const ParsedAttr &Attr)

void handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL)

QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError=false)

Build an Objective-C type parameter type.

TypeResult actOnObjCTypeArgsAndProtocolQualifiers(Scope *S, SourceLocation Loc, ParsedType BaseType, SourceLocation TypeArgsLAngleLoc, ArrayRef< ParsedType > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< Decl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)

Build a specialized and/or protocol-qualified Objective-C type.

void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)

Check an Objective-C array literal being converted to the given target type.

void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL)

ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)

CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...

IdentifierInfo * getNSErrorIdent()

Retrieve the identifier "NSError".

StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)

ParsedType ActOnObjCInstanceType(SourceLocation Loc)

The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...

void handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL)

void handleIndependentClass(Decl *D, const ParsedAttr &AL)

ObjCInterfaceDecl * NSArrayDecl

The declaration of the Objective-C NSArray class.

RecordDecl * CFError

The struct behind the CFErrorRef pointer.

void handleIBOutlet(Decl *D, const ParsedAttr &AL)

void handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs)

bool isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType)

Determine whether this is an Objective-C writeback conversion, used for parameter passing when perfor...

void CheckObjCCircularContainer(ObjCMessageExpr *Message)

Check whether receiver is mutable ObjC container which attempts to add itself into the container.

void handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL)

StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)

void handleOwnershipAttr(Decl *D, const ParsedAttr &AL)

bool isSignedCharBool(QualType Ty)

void handleBlocksAttr(Decl *D, const ParsedAttr &AL)

StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)

void ActOnObjCContainerFinishDefinition()

TypeResult actOnObjCProtocolQualifierType(SourceLocation lAngleLoc, ArrayRef< Decl * > protocols, ArrayRef< SourceLocation > protocolLocs, SourceLocation rAngleLoc)

Build a an Objective-C protocol-qualified 'id' type where no base type was specified.

StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)

void handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL)

Sema::RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL)

void handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs)

ObjCInterfaceDecl * NSDictionaryDecl

The declaration of the Objective-C NSDictionary class.

bool CheckObjCString(Expr *Arg)

CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...

QualType BuildObjCObjectType(QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, ArrayRef< TypeSourceInfo * > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError, bool Rebuilding)

Build an Objective-C object pointer type.

ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)

void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, Sema::RetainOwnershipKind K, bool IsTemplateInstantiation)

void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)

const DeclContext * getCurObjCLexicalContext() const

void handleDesignatedInitializer(Decl *D, const ParsedAttr &AL)

void handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL)

void handleIBOutletCollection(Decl *D, const ParsedAttr &AL)

ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)

Find the protocol with the given name, if any.

void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)

Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...

bool isCFStringType(QualType T)

void handleDirectAttr(Decl *D, const ParsedAttr &AL)

StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)

void checkRetainCycles(ObjCMessageExpr *msg)

checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.

StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)

bool isNSStringType(QualType T, bool AllowNSAttributedString=false)

bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)

ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection)

void AddCFAuditedAttribute(Decl *D)

AddCFAuditedAttribute - Check whether we're currently within '#pragma clang arc_cf_code_audited' and,...

void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)

Check an Objective-C dictionary literal being converted to the given target type.

void handleBoxable(Decl *D, const ParsedAttr &AL)

bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type)

ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)

LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...

StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)

void handleDirectMembersAttr(Decl *D, const ParsedAttr &AL)

bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)

void handleBridgeAttr(Decl *D, const ParsedAttr &AL)

void handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL)

std::unique_ptr< NSAPI > NSAPIObj

Caches identifiers/selectors for NSFoundation APIs.

void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl)

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

ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)

Package the given type and TSI into a ParsedType.

ExprResult PerformContextuallyConvertToObjCPointer(Expr *From)

PerformContextuallyConvertToObjCPointer - Perform a contextual conversion of the expression From to a...

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

@ LookupObjCProtocolName

Look up the name of an Objective-C protocol.

bool FormatStringHasSArg(const StringLiteral *FExpr)

static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)

Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...

Scope * getScopeForContext(DeclContext *Ctx)

Determines the active Scope associated with the given declaration context.

NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)

Look up a name, looking for a single declaration.

static FormatStringType GetFormatStringType(const FormatAttr *Format)

bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)

isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

ObjCMethodDecl * getCurMethodDecl()

getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Calls Lexer::getLocForEndOfToken()

DeclContext * getCurLexicalContext() const

sema::FunctionScopeInfo * getCurFunction() const

AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)

Check assignment constraints for an assignment of RHS to LHSType.

ExprResult DefaultLvalueConversion(Expr *E)

void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)

Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

@ Compatible

Compatible - the types are compatible according to the standard.

DeclContext * OriginalLexicalContext

Generally null except when we temporarily switch decl contexts, like in.

bool inTemplateInstantiation() const

Determine whether we are currently performing template instantiation.

bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)

void setFunctionHasBranchProtectedScope()

ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)

If the identifier refers to a type name within this scope, return the declaration of that type.

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

Scope * TUScope

Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...

void DiagnoseAutoDeductionFailure(const VarDecl *VDecl, const Expr *Init)

TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)

Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)

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)

bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)

Check if the argument E is a ASCII string literal.

ASTMutationListener * getASTMutationListener() const

ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})

Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...

ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)

void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)

Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteral - This represents a string literal expression, e.g.

StringRef getString() const

TagKind getTagKind() const

Base wrapper for a particular "section" of type source info.

TypeLoc findExplicitQualifierLoc() const

Find a type with the location of an explicit type qualifier.

T getAs() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

T castAs() const

Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

SourceLocation getBeginLoc() const

Get the begin source location.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

bool isBlockPointerType() const

bool isVoidPointerType() const

bool isPointerType() const

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

bool isObjCNSObjectType() const

QualType getPointeeType() const

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

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

AutoType * getContainedAutoType() const

Get the AutoType whose type will be deduced for a variable with an initializer of this type.

bool isSpecificBuiltinType(unsigned K) const

Test for a particular builtin type.

bool isBuiltinType() const

Helper methods to distinguish type categories.

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isCARCBridgableType() const

Determine whether the given type T is a "bridgeable" C type.

bool isObjCIdType() const

bool isObjCObjectType() const

bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const

bool isObjCLifetimeType() const

Returns true if objects of this type have lifetime semantics under ARC.

Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const

Return the implicit lifetime for this type, which must not be dependent.

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isObjCObjectPointerType() const

const T * getAs() const

Member-template getAs'.

bool isObjCRetainableType() const

QualType getUnderlyingType() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

void setType(QualType newType)

Represents a variable declaration or definition.

void setARCPseudoStrong(bool PS)

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Retains information about a function, method, or block that is currently being parsed.

void setHasObjCTry(SourceLocation TryLoc)

SourceLocation FirstSEHTryLoc

First SEH '__try' statement in the current function.

Provides information about an attempted template argument deduction, whose success or failure was des...

const AstTypeMatcher< PointerType > pointerType

Matches pointer types, but does not match Objective-C object pointer types.

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

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

static void checkCollectionLiteralElement(Sema &S, QualType TargetElementType, Expr *Element, unsigned ElementKind)

Check a single element within a collection literal against the target element type.

AttributeDeclKind

These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...

@ ExpectedFunctionMethodOrParameter

@ ExpectedFunctionOrMethod

bool hasDeclarator(const Decl *D)

Return true if the given decl has a declarator that should have been processed by Sema::GetTypeForDec...

static bool isValidSubjectOfOSAttribute(QualType QT)

static void diagnoseRetainCycle(Sema &S, Expr *capturer, RetainCycleOwner &owner)

const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)

static bool isSetterLikeSelector(Selector sel)

Check for a keyword selector that starts with the word 'add' or 'set'.

static Expr * findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner)

Check whether the given argument is a block which captures a variable.

static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner)

Consider whether capturing the given variable can possibly lead to a retain cycle.

static std::optional< int > GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)

@ AANT_ArgumentIdentifier

@ Property

The type of a property.

@ Result

The result type of a method or function.

static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL)

LLVM_READONLY bool isLowercase(unsigned char c)

Return true if this character is a lowercase ASCII letter: [a-z].

@ Struct

The "struct" keyword.

static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, ArrayRef< TypeSourceInfo * > typeArgs, SourceRange typeArgsRange, bool failOnError, bool rebuilding)

Apply Objective-C type arguments to the given type.

static bool isValidSubjectOfNSAttribute(QualType QT)

static bool isValidSubjectOfCFAttribute(QualType QT)

static std::optional< int > GetNSSetArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)

static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, bool DiagnoseFailure)

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

const FunctionProtoType * T

static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT)

bool hasFunctionProto(const Decl *D)

hasFunctionProto - Return true if the given decl has a argument information.

static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner)

unsigned getFunctionOrMethodNumParams(const Decl *D)

getFunctionOrMethodNumParams - Return number of function or method parameters.

TemplateDeductionResult

Describes the result of template argument deduction.

@ Success

Template argument deduction was successful.

@ AlreadyDiagnosed

Some error which was already diagnosed.

U cast(CodeGen::Address addr)

static std::optional< int > GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message)

Wraps an identifier and optional source location for the identifier.