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)
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
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
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics...
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.
Expr - 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 FunctionProtoType * T
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.
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
SourceLocation getLocStart() const LLVM_READONLY
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.