39#include "llvm/ADT/SmallString.h"
48 unsigned MSPropertySubscriptCount;
50 const SpecificRebuilderRefTy &SpecificCallback;
51 Rebuilder(
Sema &S,
const SpecificRebuilderRefTy &SpecificCallback)
52 : S(S), MSPropertySubscriptCount(0),
53 SpecificCallback(SpecificCallback) {}
97 auto *NewBase = rebuild(refExpr->
getBase());
98 ++MSPropertySubscriptCount;
101 SpecificCallback(refExpr->
getIdx(), MSPropertySubscriptCount),
108 if (
auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e))
109 return rebuildObjCPropertyRefExpr(PRE);
110 if (
auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e))
111 return rebuildObjCSubscriptRefExpr(SRE);
112 if (
auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e))
113 return rebuildMSPropertyRefExpr(MSPRE);
114 if (
auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e))
115 return rebuildMSPropertySubscriptExpr(MSPSE);
120 if (
ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
121 e = rebuild(parens->getSubExpr());
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(),
137 assert(!gse->isResultDependent());
138 unsigned resultIndex = gse->getResultIndex();
139 unsigned numAssocs = gse->getNumAssocs();
143 assocExprs.reserve(numAssocs);
144 assocTypes.reserve(numAssocs);
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());
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);
166 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
167 assert(!ce->isConditionDependent());
169 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
170 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
171 rebuiltExpr = rebuild(rebuiltExpr);
174 ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS,
177 ce->isConditionTrue());
180 llvm_unreachable(
"bad expression to rebuild!");
184 class PseudoOpBuilder {
187 unsigned ResultIndex;
194 GenericLoc(genericLoc), IsUnique(IsUnique) {}
196 virtual ~PseudoOpBuilder() {}
199 void addSemanticExpr(
Expr *semantic) {
200 Semantics.push_back(semantic);
204 void addResultSemanticExpr(
Expr *resultExpr) {
206 ResultIndex = Semantics.size();
207 Semantics.push_back(resultExpr);
209 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
210 OVE->setIsUnique(
false);
227 void setResultToLastSemantic() {
229 ResultIndex = Semantics.size() - 1;
231 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
232 OVE->setIsUnique(
false);
236 static bool CanCaptureValue(
Expr *
exp) {
237 if (
exp->isGLValue())
244 return ClassDecl->isTriviallyCopyable();
248 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
251 bool captureSetValueAsResult) = 0;
265 virtual bool captureSetValueAsResult()
const {
return true; }
269 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
281 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
282 RefExpr(refExpr), SyntacticRefExpr(nullptr),
283 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
296 bool findSetter(
bool warn=
true);
298 void DiagnoseUnsupportedPropertyUse();
300 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
305 bool isWeakProperty()
const;
309 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
321 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
322 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
323 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
330 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
332 bool findAtIndexGetter();
333 bool findAtIndexSetter();
339 class MSPropertyOpBuilder :
public PseudoOpBuilder {
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);
356 Expr *rebuildAndCaptureObject(
Expr *)
override;
359 bool captureSetValueAsResult()
const override {
return false; }
374 addSemanticExpr(captured);
389 if (!isa<OpaqueValueExpr>(e)) {
391 setResultToLastSemantic();
399 assert(index < Semantics.size() &&
400 "captured expression not found in semantics!");
401 if (e == Semantics[index])
break;
405 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
406 return cast<OpaqueValueExpr>(e);
412 Semantics, ResultIndex);
417 Expr *syntacticBase = rebuildAndCaptureObject(op);
421 addResultSemanticExpr(getExpr.
get());
423 return complete(syntacticBase);
434 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
443 Expr *semanticRHS = capturedRHS;
446 Semantics.pop_back();
452 if (opcode == BO_Assign) {
453 result = semanticRHS;
455 opcode, capturedRHS->
getType(),
466 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
478 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
480 addSemanticExpr(result.
get());
483 setResultToLastSemantic();
485 return complete(syntactic);
496 Expr *syntacticOp = rebuildAndCaptureObject(op);
507 result = capture(result.
get());
508 setResultToLastSemantic();
517 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
519 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
526 captureSetValueAsResult());
528 addSemanticExpr(result.
get());
532 setResultToLastSemantic();
542 return complete(syntactic);
586bool ObjCPropertyOpBuilder::isWeakProperty()
const {
588 if (RefExpr->isExplicitProperty()) {
603bool ObjCPropertyOpBuilder::findGetter() {
604 if (Getter)
return true;
607 if (RefExpr->isImplicitProperty()) {
608 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
609 GetterSelector = Getter->getSelector();
615 assert(setter &&
"both setter and getter are null - cannot happen");
628 return (Getter !=
nullptr);
635bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
637 if (RefExpr->isImplicitProperty()) {
638 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
643 const IdentifierInfo *getterName = RefExpr->getImplicitPropertyGetter()
645 .getIdentifierInfoForSlot(0);
664 StringRef thisPropertyName = prop->
getName();
666 char front = thisPropertyName.front();
669 PropertyName[0] = front;
674 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
675 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
678 S.
Diag(prop1->getLocation(), diag::note_property_declare);
693void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
698 S.
Diag(RefExpr->getLocation(),
699 diag::err_property_function_in_objc_container);
706Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
707 assert(InstanceReceiver ==
nullptr);
711 if (RefExpr->isObjectReceiver()) {
712 InstanceReceiver = capture(RefExpr->getBase());
713 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
714 return InstanceReceiver;
715 }).rebuild(syntacticBase);
719 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
720 SyntacticRefExpr = refE;
722 return syntacticBase;
729 DiagnoseUnsupportedPropertyUse();
733 if (SyntacticRefExpr)
734 SyntacticRefExpr->setIsMessagingGetter();
737 if (!Getter->isImplicit())
741 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
742 RefExpr->isObjectReceiver()) {
743 assert(InstanceReceiver || RefExpr->isSuperReceiver());
745 GenericLoc, Getter->getSelector(),
746 Getter, std::nullopt);
749 GenericLoc, Getter->getSelector(), Getter,
760 bool captureSetValueAsResult) {
761 if (!findSetter(
false)) {
762 DiagnoseUnsupportedPropertyUse();
766 if (SyntacticRefExpr)
767 SyntacticRefExpr->setIsMessagingSetter();
775 QualType paramType = (*Setter->param_begin())->getType()
778 Setter->getDeclContext(),
779 ObjCSubstitutionContext::Parameter);
791 assert(op &&
"successful assignment left argument invalid?");
796 Expr *args[] = { op };
800 if (!Setter->isImplicit())
802 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
803 RefExpr->isObjectReceiver()) {
805 GenericLoc, SetterSelector, Setter,
810 SetterSelector, Setter,
814 if (!msg.
isInvalid() && captureSetValueAsResult) {
818 if (CanCaptureValue(arg))
819 msgExpr->
setArg(0, captureValueAsResult(arg));
829 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
830 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
831 << RefExpr->getSourceRange();
835 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
838 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
840 Getter, RefExpr->getLocation());
844 if (RefExpr->isExplicitProperty() && result.
get()->
isPRValue()) {
846 QualType propType = RefExpr->getExplicitProperty()
847 ->getUsageType(receiverType);
851 if (!ptr->isObjCIdType())
857 RefExpr->getLocation()))
868bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
881 QualType resultType = Getter->getReturnType();
884 result = buildRValueOperation(op);
890ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
900 if (tryBuildGetOfReference(LHS, result)) {
906 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
907 <<
unsigned(RefExpr->isImplicitProperty())
916 if (opcode != BO_Assign && !findGetter()) {
917 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
923 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
927 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
944 if (tryBuildGetOfReference(op, result)) {
950 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
951 <<
unsigned(RefExpr->isImplicitProperty())
962 assert(RefExpr->isImplicitProperty());
963 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
970 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
978 SyntacticRefExpr->isMessagingGetter());
980 return PseudoOpBuilder::complete(SyntacticForm);
990ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
991 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
998ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
1004 if (!findAtIndexSetter())
1008 if (opcode != BO_Assign && !findAtIndexGetter())
1012 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1016 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1025Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1026 assert(InstanceBase ==
nullptr);
1030 InstanceBase = capture(RefExpr->getBaseExpr());
1031 InstanceKey = capture(RefExpr->getKeyExpr());
1034 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1037 return InstanceBase;
1041 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1043 }).rebuild(syntacticBase);
1045 return syntacticBase;
1069 if (isa<StringLiteral>(IndexExpr))
1073 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1080 diag::err_objc_index_incomplete_class_type, FromE))
1085 int NoIntegrals=0, NoObjCIdPointers=0;
1089 ->getVisibleConversionFunctions()) {
1091 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1092 QualType CT = Conversion->getConversionType().getNonReferenceType();
1095 ConversionDecls.push_back(Conversion);
1099 ConversionDecls.push_back(Conversion);
1103 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1105 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1107 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1109 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1113 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1115 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1116 Diag(ConversionDecls[i]->getLocation(),
1117 diag::note_conv_function_declared_at);
1142bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1146 Expr *BaseExpr = RefExpr->getBaseExpr();
1159 RefExpr->getKeyExpr());
1164 if (ResultType.
isNull()) {
1165 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1166 << BaseExpr->
getType() << arrayRef;
1187 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1206 AtIndexGetter->setMethodParams(S.
Context, Argument, std::nullopt);
1209 if (!AtIndexGetter) {
1211 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1212 << BaseExpr->
getType() << 0 << arrayRef;
1217 RefExpr->getSourceRange(),
1221 if (AtIndexGetter) {
1222 QualType T = AtIndexGetter->parameters()[0]->getType();
1225 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1226 arrayRef ? diag::err_objc_subscript_index_type
1227 : diag::err_objc_subscript_key_type) <<
T;
1228 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1229 diag::note_parameter_type) <<
T;
1232 QualType R = AtIndexGetter->getReturnType();
1234 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1235 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1236 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1237 AtIndexGetter->getDeclName();
1243bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1247 Expr *BaseExpr = RefExpr->getBaseExpr();
1261 RefExpr->getKeyExpr());
1266 if (ResultType.
isNull()) {
1267 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1268 << BaseExpr->
getType() << arrayRef;
1290 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1309 Params.push_back(
object);
1319 Params.push_back(key);
1320 AtIndexSetter->setMethodParams(S.
Context, Params, std::nullopt);
1323 if (!AtIndexSetter) {
1326 diag::err_objc_subscript_method_not_found)
1327 << BaseExpr->
getType() << 1 << arrayRef;
1332 RefExpr->getSourceRange(),
1337 if (AtIndexSetter && arrayRef) {
1338 QualType T = AtIndexSetter->parameters()[1]->getType();
1340 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1341 diag::err_objc_subscript_index_type) <<
T;
1342 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1343 diag::note_parameter_type) <<
T;
1346 T = AtIndexSetter->parameters()[0]->getType();
1348 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1349 diag::err_objc_subscript_object_type) <<
T << arrayRef;
1350 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1351 diag::note_parameter_type) <<
T;
1355 else if (AtIndexSetter && !arrayRef)
1356 for (
unsigned i=0; i <2; i++) {
1357 QualType T = AtIndexSetter->parameters()[i]->getType();
1360 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1361 diag::err_objc_subscript_key_type) <<
T;
1363 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1364 diag::err_objc_subscript_dic_object_type) <<
T;
1365 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1366 diag::note_parameter_type) <<
T;
1376ExprResult ObjCSubscriptOpBuilder::buildGet() {
1377 if (!findAtIndexGetter())
1380 QualType receiverType = InstanceBase->getType();
1384 Expr *Index = InstanceKey;
1387 Expr *args[] = { Index };
1388 assert(InstanceBase);
1393 AtIndexGetterSelector, AtIndexGetter,
1404 bool captureSetValueAsResult) {
1405 if (!findAtIndexSetter())
1409 QualType receiverType = InstanceBase->getType();
1410 Expr *Index = InstanceKey;
1413 Expr *args[] = { op, Index };
1418 AtIndexSetterSelector,
1422 if (!msg.
isInvalid() && captureSetValueAsResult) {
1426 if (CanCaptureValue(arg))
1427 msgExpr->
setArg(0, captureValueAsResult(arg));
1439 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1441 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(
Base)) {
1442 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1443 Base = MSPropSubscript->getBase()->IgnoreParens();
1445 return cast<MSPropertyRefExpr>(
Base);
1448Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1449 InstanceBase = capture(RefExpr->getBaseExpr());
1450 for (
Expr *&Arg : CallArgs)
1452 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1455 return InstanceBase;
1457 assert(Idx <= CallArgs.size());
1458 return CallArgs[Idx - 1];
1460 }).rebuild(syntacticBase);
1462 return syntacticBase;
1466 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1467 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1468 << 0 << RefExpr->getPropertyDecl();
1473 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
1476 SS.
Adopt(RefExpr->getQualifierLoc());
1479 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1482 S.
Diag(RefExpr->getMemberLoc(),
1483 diag::err_cannot_find_suitable_accessor) << 0
1484 << RefExpr->getPropertyDecl();
1490 RefExpr->getSourceRange().getEnd());
1494 bool captureSetValueAsResult) {
1495 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1496 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1497 << 1 << RefExpr->getPropertyDecl();
1502 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
1505 SS.
Adopt(RefExpr->getQualifierLoc());
1508 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1511 S.
Diag(RefExpr->getMemberLoc(),
1512 diag::err_cannot_find_suitable_accessor) << 1
1513 << RefExpr->getPropertyDecl();
1518 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1519 ArgExprs.push_back(op);
1532 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1533 ObjCPropertyOpBuilder builder(*
this, refExpr,
true);
1534 return builder.buildRValueOperation(E);
1537 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1538 ObjCSubscriptOpBuilder builder(*
this, refExpr,
true);
1539 return builder.buildRValueOperation(E);
1541 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1542 MSPropertyOpBuilder builder(*
this, refExpr,
true);
1543 return builder.buildRValueOperation(E);
1545 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1546 MSPropertyOpBuilder Builder(*
this, RefExpr,
true);
1547 return Builder.buildRValueOperation(E);
1549 llvm_unreachable(
"unknown pseudo-object kind!");
1565 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1566 ObjCPropertyOpBuilder builder(*
this, refExpr,
false);
1567 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1568 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1569 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1572 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1573 MSPropertyOpBuilder builder(*
this, refExpr,
false);
1574 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1576 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1577 MSPropertyOpBuilder Builder(*
this, RefExpr,
false);
1578 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1580 llvm_unreachable(
"unknown pseudo-object kind!");
1600 bool IsSimpleAssign = opcode == BO_Assign;
1603 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1604 ObjCPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1605 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1607 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1608 ObjCSubscriptOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1609 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1611 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1612 MSPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1613 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1615 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1616 MSPropertyOpBuilder Builder(*
this, RefExpr, IsSimpleAssign);
1617 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1619 llvm_unreachable(
"unknown pseudo-object kind!");
1629 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1645 uop->getValueKind(), uop->getObjectKind(),
1646 uop->getOperatorLoc(), uop->canOverflow(),
1649 = dyn_cast<CompoundAssignOperator>(syntax)) {
1651 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1654 cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
1656 cop->getComputationResultType());
1658 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1660 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1662 bop->
getType(), bop->getValueKind(),
1663 bop->getObjectKind(), bop->getOperatorLoc(),
1666 }
else if (isa<CallExpr>(syntax)) {
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::Preprocessor interface.
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 ...
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++ conversion function within a class.
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 * 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.
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.
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.
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
This represents a decl that may have a name.
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 parethesized 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)
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
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.
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.
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.
Sema - This implements semantic analysis and AST building for C.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
FPOptionsOverride CurFPFeatureOverrides()
ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
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.
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
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.
ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op)
Check an increment or decrement of a pseudo-object expression.
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
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.
ExprResult checkPseudoObjectRValue(Expr *E)
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 ...
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.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
DiagnosticsEngine & Diags
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
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)
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
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...
bool isBlockPointerType() const
bool isVoidPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
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<specific type>'.
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
@ Implicit
An implicit conversion.
MutableArrayRef< Expr * > MultiExprArg
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)