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());
130 e = rebuild(uop->getSubExpr());
134 uop->getObjectKind(),
135 uop->getOperatorLoc());
139 assert(!gse->isResultDependent());
140 unsigned resultIndex = gse->getResultIndex();
141 unsigned numAssocs = gse->getNumAssocs();
146 for (
unsigned i = 0; i != numAssocs; ++i) {
147 Expr *assoc = gse->getAssocExpr(i);
148 if (i == resultIndex) assoc = rebuild(assoc);
150 assocTypes[i] = gse->getAssocTypeSourceInfo(i);
154 gse->getGenericLoc(),
155 gse->getControllingExpr(),
158 gse->getDefaultLoc(),
160 gse->containsUnexpandedParameterPack(),
164 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
165 assert(!ce->isConditionDependent());
167 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
168 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
169 rebuiltExpr = rebuild(rebuiltExpr);
178 ce->isConditionTrue(),
183 llvm_unreachable(
"bad expression to rebuild!");
187 class PseudoOpBuilder {
190 unsigned ResultIndex;
196 GenericLoc(genericLoc) {}
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);
226 void setResultToLastSemantic() {
228 ResultIndex = Semantics.size() - 1;
232 static bool CanCaptureValue(
Expr *
exp) {
240 return ClassDecl->isTriviallyCopyable();
244 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
247 bool captureSetValueAsResult) = 0;
261 virtual bool captureSetValueAsResult()
const {
return true; }
265 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
277 PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
278 SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr),
292 bool findSetter(
bool warn=
true);
294 void DiagnoseUnsupportedPropertyUse();
296 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
301 bool isWeakProperty()
const;
305 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
317 PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
319 InstanceBase(nullptr), InstanceKey(nullptr),
320 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
327 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
329 bool findAtIndexGetter();
330 bool findAtIndexSetter();
336 class MSPropertyOpBuilder :
public PseudoOpBuilder {
345 PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
346 RefExpr(refExpr), InstanceBase(nullptr) {}
348 : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
349 InstanceBase(nullptr) {
350 RefExpr = getBaseMSProperty(refExpr);
353 Expr *rebuildAndCaptureObject(
Expr *)
override;
356 bool captureSetValueAsResult()
const override {
return false; }
369 addSemanticExpr(captured);
384 if (!isa<OpaqueValueExpr>(e)) {
386 setResultToLastSemantic();
394 assert(index < Semantics.size() &&
395 "captured expression not found in semantics!");
396 if (e == Semantics[index])
break;
399 return cast<OpaqueValueExpr>(e);
405 Semantics, ResultIndex);
410 Expr *syntacticBase = rebuildAndCaptureObject(op);
414 addResultSemanticExpr(getExpr.
get());
416 return complete(syntacticBase);
427 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
436 Expr *semanticRHS = capturedRHS;
439 Semantics.pop_back();
446 result = semanticRHS;
448 opcode, capturedRHS->
getType(),
458 result =
S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
463 result.
get()->getType(),
464 result.
get()->getValueKind(),
466 opLHS.
get()->getType(),
467 result.
get()->getType(),
473 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
475 addSemanticExpr(result.
get());
476 if (!captureSetValueAsResult() && !result.
get()->getType()->isVoidType() &&
477 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
478 setResultToLastSemantic();
480 return complete(syntactic);
491 Expr *syntacticOp = rebuildAndCaptureObject(op);
501 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get()))) {
502 result = capture(result.
get());
503 setResultToLastSemantic();
521 captureSetValueAsResult());
523 addSemanticExpr(result.
get());
525 !result.
get()->getType()->isVoidType() &&
526 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
527 setResultToLastSemantic();
532 return complete(syntactic);
576 bool ObjCPropertyOpBuilder::isWeakProperty()
const {
578 if (RefExpr->isExplicitProperty()) {
581 return !Prop->
hasAttr<IBOutletAttr>();
585 T = Getter->getReturnType();
593 bool ObjCPropertyOpBuilder::findGetter() {
594 if (Getter)
return true;
597 if (RefExpr->isImplicitProperty()) {
598 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
599 GetterSelector = Getter->getSelector();
605 assert(setter &&
"both setter and getter are null - cannot happen");
618 return (Getter !=
nullptr);
625 bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
627 if (RefExpr->isImplicitProperty()) {
628 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
634 RefExpr->getImplicitPropertyGetter()->getSelector()
635 .getIdentifierInfoForSlot(0);
654 StringRef thisPropertyName = prop->
getName();
656 char front = thisPropertyName.front();
659 PropertyName[0] = front;
662 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
663 S.
Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
666 S.
Diag(prop1->getLocation(), diag::note_property_declare);
681 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
686 S.
Diag(RefExpr->getLocation(),
687 diag::err_property_function_in_objc_container);
694 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
695 assert(InstanceReceiver ==
nullptr);
699 if (RefExpr->isObjectReceiver()) {
700 InstanceReceiver = capture(RefExpr->getBase());
701 syntacticBase = Rebuilder(
S, [=](
Expr *,
unsigned) ->
Expr * {
702 return InstanceReceiver;
703 }).rebuild(syntacticBase);
707 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
708 SyntacticRefExpr = refE;
710 return syntacticBase;
714 ExprResult ObjCPropertyOpBuilder::buildGet() {
717 DiagnoseUnsupportedPropertyUse();
721 if (SyntacticRefExpr)
722 SyntacticRefExpr->setIsMessagingGetter();
725 if (!Getter->isImplicit())
729 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
730 RefExpr->isObjectReceiver()) {
731 assert(InstanceReceiver || RefExpr->isSuperReceiver());
733 GenericLoc, Getter->getSelector(),
737 GenericLoc, Getter->getSelector(),
748 bool captureSetValueAsResult) {
749 if (!findSetter(
false)) {
750 DiagnoseUnsupportedPropertyUse();
754 if (SyntacticRefExpr)
755 SyntacticRefExpr->setIsMessagingSetter();
763 QualType paramType = (*Setter->param_begin())->getType()
766 Setter->getDeclContext(),
778 assert(op &&
"successful assignment left argument invalid?");
783 Expr *args[] = { op };
787 if (!Setter->isImplicit())
789 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
790 RefExpr->isObjectReceiver()) {
792 GenericLoc, SetterSelector, Setter,
797 SetterSelector, Setter,
801 if (!msg.
isInvalid() && captureSetValueAsResult) {
803 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
805 if (CanCaptureValue(arg))
806 msgExpr->
setArg(0, captureValueAsResult(arg));
813 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(
Expr *op) {
816 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
817 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
818 << RefExpr->getSourceRange();
822 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
825 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
827 Getter, RefExpr->getLocation());
831 if (RefExpr->isExplicitProperty() && result.
get()->isRValue()) {
833 QualType propType = RefExpr->getExplicitProperty()
834 ->getUsageType(receiverType);
835 if (result.
get()->getType()->isObjCIdType()) {
838 if (!ptr->isObjCIdType())
845 if (!
S.
Diags.
isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
857 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
870 QualType resultType = Getter->getReturnType();
873 result = buildRValueOperation(op);
879 ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
889 if (tryBuildGetOfReference(LHS, result)) {
895 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
896 <<
unsigned(RefExpr->isImplicitProperty())
898 << LHS->getSourceRange() << RHS->getSourceRange();
905 if (opcode !=
BO_Assign && !findGetter()) {
906 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
907 << LHS->getSourceRange() << RHS->getSourceRange();
912 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
916 if (
S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
933 if (tryBuildGetOfReference(op, result)) {
939 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
940 <<
unsigned(RefExpr->isImplicitProperty())
943 << op->getSourceRange();
951 assert(RefExpr->isImplicitProperty());
952 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
955 << op->getSourceRange();
959 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
963 if (
S.
getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
965 SyntacticForm->getLocStart()))
967 SyntacticRefExpr->isMessagingGetter());
969 return PseudoOpBuilder::complete(SyntacticForm);
979 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
980 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
987 ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
993 if (!findAtIndexSetter())
997 if (opcode !=
BO_Assign && !findAtIndexGetter())
1001 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1005 if (
S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1014 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1015 assert(InstanceBase ==
nullptr);
1019 InstanceBase = capture(RefExpr->getBaseExpr());
1020 InstanceKey = capture(RefExpr->getKeyExpr());
1023 Rebuilder(
S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1026 return InstanceBase;
1030 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1032 }).rebuild(syntacticBase);
1034 return syntacticBase;
1053 return OS_Dictionary;
1054 if (!getLangOpts().CPlusPlus ||
1058 if (isa<StringLiteral>(IndexExpr))
1062 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1068 if (RequireCompleteType(FromE->
getExprLoc(), T,
1069 diag::err_objc_index_incomplete_class_type, FromE))
1074 int NoIntegrals=0, NoObjCIdPointers=0;
1078 ->getVisibleConversionFunctions()) {
1080 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1081 QualType CT = Conversion->getConversionType().getNonReferenceType();
1084 ConversionDecls.push_back(Conversion);
1088 ConversionDecls.push_back(Conversion);
1092 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1094 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1095 return OS_Dictionary;
1096 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1098 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1102 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1104 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1105 Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
1131 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1135 Expr *BaseExpr = RefExpr->getBaseExpr();
1148 RefExpr->getKeyExpr());
1153 if (ResultType.
isNull()) {
1155 << BaseExpr->
getType() << arrayRef;
1180 if (!AtIndexGetter &&
S.
getLangOpts().DebuggerObjCLiteral) {
1200 AtIndexGetter->setMethodParams(
S.
Context, Argument, None);
1203 if (!AtIndexGetter) {
1204 if (!receiverIdType) {
1205 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1206 << BaseExpr->
getType() << 0 << arrayRef;
1211 RefExpr->getSourceRange(),
1215 if (AtIndexGetter) {
1216 QualType T = AtIndexGetter->parameters()[0]->getType();
1219 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1220 arrayRef ? diag::err_objc_subscript_index_type
1221 : diag::err_objc_subscript_key_type) << T;
1222 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1223 diag::note_parameter_type) << T;
1226 QualType R = AtIndexGetter->getReturnType();
1228 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1229 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1230 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1231 AtIndexGetter->getDeclName();
1237 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1241 Expr *BaseExpr = RefExpr->getBaseExpr();
1255 RefExpr->getKeyExpr());
1260 if (ResultType.
isNull()) {
1262 << BaseExpr->
getType() << arrayRef;
1289 if (!AtIndexSetter &&
S.
getLangOpts().DebuggerObjCLiteral) {
1307 Params.push_back(
object);
1317 Params.push_back(key);
1318 AtIndexSetter->setMethodParams(
S.
Context, Params, None);
1321 if (!AtIndexSetter) {
1322 if (!receiverIdType) {
1324 diag::err_objc_subscript_method_not_found)
1325 << BaseExpr->
getType() << 1 << arrayRef;
1330 RefExpr->getSourceRange(),
1335 if (AtIndexSetter && arrayRef) {
1336 QualType T = AtIndexSetter->parameters()[1]->getType();
1338 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1339 diag::err_objc_subscript_index_type) << T;
1340 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1341 diag::note_parameter_type) << T;
1344 T = AtIndexSetter->parameters()[0]->getType();
1346 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1347 diag::err_objc_subscript_object_type) << T << arrayRef;
1348 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1349 diag::note_parameter_type) << T;
1353 else if (AtIndexSetter && !arrayRef)
1354 for (
unsigned i=0; i <2; i++) {
1355 QualType T = AtIndexSetter->parameters()[i]->getType();
1358 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1359 diag::err_objc_subscript_key_type) << T;
1361 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1362 diag::err_objc_subscript_dic_object_type) << T;
1363 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1364 diag::note_parameter_type) << T;
1374 ExprResult ObjCSubscriptOpBuilder::buildGet() {
1375 if (!findAtIndexGetter())
1378 QualType receiverType = InstanceBase->getType();
1382 Expr *Index = InstanceKey;
1385 Expr *args[] = { Index };
1386 assert(InstanceBase);
1391 AtIndexGetterSelector, AtIndexGetter,
1402 bool captureSetValueAsResult) {
1403 if (!findAtIndexSetter())
1407 QualType receiverType = InstanceBase->getType();
1408 Expr *Index = InstanceKey;
1411 Expr *args[] = { op, Index };
1416 AtIndexSetterSelector,
1420 if (!msg.
isInvalid() && captureSetValueAsResult) {
1422 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
1424 if (CanCaptureValue(arg))
1425 msgExpr->
setArg(0, captureValueAsResult(arg));
1437 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1439 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1440 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1443 return cast<MSPropertyRefExpr>(Base);
1446 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1447 InstanceBase = capture(RefExpr->getBaseExpr());
1448 std::for_each(CallArgs.begin(), CallArgs.end(),
1449 [
this](
Expr *&Arg) { Arg = capture(Arg); });
1450 syntacticBase = Rebuilder(
S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1453 return InstanceBase;
1455 assert(Idx <= CallArgs.size());
1456 return CallArgs[Idx - 1];
1458 }).rebuild(syntacticBase);
1460 return syntacticBase;
1464 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1465 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1466 << 0 << RefExpr->getPropertyDecl();
1474 SS.
Adopt(RefExpr->getQualifierLoc());
1477 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1480 S.
Diag(RefExpr->getMemberLoc(),
1481 diag::error_cannot_find_suitable_accessor) << 0
1482 << RefExpr->getPropertyDecl();
1487 RefExpr->getSourceRange().getBegin(), CallArgs,
1488 RefExpr->getSourceRange().getEnd());
1492 bool captureSetValueAsResult) {
1493 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1494 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1495 << 1 << RefExpr->getPropertyDecl();
1503 SS.
Adopt(RefExpr->getQualifierLoc());
1506 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1509 S.
Diag(RefExpr->getMemberLoc(),
1510 diag::error_cannot_find_suitable_accessor) << 1
1511 << RefExpr->getPropertyDecl();
1516 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1517 ArgExprs.push_back(op);
1519 RefExpr->getSourceRange().getBegin(), ArgExprs,
1520 op->getSourceRange().getEnd());
1530 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1531 ObjCPropertyOpBuilder builder(*
this, refExpr);
1532 return builder.buildRValueOperation(E);
1535 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1536 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1537 return builder.buildRValueOperation(E);
1539 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1540 MSPropertyOpBuilder builder(*
this, refExpr);
1541 return builder.buildRValueOperation(E);
1543 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1544 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1545 return Builder.buildRValueOperation(E);
1547 llvm_unreachable(
"unknown pseudo-object kind!");
1562 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1563 ObjCPropertyOpBuilder builder(*
this, refExpr);
1564 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1565 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1566 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1569 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1570 MSPropertyOpBuilder builder(*
this, refExpr);
1571 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1573 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1574 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1575 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1577 llvm_unreachable(
"unknown pseudo-object kind!");
1591 ExprResult result = CheckPlaceholderExpr(RHS);
1598 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1599 ObjCPropertyOpBuilder builder(*
this, refExpr);
1600 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1602 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1603 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1604 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1606 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1607 MSPropertyOpBuilder builder(*
this, refExpr);
1608 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1610 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1611 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1612 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1614 llvm_unreachable(
"unknown pseudo-object kind!");
1624 return cast<OpaqueValueExpr>(
E)->getSourceExpr();
1640 uop->getValueKind(), uop->getObjectKind(),
1641 uop->getOperatorLoc());
1643 = dyn_cast<CompoundAssignOperator>(syntax)) {
1645 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1648 cop->getValueKind(),
1649 cop->getObjectKind(),
1650 cop->getComputationLHSType(),
1651 cop->getComputationResultType(),
1652 cop->getOperatorLoc(),
false);
1653 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1655 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1657 bop->
getType(), bop->getValueKind(),
1658 bop->getObjectKind(),
1659 bop->getOperatorLoc(),
false);
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
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'.
Scope * getCurScope() const
Retrieve the parser's current scope.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Smart pointer class that efficiently represents Objective-C method names.
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
SelectorTable & getSelectorTable()
A (possibly-)qualified type.
bool isObjCContainer() const
static Opcode getOpForCompoundAssignment(Opcode Opc)
ObjCInterfaceDecl * getClassInterface()
DeclContext * getCurLexicalContext() const
const LangOptions & getLangOpts() 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 * getAtIndexMethodDecl() const
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
bool isVoidPointerType() const
ParenExpr - This represents a parethesized expression, e.g.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
A container of type source information.
MS property subscript expression.
bool isBlockPointerType() const
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
bool isExplicitProperty() const
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...
DiagnosticsEngine & Diags
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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)
ParmVarDecl - Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
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.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
ObjCInterfaceDecl * getClassReceiver() 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...
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.
Represents a C++ unqualified-id that has been parsed.
Selector getNullarySelector(IdentifierInfo *ID)
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics...
static Expr * stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E)
Given a pseudo-object reference, rebuild it without the opaque values.
bool isSuperReceiver() const
A builtin binary operation expression such as "x + y" or "x <= y".
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
RecordDecl * getDecl() const
Selector getSetterName() const
Expr * getBaseExpr() 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.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
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'.
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
An ordinary object is located at an address in memory.
const Expr * getBase() const
Represents an ObjC class declaration.
ObjCMethodDecl * setAtIndexMethodDecl() const
PropertyAttributeKind getPropertyAttributes() const
MSPropertyDecl * getPropertyDecl() const
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.
bool isAssignmentOp() const
SourceLocation getMemberLoc() const
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
NestedNameSpecifierLoc getQualifierLoc() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
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)
CK_BitCast - A conversion which causes a bit pattern of one type to be reinterpreted as a bit pattern...
TranslationUnitDecl * getTranslationUnitDecl() const
Defines the clang::Preprocessor interface.
ObjCMethodDecl * getImplicitPropertyGetter() const
DeclContext * getDeclContext()
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...
bool isObjCIdType() const
SourceLocation getLocation() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
QualType getObjCIdType() const
Represents the Objective-CC id type.
An expression that sends a message to the given Objective-C object or class.
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.
Represents a C++ conversion function within a class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
ArrayRef< ParmVarDecl * > parameters() const
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
SelectorTable & Selectors
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
SourceLocation getRBracket() const
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...
IdentifierTable & getIdentifierTable()
bool isPropertyAccessor() const
Represents one property declaration in an Objective-C interface.
const T * castAs() const
Member-template castAs<specific 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.
sema::FunctionScopeInfo * getCurFunction() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
bool isObjectReceiver() const
MutableArrayRef< Expr * > MultiExprArg
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
SourceLocation getRBracketLoc() const
CompoundAssignOperator - For compound assignments (e.g.
Represents a C11 generic selection.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true)
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.
bool isClassReceiver() const
Selector getGetterName() const
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
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 .
bool isLValueReferenceType() const
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
Expr * getBaseExpr() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
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.
static LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures...
bool isDecrementOp() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
Decl::Kind getDeclKind() const
CanQualType UnsignedLongTy
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
bool isObjCQualifiedIdType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
QualType getSuperReceiverType() const
Expr * getKeyExpr() const
bool isIncrementOp() const
ObjCPropertyDecl * getExplicitProperty() const
Reading or writing from this object requires a barrier call.
bool isObjCClassType() const
True if this is equivalent to the 'Class' type, i.e.
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
bool isObjCObjectPointerType() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
The parameter type of a method or function.
static LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
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.
static LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
ARCConversionResult CheckObjCARCConversion(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...
bool isIncrementDecrementOp() const
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
ObjCMethodDecl * getImplicitPropertySetter() const
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.