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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

40

41using namespace clang;

42using namespace sema;

43

44namespace {

45

46 struct Rebuilder {

48 unsigned MSPropertySubscriptCount;

49 typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy;

50 const SpecificRebuilderRefTy &SpecificCallback;

51 Rebuilder(Sema &S, const SpecificRebuilderRefTy &SpecificCallback)

52 : S(S), MSPropertySubscriptCount(0),

53 SpecificCallback(SpecificCallback) {}

54

56

57

59 return refExpr;

60

66 }

72 }

76

78 SpecificCallback(refExpr->getBaseExpr(), 0),

83 }

86

88 SpecificCallback(refExpr->getBaseExpr(), 0),

92 }

94 assert(refExpr->getBase());

95 assert(refExpr->getIdx());

96

97 auto *NewBase = rebuild(refExpr->getBase());

98 ++MSPropertySubscriptCount;

100 NewBase,

101 SpecificCallback(refExpr->getIdx(), MSPropertySubscriptCount),

104 }

105

107

108 if (auto *PRE = dyn_cast(e))

109 return rebuildObjCPropertyRefExpr(PRE);

110 if (auto *SRE = dyn_cast(e))

111 return rebuildObjCSubscriptRefExpr(SRE);

112 if (auto *MSPRE = dyn_cast(e))

113 return rebuildMSPropertyRefExpr(MSPRE);

114 if (auto *MSPSE = dyn_cast(e))

115 return rebuildMSPropertySubscriptExpr(MSPSE);

116

117

118

119

120 if (ParenExpr *parens = dyn_cast(e)) {

121 e = rebuild(parens->getSubExpr());

123 parens->getRParen(),

124 e);

125 }

126

127 if (UnaryOperator *uop = dyn_cast(e)) {

128 assert(uop->getOpcode() == UO_Extension);

129 e = rebuild(uop->getSubExpr());

131 S.Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(),

132 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(),

134 }

135

137 assert(!gse->isResultDependent());

138 unsigned resultIndex = gse->getResultIndex();

139 unsigned numAssocs = gse->getNumAssocs();

140

143 assocExprs.reserve(numAssocs);

144 assocTypes.reserve(numAssocs);

145

147 gse->associations()) {

148 Expr *assocExpr = assoc.getAssociationExpr();

149 if (assoc.isSelected())

150 assocExpr = rebuild(assocExpr);

151 assocExprs.push_back(assocExpr);

152 assocTypes.push_back(assoc.getTypeSourceInfo());

153 }

154

155 if (gse->isExprPredicate())

157 S.Context, gse->getGenericLoc(), gse->getControllingExpr(),

158 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),

159 gse->containsUnexpandedParameterPack(), resultIndex);

161 S.Context, gse->getGenericLoc(), gse->getControllingType(),

162 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),

163 gse->containsUnexpandedParameterPack(), resultIndex);

164 }

165

166 if (ChooseExpr *ce = dyn_cast(e)) {

167 assert(!ce->isConditionDependent());

168

169 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();

170 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;

171 rebuiltExpr = rebuild(rebuiltExpr);

172

174 ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS,

176 rebuiltExpr->getObjectKind(), ce->getRParenLoc(),

177 ce->isConditionTrue());

178 }

179

180 llvm_unreachable("bad expression to rebuild!");

181 }

182 };

183

184 class PseudoOpBuilder {

185 public:

187 unsigned ResultIndex;

189 bool IsUnique;

191

194 GenericLoc(genericLoc), IsUnique(IsUnique) {}

195

196 virtual ~PseudoOpBuilder() {}

197

198

199 void addSemanticExpr(Expr *semantic) {

200 Semantics.push_back(semantic);

201 }

202

203

204 void addResultSemanticExpr(Expr *resultExpr) {

206 ResultIndex = Semantics.size();

207 Semantics.push_back(resultExpr);

208

209 if (auto *OVE = dyn_cast(Semantics.back()))

210 OVE->setIsUnique(false);

211 }

212

221

223

226

227 void setResultToLastSemantic() {

229 ResultIndex = Semantics.size() - 1;

230

231 if (auto *OVE = dyn_cast(Semantics.back()))

232 OVE->setIsUnique(false);

233 }

234

235

236 static bool CanCaptureValue(Expr *exp) {

237 if (exp->isGLValue())

238 return true;

242

244 return ClassDecl->isTriviallyCopyable();

245 return true;

246 }

247

248 virtual Expr *rebuildAndCaptureObject(Expr *) = 0;

251 bool captureSetValueAsResult) = 0;

