40 #include "llvm/ADT/SmallString.h" 42 using namespace clang;
49 unsigned MSPropertySubscriptCount;
50 typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy;
51 const SpecificRebuilderRefTy &SpecificCallback;
52 Rebuilder(
Sema &S,
const SpecificRebuilderRefTy &SpecificCallback)
53 : S(S), MSPropertySubscriptCount(0),
54 SpecificCallback(SpecificCallback) {}
98 auto *NewBase = rebuild(refExpr->
getBase());
99 ++MSPropertySubscriptCount;
102 SpecificCallback(refExpr->
getIdx(), MSPropertySubscriptCount),
109 if (
auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e))
110 return rebuildObjCPropertyRefExpr(PRE);
111 if (
auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e))
112 return rebuildObjCSubscriptRefExpr(SRE);
113 if (
auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e))
114 return rebuildMSPropertyRefExpr(MSPRE);
115 if (
auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e))
116 return rebuildMSPropertySubscriptExpr(MSPSE);
121 if (
ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
122 e = rebuild(parens->getSubExpr());
129 assert(uop->getOpcode() == UO_Extension);
130 e = rebuild(uop->getSubExpr());
134 uop->getObjectKind(),
135 uop->getOperatorLoc(),
140 assert(!gse->isResultDependent());
141 unsigned resultIndex = gse->getResultIndex();
142 unsigned numAssocs = gse->getNumAssocs();
147 for (
unsigned i = 0; i != numAssocs; ++i) {
148 Expr *assoc = gse->getAssocExpr(i);
149 if (i == resultIndex) assoc = rebuild(assoc);
151 assocTypes[i] = gse->getAssocTypeSourceInfo(i);
155 gse->getGenericLoc(),
156 gse->getControllingExpr(),
159 gse->getDefaultLoc(),
161 gse->containsUnexpandedParameterPack(),
165 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
166 assert(!ce->isConditionDependent());
168 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
169 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
170 rebuiltExpr = rebuild(rebuiltExpr);
179 ce->isConditionTrue(),
184 llvm_unreachable(
"bad expression to rebuild!");
188 class PseudoOpBuilder {
191 unsigned ResultIndex;
198 GenericLoc(genericLoc), IsUnique(IsUnique) {}
200 virtual ~PseudoOpBuilder() {}
203 void addSemanticExpr(
Expr *semantic) {
204 Semantics.push_back(semantic);
208 void addResultSemanticExpr(
Expr *resultExpr) {
210 ResultIndex = Semantics.size();
211 Semantics.push_back(resultExpr);
213 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
214 OVE->setIsUnique(
false);
231 void setResultToLastSemantic() {
233 ResultIndex = Semantics.size() - 1;
235 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
236 OVE->setIsUnique(
false);
240 static bool CanCaptureValue(
Expr *
exp) {
248 return ClassDecl->isTriviallyCopyable();
252 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
255 bool captureSetValueAsResult) = 0;
269 virtual bool captureSetValueAsResult()
const {
return true; }
273 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
285 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
286 RefExpr(refExpr), SyntacticRefExpr(nullptr),
287 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
300 bool findSetter(
bool warn=
true);
302 void DiagnoseUnsupportedPropertyUse();
304 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
309 bool isWeakProperty()
const;
313 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
325 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
326 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
327 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
334 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
336 bool findAtIndexGetter();
337 bool findAtIndexSetter();
343 class MSPropertyOpBuilder :
public PseudoOpBuilder {
352 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
353 RefExpr(refExpr), InstanceBase(nullptr) {}
355 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
356 InstanceBase(nullptr) {
357 RefExpr = getBaseMSProperty(refExpr);
360 Expr *rebuildAndCaptureObject(
Expr *)
override;
363 bool captureSetValueAsResult()
const override {
return false; }
378 addSemanticExpr(captured);
393 if (!isa<OpaqueValueExpr>(e)) {
395 setResultToLastSemantic();
403 assert(index < Semantics.size() &&
404 "captured expression not found in semantics!");
405 if (e == Semantics[index])
break;
409 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
410 return cast<OpaqueValueExpr>(e);
416 Semantics, ResultIndex);
421 Expr *syntacticBase = rebuildAndCaptureObject(op);
425 addResultSemanticExpr(getExpr.
get());
427 return complete(syntacticBase);
438 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
447 Expr *semanticRHS = capturedRHS;
450 Semantics.pop_back();
456 if (opcode == BO_Assign) {
457 result = semanticRHS;
459 opcode, capturedRHS->
getType(),
470 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
475 result.
get()->getType(),
476 result.
get()->getValueKind(),
478 opLHS.
get()->getType(),
479 result.
get()->getType(),
485 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
487 addSemanticExpr(result.
get());
488 if (!captureSetValueAsResult() && !result.
get()->getType()->isVoidType() &&
489 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
490 setResultToLastSemantic();
492 return complete(syntactic);
503 Expr *syntacticOp = rebuildAndCaptureObject(op);
513 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get()))) {
514 result = capture(result.
get());
515 setResultToLastSemantic();
524 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
526 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
533 captureSetValueAsResult());
535 addSemanticExpr(result.
get());
537 !result.
get()->getType()->isVoidType() &&
538 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
539 setResultToLastSemantic();
547 return complete(syntactic);
591 bool ObjCPropertyOpBuilder::isWeakProperty()
const {
593 if (RefExpr->isExplicitProperty()) {
600 T = Getter->getReturnType();
608 bool ObjCPropertyOpBuilder::findGetter() {
609 if (Getter)
return true;
612 if (RefExpr->isImplicitProperty()) {
613 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
614 GetterSelector = Getter->getSelector();
620 assert(setter &&
"both setter and getter are null - cannot happen");
633 return (Getter !=
nullptr);
640 bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
642 if (RefExpr->isImplicitProperty()) {
643 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
649 RefExpr->getImplicitPropertyGetter()->getSelector()
650 .getIdentifierInfoForSlot(0);
666 if (setter->isPropertyAccessor() && warn)
668 dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
669 StringRef thisPropertyName = prop->
getName();
671 char front = thisPropertyName.front();
674 PropertyName[0] = front;
678 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
679 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
680 << prop << prop1 << setter->getSelector();
682 S.
Diag(prop1->getLocation(), diag::note_property_declare);
697 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
702 S.
Diag(RefExpr->getLocation(),
703 diag::err_property_function_in_objc_container);
704 S.
Diag(prop->getLocation(), diag::note_property_declare);
710 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
711 assert(InstanceReceiver ==
nullptr);
715 if (RefExpr->isObjectReceiver()) {
716 InstanceReceiver = capture(RefExpr->getBase());
717 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
718 return InstanceReceiver;
719 }).rebuild(syntacticBase);
723 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
724 SyntacticRefExpr = refE;
726 return syntacticBase;
730 ExprResult ObjCPropertyOpBuilder::buildGet() {
733 DiagnoseUnsupportedPropertyUse();
737 if (SyntacticRefExpr)
738 SyntacticRefExpr->setIsMessagingGetter();
741 if (!Getter->isImplicit())
745 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
746 RefExpr->isObjectReceiver()) {
747 assert(InstanceReceiver || RefExpr->isSuperReceiver());
749 GenericLoc, Getter->getSelector(),
753 GenericLoc, Getter->getSelector(),
764 bool captureSetValueAsResult) {
765 if (!findSetter(
false)) {
766 DiagnoseUnsupportedPropertyUse();
770 if (SyntacticRefExpr)
771 SyntacticRefExpr->setIsMessagingSetter();
779 QualType paramType = (*Setter->param_begin())->getType()
782 Setter->getDeclContext(),
795 assert(op &&
"successful assignment left argument invalid?");
800 Expr *args[] = { op };
804 if (!Setter->isImplicit())
806 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
807 RefExpr->isObjectReceiver()) {
809 GenericLoc, SetterSelector, Setter,
814 SetterSelector, Setter,
818 if (!msg.
isInvalid() && captureSetValueAsResult) {
820 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
822 if (CanCaptureValue(arg))
823 msgExpr->
setArg(0, captureValueAsResult(arg));
830 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(
Expr *op) {
833 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
834 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
835 << RefExpr->getSourceRange();
839 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
842 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
844 Getter, RefExpr->getLocation());
848 if (RefExpr->isExplicitProperty() && result.
get()->isRValue()) {
850 QualType propType = RefExpr->getExplicitProperty()
851 ->getUsageType(receiverType);
852 if (result.
get()->getType()->isObjCIdType()) {
855 if (!ptr->isObjCIdType())
861 RefExpr->getLocation()))
872 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
885 QualType resultType = Getter->getReturnType();
888 result = buildRValueOperation(op);
894 ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
904 if (tryBuildGetOfReference(LHS, result)) {
910 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
911 << unsigned(RefExpr->isImplicitProperty())
920 if (opcode != BO_Assign && !findGetter()) {
921 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
927 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
931 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
948 if (tryBuildGetOfReference(op, result)) {
954 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
955 << unsigned(RefExpr->isImplicitProperty())
966 assert(RefExpr->isImplicitProperty());
967 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
974 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
982 SyntacticRefExpr->isMessagingGetter());
984 return PseudoOpBuilder::complete(SyntacticForm);
994 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
995 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
1002 ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
1008 if (!findAtIndexSetter())
1012 if (opcode != BO_Assign && !findAtIndexGetter())
1016 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1020 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1029 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1030 assert(InstanceBase ==
nullptr);
1034 InstanceBase = capture(RefExpr->getBaseExpr());
1035 InstanceKey = capture(RefExpr->getKeyExpr());
1038 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1041 return InstanceBase;
1045 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1047 }).rebuild(syntacticBase);
1049 return syntacticBase;
1068 return OS_Dictionary;
1069 if (!getLangOpts().CPlusPlus ||
1073 if (isa<StringLiteral>(IndexExpr))
1077 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1083 if (RequireCompleteType(FromE->
getExprLoc(), T,
1084 diag::err_objc_index_incomplete_class_type, FromE))
1089 int NoIntegrals=0, NoObjCIdPointers=0;
1093 ->getVisibleConversionFunctions()) {
1095 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1096 QualType CT = Conversion->getConversionType().getNonReferenceType();
1099 ConversionDecls.push_back(Conversion);
1103 ConversionDecls.push_back(Conversion);
1107 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1109 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1110 return OS_Dictionary;
1111 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1113 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1117 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1119 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1120 Diag(ConversionDecls[i]->getLocation(),
1121 diag::note_conv_function_declared_at);
1147 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1151 Expr *BaseExpr = RefExpr->getBaseExpr();
1164 RefExpr->getKeyExpr());
1169 if (ResultType.
isNull()) {
1170 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1171 << BaseExpr->
getType() << arrayRef;
1194 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1214 AtIndexGetter->setMethodParams(S.
Context, Argument, None);
1217 if (!AtIndexGetter) {
1219 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1220 << BaseExpr->
getType() << 0 << arrayRef;
1225 RefExpr->getSourceRange(),
1229 if (AtIndexGetter) {
1230 QualType T = AtIndexGetter->parameters()[0]->getType();
1233 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1234 arrayRef ? diag::err_objc_subscript_index_type
1235 : diag::err_objc_subscript_key_type) << T;
1236 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1237 diag::note_parameter_type) << T;
1240 QualType R = AtIndexGetter->getReturnType();
1242 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1243 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1244 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1245 AtIndexGetter->getDeclName();
1251 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1255 Expr *BaseExpr = RefExpr->getBaseExpr();
1269 RefExpr->getKeyExpr());
1274 if (ResultType.
isNull()) {
1275 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1276 << BaseExpr->
getType() << arrayRef;
1300 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1318 Params.push_back(
object);
1328 Params.push_back(key);
1329 AtIndexSetter->setMethodParams(S.
Context, Params, None);
1332 if (!AtIndexSetter) {
1335 diag::err_objc_subscript_method_not_found)
1336 << BaseExpr->
getType() << 1 << arrayRef;
1341 RefExpr->getSourceRange(),
1346 if (AtIndexSetter && arrayRef) {
1347 QualType T = AtIndexSetter->parameters()[1]->getType();
1349 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1350 diag::err_objc_subscript_index_type) << T;
1351 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1352 diag::note_parameter_type) << T;
1355 T = AtIndexSetter->parameters()[0]->getType();
1357 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1358 diag::err_objc_subscript_object_type) << T << arrayRef;
1359 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1360 diag::note_parameter_type) << T;
1364 else if (AtIndexSetter && !arrayRef)
1365 for (
unsigned i=0; i <2; i++) {
1366 QualType T = AtIndexSetter->parameters()[i]->getType();
1369 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1370 diag::err_objc_subscript_key_type) << T;
1372 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1373 diag::err_objc_subscript_dic_object_type) << T;
1374 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1375 diag::note_parameter_type) << T;
1385 ExprResult ObjCSubscriptOpBuilder::buildGet() {
1386 if (!findAtIndexGetter())
1389 QualType receiverType = InstanceBase->getType();
1393 Expr *Index = InstanceKey;
1396 Expr *args[] = { Index };
1397 assert(InstanceBase);
1402 AtIndexGetterSelector, AtIndexGetter,
1413 bool captureSetValueAsResult) {
1414 if (!findAtIndexSetter())
1418 QualType receiverType = InstanceBase->getType();
1419 Expr *Index = InstanceKey;
1422 Expr *args[] = { op, Index };
1427 AtIndexSetterSelector,
1431 if (!msg.
isInvalid() && captureSetValueAsResult) {
1433 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
1435 if (CanCaptureValue(arg))
1436 msgExpr->
setArg(0, captureValueAsResult(arg));
1448 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1450 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1451 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1454 return cast<MSPropertyRefExpr>(Base);
1457 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1458 InstanceBase = capture(RefExpr->getBaseExpr());
1459 llvm::for_each(CallArgs, [
this](
Expr *&Arg) { Arg = capture(Arg); });
1460 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1463 return InstanceBase;
1465 assert(Idx <= CallArgs.size());
1466 return CallArgs[Idx - 1];
1468 }).rebuild(syntacticBase);
1470 return syntacticBase;
1474 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1475 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1476 << 0 << RefExpr->getPropertyDecl();
1484 SS.
Adopt(RefExpr->getQualifierLoc());
1487 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1490 S.
Diag(RefExpr->getMemberLoc(),
1491 diag::err_cannot_find_suitable_accessor) << 0
1492 << RefExpr->getPropertyDecl();
1497 RefExpr->getSourceRange().getBegin(), CallArgs,
1498 RefExpr->getSourceRange().getEnd());
1502 bool captureSetValueAsResult) {
1503 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1504 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1505 << 1 << RefExpr->getPropertyDecl();
1513 SS.
Adopt(RefExpr->getQualifierLoc());
1516 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1519 S.
Diag(RefExpr->getMemberLoc(),
1520 diag::err_cannot_find_suitable_accessor) << 1
1521 << RefExpr->getPropertyDecl();
1526 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1527 ArgExprs.push_back(op);
1529 RefExpr->getSourceRange().getBegin(), ArgExprs,
1540 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1541 ObjCPropertyOpBuilder builder(*
this, refExpr,
true);
1542 return builder.buildRValueOperation(E);
1545 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1546 ObjCSubscriptOpBuilder builder(*
this, refExpr,
true);
1547 return builder.buildRValueOperation(E);
1549 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1550 MSPropertyOpBuilder builder(*
this, refExpr,
true);
1551 return builder.buildRValueOperation(E);
1553 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1554 MSPropertyOpBuilder Builder(*
this, RefExpr,
true);
1555 return Builder.buildRValueOperation(E);
1557 llvm_unreachable(
"unknown pseudo-object kind!");
1572 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1573 ObjCPropertyOpBuilder builder(*
this, refExpr,
false);
1574 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1575 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1576 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1579 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1580 MSPropertyOpBuilder builder(*
this, refExpr,
false);
1581 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1583 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1584 MSPropertyOpBuilder Builder(*
this, RefExpr,
false);
1585 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1587 llvm_unreachable(
"unknown pseudo-object kind!");
1602 ExprResult result = CheckPlaceholderExpr(RHS);
1607 bool IsSimpleAssign = opcode == BO_Assign;
1610 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1611 ObjCPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1612 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1614 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1615 ObjCSubscriptOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1616 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1618 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1619 MSPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1620 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1622 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1623 MSPropertyOpBuilder Builder(*
this, RefExpr, IsSimpleAssign);
1624 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1626 llvm_unreachable(
"unknown pseudo-object kind!");
1636 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1652 op, uop->getOpcode(), uop->
getType(), uop->getValueKind(),
1653 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow());
1655 = dyn_cast<CompoundAssignOperator>(syntax)) {
1657 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1660 cop->getValueKind(),
1661 cop->getObjectKind(),
1662 cop->getComputationLHSType(),
1663 cop->getComputationResultType(),
1664 cop->getOperatorLoc(),
1666 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1668 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1670 bop->
getType(), bop->getValueKind(),
1671 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
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
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.
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
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 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
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
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
IgnoreParens - Ignore parentheses.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.