39 #include "llvm/ADT/SmallString.h" 41 using namespace clang;
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) {}
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());
133 uop->getObjectKind(),
134 uop->getOperatorLoc(),
139 assert(!gse->isResultDependent());
140 unsigned resultIndex = gse->getResultIndex();
141 unsigned numAssocs = gse->getNumAssocs();
145 assocExprs.reserve(numAssocs);
146 assocTypes.reserve(numAssocs);
149 gse->associations()) {
150 Expr *assocExpr = assoc.getAssociationExpr();
151 if (assoc.isSelected())
152 assocExpr = rebuild(assocExpr);
153 assocExprs.push_back(assocExpr);
154 assocTypes.push_back(assoc.getTypeSourceInfo());
158 S.
Context, gse->getGenericLoc(), gse->getControllingExpr(),
159 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
160 gse->containsUnexpandedParameterPack(), resultIndex);
163 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
164 assert(!ce->isConditionDependent());
166 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
167 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
168 rebuiltExpr = rebuild(rebuiltExpr);
177 ce->isConditionTrue(),
182 llvm_unreachable(
"bad expression to rebuild!");
186 class PseudoOpBuilder {
189 unsigned ResultIndex;
196 GenericLoc(genericLoc), IsUnique(IsUnique) {}
198 virtual ~PseudoOpBuilder() {}
201 void addSemanticExpr(
Expr *semantic) {
202 Semantics.push_back(semantic);
206 void addResultSemanticExpr(
Expr *resultExpr) {
208 ResultIndex = Semantics.size();
209 Semantics.push_back(resultExpr);
211 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
212 OVE->setIsUnique(
false);
229 void setResultToLastSemantic() {
231 ResultIndex = Semantics.size() - 1;
233 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
234 OVE->setIsUnique(
false);
238 static bool CanCaptureValue(
Expr *
exp) {
246 return ClassDecl->isTriviallyCopyable();
250 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
253 bool captureSetValueAsResult) = 0;
267 virtual bool captureSetValueAsResult()
const {
return true; }
271 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
283 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
284 RefExpr(refExpr), SyntacticRefExpr(nullptr),
285 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
298 bool findSetter(
bool warn=
true);
300 void DiagnoseUnsupportedPropertyUse();
302 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
307 bool isWeakProperty()
const;
311 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
323 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
324 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
325 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
332 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
334 bool findAtIndexGetter();
335 bool findAtIndexSetter();
341 class MSPropertyOpBuilder :
public PseudoOpBuilder {
350 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
351 RefExpr(refExpr), InstanceBase(nullptr) {}
353 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
354 InstanceBase(nullptr) {
355 RefExpr = getBaseMSProperty(refExpr);
358 Expr *rebuildAndCaptureObject(
Expr *)
override;
361 bool captureSetValueAsResult()
const override {
return false; }
376 addSemanticExpr(captured);
391 if (!isa<OpaqueValueExpr>(e)) {
393 setResultToLastSemantic();
401 assert(index < Semantics.size() &&
402 "captured expression not found in semantics!");
403 if (e == Semantics[index])
break;
407 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
408 return cast<OpaqueValueExpr>(e);
414 Semantics, ResultIndex);
419 Expr *syntacticBase = rebuildAndCaptureObject(op);
423 addResultSemanticExpr(getExpr.
get());
425 return complete(syntacticBase);
436 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
445 Expr *semanticRHS = capturedRHS;
448 Semantics.pop_back();
454 if (opcode == BO_Assign) {
455 result = semanticRHS;
457 opcode, capturedRHS->
getType(),
468 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
473 result.
get()->getType(),
474 result.
get()->getValueKind(),
476 opLHS.
get()->getType(),
477 result.
get()->getType(),
483 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
485 addSemanticExpr(result.
get());
486 if (!captureSetValueAsResult() && !result.
get()->getType()->isVoidType() &&
487 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
488 setResultToLastSemantic();
490 return complete(syntactic);
501 Expr *syntacticOp = rebuildAndCaptureObject(op);
511 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get()))) {
512 result = capture(result.
get());
513 setResultToLastSemantic();
522 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
524 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
531 captureSetValueAsResult());
533 addSemanticExpr(result.
get());
535 !result.
get()->getType()->isVoidType() &&
536 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
537 setResultToLastSemantic();
545 return complete(syntactic);
589 bool ObjCPropertyOpBuilder::isWeakProperty()
const {
591 if (RefExpr->isExplicitProperty()) {
598 T = Getter->getReturnType();
606 bool ObjCPropertyOpBuilder::findGetter() {
607 if (Getter)
return true;
610 if (RefExpr->isImplicitProperty()) {
611 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
612 GetterSelector = Getter->getSelector();
618 assert(setter &&
"both setter and getter are null - cannot happen");
631 return (Getter !=
nullptr);
638 bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
640 if (RefExpr->isImplicitProperty()) {
641 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
647 RefExpr->getImplicitPropertyGetter()->getSelector()
648 .getIdentifierInfoForSlot(0);
664 if (setter->isPropertyAccessor() && warn)
666 dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
667 StringRef thisPropertyName = prop->
getName();
669 char front = thisPropertyName.front();
672 PropertyName[0] = front;
676 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
677 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
678 << prop << prop1 << setter->getSelector();
680 S.
Diag(prop1->getLocation(), diag::note_property_declare);
695 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
700 S.
Diag(RefExpr->getLocation(),
701 diag::err_property_function_in_objc_container);
702 S.
Diag(prop->getLocation(), diag::note_property_declare);
708 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
709 assert(InstanceReceiver ==
nullptr);
713 if (RefExpr->isObjectReceiver()) {
714 InstanceReceiver = capture(RefExpr->getBase());
715 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
716 return InstanceReceiver;
717 }).rebuild(syntacticBase);
721 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
722 SyntacticRefExpr = refE;
724 return syntacticBase;
728 ExprResult ObjCPropertyOpBuilder::buildGet() {
731 DiagnoseUnsupportedPropertyUse();
735 if (SyntacticRefExpr)
736 SyntacticRefExpr->setIsMessagingGetter();
739 if (!Getter->isImplicit())
743 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
744 RefExpr->isObjectReceiver()) {
745 assert(InstanceReceiver || RefExpr->isSuperReceiver());
747 GenericLoc, Getter->getSelector(),
751 GenericLoc, Getter->getSelector(),
762 bool captureSetValueAsResult) {
763 if (!findSetter(
false)) {
764 DiagnoseUnsupportedPropertyUse();
768 if (SyntacticRefExpr)
769 SyntacticRefExpr->setIsMessagingSetter();
777 QualType paramType = (*Setter->param_begin())->getType()
780 Setter->getDeclContext(),
793 assert(op &&
"successful assignment left argument invalid?");
798 Expr *args[] = { op };
802 if (!Setter->isImplicit())
804 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
805 RefExpr->isObjectReceiver()) {
807 GenericLoc, SetterSelector, Setter,
812 SetterSelector, Setter,
816 if (!msg.
isInvalid() && captureSetValueAsResult) {
818 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
820 if (CanCaptureValue(arg))
821 msgExpr->
setArg(0, captureValueAsResult(arg));
828 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(
Expr *op) {
831 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
832 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
833 << RefExpr->getSourceRange();
837 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
840 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
842 Getter, RefExpr->getLocation());
846 if (RefExpr->isExplicitProperty() && result.
get()->isRValue()) {
848 QualType propType = RefExpr->getExplicitProperty()
849 ->getUsageType(receiverType);
850 if (result.
get()->getType()->isObjCIdType()) {
853 if (!ptr->isObjCIdType())
859 RefExpr->getLocation()))
870 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
883 QualType resultType = Getter->getReturnType();
886 result = buildRValueOperation(op);
892 ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
902 if (tryBuildGetOfReference(LHS, result)) {
908 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
909 << unsigned(RefExpr->isImplicitProperty())
918 if (opcode != BO_Assign && !findGetter()) {
919 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
925 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
929 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
946 if (tryBuildGetOfReference(op, result)) {
952 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
953 << unsigned(RefExpr->isImplicitProperty())
964 assert(RefExpr->isImplicitProperty());
965 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
972 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
980 SyntacticRefExpr->isMessagingGetter());
982 return PseudoOpBuilder::complete(SyntacticForm);
992 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
993 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
1000 ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
1006 if (!findAtIndexSetter())
1010 if (opcode != BO_Assign && !findAtIndexGetter())
1014 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1018 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1027 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1028 assert(InstanceBase ==
nullptr);
1032 InstanceBase = capture(RefExpr->getBaseExpr());
1033 InstanceKey = capture(RefExpr->getKeyExpr());
1036 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1039 return InstanceBase;
1043 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1045 }).rebuild(syntacticBase);
1047 return syntacticBase;
1066 return OS_Dictionary;
1067 if (!getLangOpts().CPlusPlus ||
1071 if (isa<StringLiteral>(IndexExpr))
1075 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1081 if (RequireCompleteType(FromE->
getExprLoc(), T,
1082 diag::err_objc_index_incomplete_class_type, FromE))
1087 int NoIntegrals=0, NoObjCIdPointers=0;
1091 ->getVisibleConversionFunctions()) {
1093 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1094 QualType CT = Conversion->getConversionType().getNonReferenceType();
1097 ConversionDecls.push_back(Conversion);
1101 ConversionDecls.push_back(Conversion);
1105 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1107 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1108 return OS_Dictionary;
1109 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1111 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1115 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1117 for (
unsigned int i = 0;
i < ConversionDecls.size();
i++)
1118 Diag(ConversionDecls[
i]->getLocation(),
1119 diag::note_conv_function_declared_at);
1145 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1149 Expr *BaseExpr = RefExpr->getBaseExpr();
1162 RefExpr->getKeyExpr());
1167 if (ResultType.
isNull()) {
1168 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1169 << BaseExpr->
getType() << arrayRef;
1192 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1212 AtIndexGetter->setMethodParams(S.
Context, Argument, None);
1215 if (!AtIndexGetter) {
1217 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1218 << BaseExpr->
getType() << 0 << arrayRef;
1223 RefExpr->getSourceRange(),
1227 if (AtIndexGetter) {
1228 QualType T = AtIndexGetter->parameters()[0]->getType();
1231 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1232 arrayRef ? diag::err_objc_subscript_index_type
1233 : diag::err_objc_subscript_key_type) << T;
1234 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1235 diag::note_parameter_type) << T;
1238 QualType R = AtIndexGetter->getReturnType();
1240 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1241 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1242 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1243 AtIndexGetter->getDeclName();
1249 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1253 Expr *BaseExpr = RefExpr->getBaseExpr();
1267 RefExpr->getKeyExpr());
1272 if (ResultType.
isNull()) {
1273 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1274 << BaseExpr->
getType() << arrayRef;
1298 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1316 Params.push_back(
object);
1326 Params.push_back(key);
1327 AtIndexSetter->setMethodParams(S.
Context, Params, None);
1330 if (!AtIndexSetter) {
1333 diag::err_objc_subscript_method_not_found)
1334 << BaseExpr->
getType() << 1 << arrayRef;
1339 RefExpr->getSourceRange(),
1344 if (AtIndexSetter && arrayRef) {
1345 QualType T = AtIndexSetter->parameters()[1]->getType();
1347 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1348 diag::err_objc_subscript_index_type) << T;
1349 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1350 diag::note_parameter_type) << T;
1353 T = AtIndexSetter->parameters()[0]->getType();
1355 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1356 diag::err_objc_subscript_object_type) << T << arrayRef;
1357 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1358 diag::note_parameter_type) << T;
1362 else if (AtIndexSetter && !arrayRef)
1363 for (
unsigned i=0;
i <2;
i++) {
1364 QualType T = AtIndexSetter->parameters()[
i]->getType();
1367 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1368 diag::err_objc_subscript_key_type) << T;
1370 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1371 diag::err_objc_subscript_dic_object_type) << T;
1372 S.
Diag(AtIndexSetter->parameters()[
i]->getLocation(),
1373 diag::note_parameter_type) << T;
1383 ExprResult ObjCSubscriptOpBuilder::buildGet() {
1384 if (!findAtIndexGetter())
1387 QualType receiverType = InstanceBase->getType();
1391 Expr *Index = InstanceKey;
1394 Expr *args[] = { Index };
1395 assert(InstanceBase);
1400 AtIndexGetterSelector, AtIndexGetter,
1411 bool captureSetValueAsResult) {
1412 if (!findAtIndexSetter())
1416 QualType receiverType = InstanceBase->getType();
1417 Expr *Index = InstanceKey;
1420 Expr *args[] = { op, Index };
1425 AtIndexSetterSelector,
1429 if (!msg.
isInvalid() && captureSetValueAsResult) {
1431 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
1433 if (CanCaptureValue(arg))
1434 msgExpr->
setArg(0, captureValueAsResult(arg));
1446 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1448 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1449 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1452 return cast<MSPropertyRefExpr>(Base);
1455 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1456 InstanceBase = capture(RefExpr->getBaseExpr());
1457 llvm::for_each(CallArgs, [
this](
Expr *&Arg) { Arg = capture(Arg); });
1458 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1461 return InstanceBase;
1463 assert(Idx <= CallArgs.size());
1464 return CallArgs[Idx - 1];
1466 }).rebuild(syntacticBase);
1468 return syntacticBase;
1472 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1473 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1474 << 0 << RefExpr->getPropertyDecl();
1482 SS.
Adopt(RefExpr->getQualifierLoc());
1485 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1488 S.
Diag(RefExpr->getMemberLoc(),
1489 diag::err_cannot_find_suitable_accessor) << 0
1490 << RefExpr->getPropertyDecl();
1495 RefExpr->getSourceRange().getBegin(), CallArgs,
1496 RefExpr->getSourceRange().getEnd());
1500 bool captureSetValueAsResult) {
1501 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1502 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1503 << 1 << RefExpr->getPropertyDecl();
1511 SS.
Adopt(RefExpr->getQualifierLoc());
1514 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1517 S.
Diag(RefExpr->getMemberLoc(),
1518 diag::err_cannot_find_suitable_accessor) << 1
1519 << RefExpr->getPropertyDecl();
1524 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1525 ArgExprs.push_back(op);
1527 RefExpr->getSourceRange().getBegin(), ArgExprs,
1538 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1539 ObjCPropertyOpBuilder builder(*
this, refExpr,
true);
1540 return builder.buildRValueOperation(E);
1543 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1544 ObjCSubscriptOpBuilder builder(*
this, refExpr,
true);
1545 return builder.buildRValueOperation(E);
1547 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1548 MSPropertyOpBuilder builder(*
this, refExpr,
true);
1549 return builder.buildRValueOperation(E);
1551 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1552 MSPropertyOpBuilder Builder(*
this, RefExpr,
true);
1553 return Builder.buildRValueOperation(E);
1555 llvm_unreachable(
"unknown pseudo-object kind!");
1570 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1571 ObjCPropertyOpBuilder builder(*
this, refExpr,
false);
1572 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1573 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1574 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1577 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1578 MSPropertyOpBuilder builder(*
this, refExpr,
false);
1579 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1581 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1582 MSPropertyOpBuilder Builder(*
this, RefExpr,
false);
1583 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1585 llvm_unreachable(
"unknown pseudo-object kind!");
1600 ExprResult result = CheckPlaceholderExpr(RHS);
1605 bool IsSimpleAssign = opcode == BO_Assign;
1608 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1609 ObjCPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1610 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1612 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1613 ObjCSubscriptOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1614 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1616 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1617 MSPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1618 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1620 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1621 MSPropertyOpBuilder Builder(*
this, RefExpr, IsSimpleAssign);
1622 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1624 llvm_unreachable(
"unknown pseudo-object kind!");
1634 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1650 op, uop->getOpcode(), uop->
getType(), uop->getValueKind(),
1651 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow());
1653 = dyn_cast<CompoundAssignOperator>(syntax)) {
1655 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1658 cop->getValueKind(),
1659 cop->getObjectKind(),
1660 cop->getComputationLHSType(),
1661 cop->getComputationResultType(),
1662 cop->getOperatorLoc(),
1664 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1666 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1668 bop->
getType(), bop->getValueKind(),
1669 bop->getObjectKind(),
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyQueryKind getQueryKind() const
bool isIncrementOp() const
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
SelectorTable & getSelectorTable()
A (possibly-)qualified type.
bool isBlockPointerType() const
static Opcode getOpForCompoundAssignment(Opcode Opc)
ObjCMethodDecl * getAtIndexMethodDecl() const
ObjCInterfaceDecl * getClassInterface()
bool isSuperReceiver() const
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 ...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
ObjCMethodDecl * setAtIndexMethodDecl() const
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool isRecordType() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
ObjCMethodDecl * getImplicitPropertySetter() const
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
ParenExpr - This represents a parethesized expression, e.g.
bool isObjCContainer() const
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
A container of type source information.
Floating point control options.
MS property subscript expression.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
DiagnosticsEngine & Diags
const T * getAs() const
Member-template getAs<specific type>'.
ObjCInterfaceDecl * getClassReceiver() const
ObjCMethodDecl - Represents an instance or class method declaration.
static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, Expr *Key)
CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF objects used as dictionary ...
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input)
Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
ObjCPropertyDecl * getExplicitProperty() const
One of these records is kept for each identifier that is lexed.
bool isExplicitProperty() const
SourceLocation getBeginLoc() const LLVM_READONLY
bool isObjCIdType() const
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
bool isAssignmentOp() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
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 Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Expr * getKeyExpr() const
Represents a C++ unqualified-id that has been parsed.
Selector getNullarySelector(IdentifierInfo *ID)
Expr * getBaseExpr() const
static Expr * stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E)
Given a pseudo-object reference, rebuild it without the opaque values.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
PropertyAttributeKind getPropertyAttributes() const
A builtin binary operation expression such as "x + y" or "x <= y".
bool isClassReceiver() const
Scope - A scope is a transient data structure that is used while parsing the program.
Represents a C++ nested-name-specifier or a global scope specifier.
AssociationTy< false > Association
const LangOptions & getLangOpts() const
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'.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
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.
An ordinary object is located at an address in memory.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5...
Represents an ObjC class declaration.
ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op)
Check an increment or decrement of a pseudo-object expression.
Sema - This implements semantic analysis and AST building for C.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
SourceLocation getRBracket() const
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
SourceLocation getRBracketLoc() const
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents one expression.
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 isImplicitlyDeclared=false, bool isDefined=false, ImplementationControl impControl=None, bool HasRelatedResultType=false)
Selector getSetterName() const
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
const T * castAs() const
Member-template castAs<specific type>.
Defines the clang::Preprocessor interface.
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
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...
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...
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl * getImplicitPropertyGetter() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
SourceLocation getEnd() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
A member reference to an MSPropertyDecl.
Selector getSelector() const
Represents a C++ conversion function within a class.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isDecrementOp() const
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool isVoidPointerType() const
RecordDecl * getDecl() const
Decl::Kind getDeclKind() const
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
SelectorTable & Selectors
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle...
MutableArrayRef< Expr * > MultiExprArg
IdentifierTable & getIdentifierTable()
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics...
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
CompoundAssignOperator - For compound assignments (e.g.
StringRef getName() const
Return the actual identifier string.
Represents a C11 generic selection.
SourceLocation getMemberLoc() const
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Dataflow Directional Tag Classes.
SourceLocation getLocation() const
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_RValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CCK_ImplicitConversion)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
MSPropertyDecl * getPropertyDecl() const
bool isObjCClassType() const
True if this is equivalent to the 'Class' type, i.e.
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.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr *> semantic, unsigned resultIndex)
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 .
NestedNameSpecifierLoc getQualifierLoc() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
ExprResult checkPseudoObjectRValue(Expr *E)
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Represents a pointer to an Objective C object.
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
CanQualType UnsignedLongTy
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
DeclContext * getCurLexicalContext() const
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.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
bool isLValueReferenceType() const
Reading or writing from this object requires a barrier call.
QualType getSuperReceiverType() const
TranslationUnitDecl * getTranslationUnitDecl() const
Represents a C++ struct/union/class.
sema::FunctionScopeInfo * getCurFunction() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
The parameter type of a method or function.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
bool isObjectReceiver() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
bool isIncrementDecrementOp() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
An l-value expression is a reference to an object with independent storage.
const Expr * getBase() const
This represents a decl that may have a name.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Selector getGetterName() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
Expr * getBaseExpr() const
SourceLocation getLocation() const
ArrayRef< ParmVarDecl * > parameters() const
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.