252

253

254

255

256

257

258

259

260

261

262

263

264

265 virtual bool captureSetValueAsResult() const { return true; }

266 };

267

268

269 class ObjCPropertyOpBuilder : public PseudoOpBuilder {

274

278

279 public:

281 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),

282 RefExpr(refExpr), SyntacticRefExpr(nullptr),

283 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {

284 }

285

294

295 bool tryBuildGetOfReference(Expr *op, ExprResult &result);

296 bool findSetter(bool warn=true);

297 bool findGetter();

298 void DiagnoseUnsupportedPropertyUse();

299

300 Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;

304

305 bool isWeakProperty() const;

306 };

307

308

309 class ObjCSubscriptOpBuilder : public PseudoOpBuilder {

314 Selector AtIndexGetterSelector;

315

317 Selector AtIndexSetterSelector;

318

319 public:

321 : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),

322 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),

323 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}

324

330 Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;

331

332 bool findAtIndexGetter();

333 bool findAtIndexSetter();

334

337 };

338

339 class MSPropertyOpBuilder : public PseudoOpBuilder {

343

345

346 public:

348 : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),

349 RefExpr(refExpr), InstanceBase(nullptr) {}

351 : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),

352 InstanceBase(nullptr) {

353 RefExpr = getBaseMSProperty(refExpr);

354 }

355

356 Expr *rebuildAndCaptureObject(Expr *) override;

359 bool captureSetValueAsResult() const override { return false; }

360 };

361}

362

363

365

369 e);

370 if (IsUnique)

372

373

374 addSemanticExpr(captured);

375 return captured;

376}

377

378

379

380

381

382

383

386

387

388

389 if (!isa(e)) {

391 setResultToLastSemantic();

392 return cap;

393 }

394

395

396

397 unsigned index = 0;

398 for (;; ++index) {

399 assert(index < Semantics.size() &&

400 "captured expression not found in semantics!");

401 if (e == Semantics[index]) break;

402 }

403 ResultIndex = index;

404

405 cast(e)->setIsUnique(false);

406 return cast(e);

407}

408

409

410ExprResult PseudoOpBuilder::complete(Expr *syntactic) {

412 Semantics, ResultIndex);

413}

414

415

416ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {

417 Expr *syntacticBase = rebuildAndCaptureObject(op);

418

421 addResultSemanticExpr(getExpr.get());

422

423 return complete(syntacticBase);

424}

425

426

427

429PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,

433

434 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);

436

437

438

439

440

441

442

443 Expr *semanticRHS = capturedRHS;

445 semanticRHS = RHS;

446 Semantics.pop_back();

447 }

448

449 Expr *syntactic;

450

452 if (opcode == BO_Assign) {

453 result = semanticRHS;

455 opcode, capturedRHS->getType(),

458

459 } else {

462

463

466 result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS);

468

470 S.Context, syntacticLHS, capturedRHS, opcode, result.get()->getType(),

474 }

475

476

477

478 result = buildSet(result.get(), opcLoc, captureSetValueAsResult());

480 addSemanticExpr(result.get());

483 setResultToLastSemantic();

484

485 return complete(syntactic);

486}

487

488

489

495

496 Expr *syntacticOp = rebuildAndCaptureObject(op);

497

498

501

503

504

507 result = capture(result.get());

508 setResultToLastSemantic();

509 }

510

511

514 GenericLoc);

515

517 result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);

518 } else {

519 result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);

520 }

522

523

524

526 captureSetValueAsResult());

528 addSemanticExpr(result.get());

532 setResultToLastSemantic();

533

540 : false,

542 return complete(syntactic);

543}

544

545

546

547

548

549

550

551

557

558

561

562

567 false);

568 }

569

571 }

572

577

579 false);

580 }

581

585}

586

587bool ObjCPropertyOpBuilder::isWeakProperty() const {

589 if (RefExpr->isExplicitProperty()) {

590 const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();

592 return true;

593

595 } else if (Getter) {

597 } else {

598 return false;

599 }

600

602}

603

604bool ObjCPropertyOpBuilder::findGetter() {

605 if (Getter) return true;

606

607

608 if (RefExpr->isImplicitProperty()) {

609 if ((Getter = RefExpr->getImplicitPropertyGetter())) {

610 GetterSelector = Getter->getSelector();

611 return true;

612 }

613 else {

614

615 ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter();

616 assert(setter && "both setter and getter are null - cannot happen");

621 GetterSelector =

623 return false;

624 }

625 }

626

629 return (Getter != nullptr);

630}

631

632

633

634

635

636bool ObjCPropertyOpBuilder::findSetter(bool warn) {

637

638 if (RefExpr->isImplicitProperty()) {

639 if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {

640 Setter = setter;

642 return true;

643 } else {

644 const IdentifierInfo *getterName = RefExpr->getImplicitPropertyGetter()

645 ->getSelector()

646 .getIdentifierInfoForSlot(0);

647 SetterSelector =

650 getterName);

651 return false;

652 }

653 }

654

655

658

659

664 dyn_cast(setter->getDeclContext())) {

665 StringRef thisPropertyName = prop->getName();

666

667 char front = thisPropertyName.front();

670 PropertyName[0] = front;

673 if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(

675 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {

676 S.Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)

677 << prop << prop1 << setter->getSelector();

678 S.Diag(prop->getLocation(), diag::note_property_declare);

679 S.Diag(prop1->getLocation(), diag::note_property_declare);

680 }

681 }

682 Setter = setter;

683 return true;

684 }

685

686

687

688

689

690

691 return false;

692}

693

694void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {

698 if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {

699 S.Diag(RefExpr->getLocation(),

700 diag::err_property_function_in_objc_container);

701 S.Diag(prop->getLocation(), diag::note_property_declare);

702 }

703 }

704}

705

706

707Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {

708 assert(InstanceReceiver == nullptr);

709

710

711

712 if (RefExpr->isObjectReceiver()) {

713 InstanceReceiver = capture(RefExpr->getBase());

714 syntacticBase = Rebuilder(S, [=](Expr *, unsigned) -> Expr * {

715 return InstanceReceiver;

716 }).rebuild(syntacticBase);

717 }

718

720 refE = dyn_cast(syntacticBase->IgnoreParens()))

721 SyntacticRefExpr = refE;

722

723 return syntacticBase;

724}

725

726

727ExprResult ObjCPropertyOpBuilder::buildGet() {

728 findGetter();

729 if (!Getter) {

730 DiagnoseUnsupportedPropertyUse();

732 }

733

734 if (SyntacticRefExpr)

735 SyntacticRefExpr->setIsMessagingGetter();

736

737 QualType receiverType = RefExpr->getReceiverType(S.Context);

738 if (!Getter->isImplicit())

740

742 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||

743 RefExpr->isObjectReceiver()) {

744 assert(InstanceReceiver || RefExpr->isSuperReceiver());

746 InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(),

747 Getter, {});

748 } else {

750 receiverType, RefExpr->isSuperReceiver(), GenericLoc,

751 Getter->getSelector(), Getter, {});

752 }

753 return msg;

754}

755

756

757

758

759

761 bool captureSetValueAsResult) {

762 if (!findSetter(false)) {

763 DiagnoseUnsupportedPropertyUse();

765 }

766

767 if (SyntacticRefExpr)

768 SyntacticRefExpr->setIsMessagingSetter();

769

770 QualType receiverType = RefExpr->getReceiverType(S.Context);

771

772

773

774

776 QualType paramType = (*Setter->param_begin())->getType()

778 receiverType,

779 Setter->getDeclContext(),

780 ObjCSubstitutionContext::Parameter);

788 AssignmentAction::Assigning))

790

791 op = opResult.get();

792 assert(op && "successful assignment left argument invalid?");

793 }

794 }

795

796

797 Expr *args[] = { op };

798

799

801 if (!Setter->isImplicit())

803 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||

804 RefExpr->isObjectReceiver()) {

806 GenericLoc, SetterSelector,

808 } else {

810 receiverType, RefExpr->isSuperReceiver(), GenericLoc, SetterSelector,

812 }

813

814 if (!msg.isInvalid() && captureSetValueAsResult) {

818 if (CanCaptureValue(arg))

819 msgExpr->setArg(0, captureValueAsResult(arg));

820 }

821

822 return msg;

823}

824

825

826ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {

827

828

829 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {

830 S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)

831 << RefExpr->getSourceRange();

833 }

834

835 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);

837

838 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())

840 Getter, RefExpr->getLocation());

841

842

843

844 if (RefExpr->isExplicitProperty() && result.get()->isPRValue()) {

845 QualType receiverType = RefExpr->getReceiverType(S.Context);

846 QualType propType = RefExpr->getExplicitProperty()

847 ->getUsageType(receiverType);

851 if (!ptr->isObjCIdType())

853 }

854 }

856 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,

857 RefExpr->getLocation()))

859 }

860

861 return result;

862}

863

864

865

866

867

868bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,

870 if (!S.getLangOpts().CPlusPlus) return false;

871

872 findGetter();

873 if (!Getter) {

874

875

877 return true;

878 }

879

880

881 QualType resultType = Getter->getReturnType();

883

884 result = buildRValueOperation(op);

885 return true;

886}

887

888

890ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,

895

896

897

898 if (!findSetter()) {

900 if (tryBuildGetOfReference(LHS, result)) {

902 return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);

903 }

904

905

906 S.Diag(opcLoc, diag::err_nosetter_property_assignment)

907 << unsigned(RefExpr->isImplicitProperty())

908 << SetterSelector

911 }

912

913

914

915

916 if (opcode != BO_Assign && !findGetter()) {

917 S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)

920 }

921

923 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);

925

926

927 if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {

930 }

931

932 return result;

933}

934

935

937ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,

940

941

942 if (!findSetter()) {

944 if (tryBuildGetOfReference(op, result)) {

947 }

948

949

950 S.Diag(opcLoc, diag::err_nosetter_property_incdec)

951 << unsigned(RefExpr->isImplicitProperty())

953 << SetterSelector

956 }

957

958

959

960

961 if (!findGetter()) {

962 assert(RefExpr->isImplicitProperty());

963 S.Diag(opcLoc, diag::err_nogetter_property_incdec)

965 << GetterSelector

968 }

969

970 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);

971}

972

973ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {

975 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,

978 SyntacticRefExpr->isMessagingGetter());

979

980 return PseudoOpBuilder::complete(SyntacticForm);

981}

982

983

984

985

986

987

988

989

990ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {

991 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);

993 return result;

994}

995

996

998ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,

1003

1004 if (!findAtIndexSetter())

1006

1007

1008 if (opcode != BO_Assign && !findAtIndexGetter())

1010

1012 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);

1014

1015

1016 if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {

1019 }

1020

1021 return result;

1022}

1023

1024

1025Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {

1026 assert(InstanceBase == nullptr);

1027

1028

1029

1030 InstanceBase = capture(RefExpr->getBaseExpr());

1031 InstanceKey = capture(RefExpr->getKeyExpr());

1032

1033 syntacticBase =

1034 Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * {

1035 switch (Idx) {

1036 case 0:

1037 return InstanceBase;

1038 case 1:

1039 return InstanceKey;

1040 default:

1041 llvm_unreachable("Unexpected index for ObjCSubscriptExpr");

1042 }

1043 }).rebuild(syntacticBase);

1044

1045 return syntacticBase;

1046}

1047

1048

1049

1051 Expr *Key) {

1052 if (ContainerT.isNull())

1053 return;

1054

1055

1060 GetterSelector, ContainerT, true );

1061 if (!Getter)

1062 return;

1065 CheckedConversionKind::Implicit);

1066}

1067

1068bool ObjCSubscriptOpBuilder::findAtIndexGetter() {

1069 if (AtIndexGetter)

1070 return true;

1071

1072 Expr *BaseExpr = RefExpr->getBaseExpr();

1074

1079 }

1085 RefExpr->getKeyExpr());

1086 return false;

1087 }

1089

1090 if (ResultType.isNull()) {

1091 S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)

1092 << BaseExpr->getType() << arrayRef;

1093 return false;

1094 }

1095 if (!arrayRef) {

1096

1097

1101 }

1102 else {

1103

1106

1108 }

1109

1111 AtIndexGetterSelector, ResultType, true );

1112

1113 if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {

1118 false ,

1119 false,

1120 false,

1121 true, false,

1122 ObjCImplementationControl::Required, false);

1129 nullptr,

1131 nullptr);

1132 AtIndexGetter->setMethodParams(S.Context, Argument, {});

1133 }

1134

1135 if (!AtIndexGetter) {

1137 S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)

1138 << BaseExpr->getType() << 0 << arrayRef;

1139 return false;

1140 }

1142 AtIndexGetterSelector, RefExpr->getSourceRange(), true);

1143 }

1144

1145 if (AtIndexGetter) {

1146 QualType T = AtIndexGetter->parameters()[0]->getType();

1149 S.Diag(RefExpr->getKeyExpr()->getExprLoc(),

1150 arrayRef ? diag::err_objc_subscript_index_type

1151 : diag::err_objc_subscript_key_type) << T;

1152 S.Diag(AtIndexGetter->parameters()[0]->getLocation(),

1153 diag::note_parameter_type) << T;

1154 return false;

1155 }

1156 QualType R = AtIndexGetter->getReturnType();

1158 S.Diag(RefExpr->getKeyExpr()->getExprLoc(),

1159 diag::err_objc_indexing_method_result_type) << R << arrayRef;

1160 S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<

1161 AtIndexGetter->getDeclName();

1162 }

1163 }

1164 return true;

1165}

1166

1167bool ObjCSubscriptOpBuilder::findAtIndexSetter() {

1168 if (AtIndexSetter)

1169 return true;

1170

1171 Expr *BaseExpr = RefExpr->getBaseExpr();

1173

1178 }

1179

1185 RefExpr->getKeyExpr());

1186 return false;

1187 }

1189

1190 if (ResultType.isNull()) {

1191 S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)

1192 << BaseExpr->getType() << arrayRef;

1193 return false;

1194 }

1195

1196 if (!arrayRef) {

1197

1198

1203 }

1204 else {

1205

1210 }

1212 AtIndexSetterSelector, ResultType, true );

1213

1214 if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {

1220 true , false ,

1221 false,

1222 false,

1223 true, false,

1224 ObjCImplementationControl::Required, false);

1230 nullptr,

1232 nullptr);

1233 Params.push_back(object);

1240 nullptr,

1242 nullptr);

1243 Params.push_back(key);

1244 AtIndexSetter->setMethodParams(S.Context, Params, {});

1245 }

1246

1247 if (!AtIndexSetter) {

1250 diag::err_objc_subscript_method_not_found)

1251 << BaseExpr->getType() << 1 << arrayRef;

1252 return false;

1253 }

1255 AtIndexSetterSelector, RefExpr->getSourceRange(), true);

1256 }

1257

1258 bool err = false;

1259 if (AtIndexSetter && arrayRef) {

1260 QualType T = AtIndexSetter->parameters()[1]->getType();

1262 S.Diag(RefExpr->getKeyExpr()->getExprLoc(),

1263 diag::err_objc_subscript_index_type) << T;

1264 S.Diag(AtIndexSetter->parameters()[1]->getLocation(),

1265 diag::note_parameter_type) << T;

1266 err = true;

1267 }

1268 T = AtIndexSetter->parameters()[0]->getType();

1270 S.Diag(RefExpr->getBaseExpr()->getExprLoc(),

1271 diag::err_objc_subscript_object_type) << T << arrayRef;

1272 S.Diag(AtIndexSetter->parameters()[0]->getLocation(),

1273 diag::note_parameter_type) << T;

1274 err = true;

1275 }

1276 }

1277 else if (AtIndexSetter && !arrayRef)

1278 for (unsigned i=0; i <2; i++) {

1279 QualType T = AtIndexSetter->parameters()[i]->getType();

1281 if (i == 1)

1282 S.Diag(RefExpr->getKeyExpr()->getExprLoc(),

1283 diag::err_objc_subscript_key_type) << T;

1284 else

1285 S.Diag(RefExpr->getBaseExpr()->getExprLoc(),

1286 diag::err_objc_subscript_dic_object_type) << T;

1287 S.Diag(AtIndexSetter->parameters()[i]->getLocation(),

1288 diag::note_parameter_type) << T;

1289 err = true;

1290 }

1291 }

1292

1293 return !err;

1294}

1295

1296

1297

1298ExprResult ObjCSubscriptOpBuilder::buildGet() {

1299 if (!findAtIndexGetter())

1301

1302 QualType receiverType = InstanceBase->getType();

1303

1304

1306 Expr *Index = InstanceKey;

1307

1308

1309 Expr *args[] = { Index };

1310 assert(InstanceBase);

1311 if (AtIndexGetter)

1314 InstanceBase, receiverType, GenericLoc, AtIndexGetterSelector,

1316 return msg;

1317}

1318

1319

1320

1321

1322

1323

1325 bool captureSetValueAsResult) {

1326 if (!findAtIndexSetter())

1328 if (AtIndexSetter)

1330 QualType receiverType = InstanceBase->getType();

1331 Expr *Index = InstanceKey;

1332

1333

1334 Expr *args[] = { op, Index };

1335

1336

1338 InstanceBase, receiverType, GenericLoc, AtIndexSetterSelector,

1340

1341 if (!msg.isInvalid() && captureSetValueAsResult) {

1345 if (CanCaptureValue(arg))

1346 msgExpr->setArg(0, captureValueAsResult(arg));

1347 }

1348

1349 return msg;

1350}

1351

1352

1353

1354

1355

1358 CallArgs.insert(CallArgs.begin(), E->getIdx());

1360 while (auto *MSPropSubscript = dyn_cast(Base)) {

1361 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());

1362 Base = MSPropSubscript->getBase()->IgnoreParens();

1363 }

1364 return cast(Base);

1365}

1366

1367Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {

1368 InstanceBase = capture(RefExpr->getBaseExpr());

1369 for (Expr *&Arg : CallArgs)

1370 Arg = capture(Arg);

1371 syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * {

1372 switch (Idx) {

1373 case 0:

1374 return InstanceBase;

1375 default:

1376 assert(Idx <= CallArgs.size());

1377 return CallArgs[Idx - 1];

1378 }

1379 }).rebuild(syntacticBase);

1380

1381 return syntacticBase;

1382}

1383

1384ExprResult MSPropertyOpBuilder::buildGet() {

1385 if (!RefExpr->getPropertyDecl()->hasGetter()) {

1386 S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)

1387 << 0 << RefExpr->getPropertyDecl();

1389 }

1390

1392 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();

1393 GetterName.setIdentifier(II, RefExpr->getMemberLoc());

1395 SS.Adopt(RefExpr->getQualifierLoc());

1398 RefExpr->isArrow() ? tok::arrow : tok::period, SS,

1401 S.Diag(RefExpr->getMemberLoc(),

1402 diag::err_cannot_find_suitable_accessor) << 0

1403 << RefExpr->getPropertyDecl();

1405 }

1406

1409 RefExpr->getSourceRange().getEnd());

1410}

1411

1413 bool captureSetValueAsResult) {

1414 if (!RefExpr->getPropertyDecl()->hasSetter()) {

1415 S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)

1416 << 1 << RefExpr->getPropertyDecl();

1418 }

1419

1421 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();

1422 SetterName.setIdentifier(II, RefExpr->getMemberLoc());

1424 SS.Adopt(RefExpr->getQualifierLoc());

1427 RefExpr->isArrow() ? tok::arrow : tok::period, SS,

1430 S.Diag(RefExpr->getMemberLoc(),

1431 diag::err_cannot_find_suitable_accessor) << 1

1432 << RefExpr->getPropertyDecl();

1434 }

1435

1437 ArgExprs.append(CallArgs.begin(), CallArgs.end());

1438 ArgExprs.push_back(op);

1442}

1443

1444

1445

1446

1447

1451 = dyn_cast(opaqueRef)) {

1452 ObjCPropertyOpBuilder builder(SemaRef, refExpr, true);

1453 return builder.buildRValueOperation(E);

1454 }

1456 = dyn_cast(opaqueRef)) {

1457 ObjCSubscriptOpBuilder builder(SemaRef, refExpr, true);

1458 return builder.buildRValueOperation(E);

1460 = dyn_cast(opaqueRef)) {

1461 MSPropertyOpBuilder builder(SemaRef, refExpr, true);

1462 return builder.buildRValueOperation(E);

1464 dyn_cast(opaqueRef)) {

1465 MSPropertyOpBuilder Builder(SemaRef, RefExpr, true);

1466 return Builder.buildRValueOperation(E);

1467 } else {

1468 llvm_unreachable("unknown pseudo-object kind!");

1469 }

1470}

1471

1472

1475

1480

1484 = dyn_cast(opaqueRef)) {

1485 ObjCPropertyOpBuilder builder(SemaRef, refExpr, false);

1486 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);

1487 } else if (isa(opaqueRef)) {

1488 Diag(opcLoc, diag::err_illegal_container_subscripting_op);

1491 = dyn_cast(opaqueRef)) {

1492 MSPropertyOpBuilder builder(SemaRef, refExpr, false);

1493 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);

1495 = dyn_cast(opaqueRef)) {

1496 MSPropertyOpBuilder Builder(SemaRef, RefExpr, false);

1497 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);

1498 } else {

1499 llvm_unreachable("unknown pseudo-object kind!");

1500 }

1501}

1502

1506

1511

1512

1516 RHS = result.get();

1517 }

1518

1519 bool IsSimpleAssign = opcode == BO_Assign;

1522 = dyn_cast(opaqueRef)) {

1523 ObjCPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);

1524 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);

1526 = dyn_cast(opaqueRef)) {

1527 ObjCSubscriptOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);

1528 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);

1530 = dyn_cast(opaqueRef)) {

1531 MSPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);

1532 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);

1534 = dyn_cast(opaqueRef)) {

1535 MSPropertyOpBuilder Builder(SemaRef, RefExpr, IsSimpleAssign);

1536 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);

1537 } else {

1538 llvm_unreachable("unknown pseudo-object kind!");

1539 }

1540}

1541

1542

1543

1544

1546 return Rebuilder(S,

1547 [=](Expr *E, unsigned) -> Expr * {

1548 return cast(E)->getSourceExpr();

1549 })

1550 .rebuild(E);

1551}

1552

1553

1554

1555

1556

1557

1558

1560 Expr *syntax = E->getSyntacticForm();

1561 if (UnaryOperator *uop = dyn_cast(syntax)) {

1565 uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(),

1568 = dyn_cast(syntax)) {

1570 Expr *rhs = cast(cop->getRHS())->getSourceExpr();

1573 cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),

1575 cop->getComputationResultType());

1576

1577 } else if (BinaryOperator *bop = dyn_cast(syntax)) {

1579 Expr *rhs = cast(bop->getRHS())->getSourceExpr();

1581 bop->getType(), bop->getValueKind(),

1582 bop->getObjectKind(), bop->getOperatorLoc(),

1584

1585 } else if (isa(syntax)) {

1586 return syntax;

1587 } else {

1590 }

1591}

1592

Defines the clang::Expr interface and subclasses for C++ expressions.

Defines the clang::Preprocessor interface.

This file declares semantic analysis for Objective-C.

static ObjCMethodDecl * LookupMethodInReceiverType(Sema &S, Selector sel, const ObjCPropertyRefExpr *PRE)

Look up a method in the receiver type of an Objective-C property reference.

static Expr * stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E)

Given a pseudo-object reference, rebuild it without the opaque values.

static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, Expr *Key)

CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF objects used as dictionary ...

This file declares semantic analysis for expressions involving.

TranslationUnitDecl * getTranslationUnitDecl() const

QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const

getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.

SelectorTable & Selectors

CanQualType UnsignedLongTy

QualType getObjCIdType() const

Represents the Objective-CC id type.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

A builtin binary operation expression such as "x + y" or "x <= y".

static Opcode getOpForCompoundAssignment(Opcode Opc)

static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)

bool isAssignmentOp() const

Represents a C++ struct/union/class.

Represents a C++ nested-name-specifier or a global scope specifier.

void Adopt(NestedNameSpecifierLoc Other)

Adopt an existing nested-name-specifier (with source-range information).

ChooseExpr - GNU builtin-in function __builtin_choose_expr.

CompoundAssignOperator - For compound assignments (e.g.

static CompoundAssignOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures, QualType CompLHSType=QualType(), QualType CompResultType=QualType())

Decl * getNonClosureAncestor()

Find the nearest non-closure ancestor of this context, i.e.

bool isObjCContainer() const

Decl::Kind getDeclKind() const

SourceLocation getLocation() const

DeclContext * getDeclContext()

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

This represents one expression.

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

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.

ExprObjectKind getObjectKind() const

getObjectKind - The object kind that this expression produces.

SourceLocation getExprLoc() const LLVM_READONLY

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

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

QualType getReturnType() const

Represents a C11 generic selection.

AssociationTy< false > Association

static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)

Create a non-result-dependent generic selection expression accepting an expression predicate.

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

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)

Returns a new integer literal with value 'V' and type 'type'.

A member reference to an MSPropertyDecl.

NestedNameSpecifierLoc getQualifierLoc() const

MSPropertyDecl * getPropertyDecl() const

Expr * getBaseExpr() const

SourceLocation getMemberLoc() const

MS property subscript expression.

SourceLocation getRBracketLoc() const

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

Represents an ObjC class declaration.

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

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

void setArg(unsigned Arg, Expr *ArgExpr)

setArg - Set the specified argument.

ObjCMethodDecl - Represents an instance or class method declaration.

ArrayRef< ParmVarDecl * > parameters() const

bool isPropertyAccessor() const

static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)

Selector getSelector() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

QualType getPointeeType() const

Gets the type pointed to by this ObjC pointer.

bool isObjCClassType() const

True if this is equivalent to the 'Class' type, i.e.

Represents one property declaration in an Objective-C interface.

ObjCPropertyQueryKind getQueryKind() const

Selector getSetterName() const

Selector getGetterName() const

ObjCPropertyAttribute::Kind getPropertyAttributes() const

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

ObjCPropertyDecl * getExplicitProperty() const

ObjCMethodDecl * getImplicitPropertyGetter() const

const Expr * getBase() const

bool isObjectReceiver() const

bool isExplicitProperty() const

QualType getSuperReceiverType() const

ObjCMethodDecl * getImplicitPropertySetter() const

ObjCInterfaceDecl * getClassReceiver() const

SourceLocation getLocation() const

bool isClassReceiver() const

bool isSuperReceiver() const

ObjCSubscriptRefExpr - used for array and dictionary subscripting.

Expr * getKeyExpr() const

Expr * getBaseExpr() const

ObjCMethodDecl * getAtIndexMethodDecl() const

SourceLocation getRBracket() const

ObjCMethodDecl * setAtIndexMethodDecl() const

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

ParenExpr - This represents a parenthesized expression, e.g.

Represents a parameter to a function.

static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)

IdentifierTable & getIdentifierTable()

SelectorTable & getSelectorTable()

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

static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)

A (possibly-)qualified type.

bool isNull() const

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

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType substObjCMemberType(QualType objectType, const DeclContext *dc, ObjCSubstitutionContext context) const

Substitute type arguments from an object type for the Objective-C type parameters used in the subject...

@ OCL_Weak

Reading or writing from this object requires a barrier call.

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

static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)

Return the default setter selector for the given identifier.

Selector getNullarySelector(const IdentifierInfo *ID)

Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)

Can create any sort of selector.

Smart pointer class that efficiently represents Objective-C method names.

const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const

Retrieve the identifier at a given position in the selector.

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

Emit a diagnostic.

bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)

ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD)

Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...

ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)

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

ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)

LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.

ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)

LookupMethodInType - Look up a method in an ObjCObjectType.

ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)

ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)

void checkRetainCycles(ObjCMessageExpr *msg)

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

bool isSelfExpr(Expr *RExpr)

Private Helper predicate to check for 'self'.

SemaPseudoObject(Sema &S)

ExprResult checkAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)

ExprResult checkIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op)

Check an increment or decrement of a pseudo-object expression.

Expr * recreateSyntacticForm(PseudoObjectExpr *E)

Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...

ExprResult checkRValue(Expr *E)

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

Scope * getCurScope() const

Retrieve the parser's current scope.

FPOptionsOverride CurFPFeatureOverrides()

ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)

ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.

const LangOptions & getLangOpts() const

ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)

BuildCallExpr - Handle a call to Fn with the specified array of arguments.

DeclContext * getCurLexicalContext() const

sema::FunctionScopeInfo * getCurFunction() const

void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)

checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...

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 ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)

The main callback when the parser finds something like expression .

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

bool isUnevaluatedContext() const

Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.

AssignConvertType

AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)

Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.

DiagnosticsEngine & Diags

bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, Expr *SrcExpr, AssignmentAction Action, bool *Complained=nullptr)

DiagnoseAssignmentResult - Emit a diagnostic, if required, for the assignment conversion type specifi...

ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)

Encodes a location in the source.

SourceLocation getEnd() const

SourceLocation getBegin() const

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

A container of type source information.

CXXRecordDecl * getAsCXXRecordDecl() const

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

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

Determine whether this type is an integral or enumeration type.

bool isNonOverloadPlaceholderType() const

Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.

bool isLValueReferenceType() const

bool isDependentType() const

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

bool isObjCIdType() const

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

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

bool isDecrementOp() const

static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)

bool isIncrementDecrementOp() const

bool isIncrementOp() const

Represents a C++ unqualified-id that has been parsed.

void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)

Specify that this unqualified-id was parsed as an identifier.

void recordUseOfWeak(const ExprT *E, bool IsRead=true)

Record that a weak object was accessed.

void markSafeWeakUse(const Expr *E)

Record that a given expression is a "safe" access of a weak object (e.g.

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

LLVM_READONLY char toLowercase(char c)

Converts the given ASCII character to its lowercase equivalent.

@ OK_Ordinary

An ordinary object is located at an address in memory.

LLVM_READONLY bool isLowercase(unsigned char c)

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

LLVM_READONLY char toUppercase(char c)

Converts the given ASCII character to its uppercase equivalent.

@ VK_PRValue

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

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

const FunctionProtoType * T

MutableArrayRef< Expr * > MultiExprArg

__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)