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());
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 {
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 {
346 RefExpr(refExpr), InstanceBase(nullptr) {}
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();
445 if (opcode == BO_Assign) {
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()) {
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);
653 dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
654 StringRef thisPropertyName = prop->
getName();
656 char front = thisPropertyName.front();
659 PropertyName[0] = front;
663 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
664 S.
Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
666 S.
Diag(prop->getLocation(), diag::note_property_declare);
667 S.
Diag(prop1->getLocation(), diag::note_property_declare);
682 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
687 S.
Diag(RefExpr->getLocation(),
688 diag::err_property_function_in_objc_container);
689 S.
Diag(prop->getLocation(), diag::note_property_declare);
695 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
696 assert(InstanceReceiver ==
nullptr);
700 if (RefExpr->isObjectReceiver()) {
701 InstanceReceiver = capture(RefExpr->getBase());
702 syntacticBase = Rebuilder(
S, [=](
Expr *,
unsigned) ->
Expr * {
703 return InstanceReceiver;
704 }).rebuild(syntacticBase);
708 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
709 SyntacticRefExpr = refE;
711 return syntacticBase;
715 ExprResult ObjCPropertyOpBuilder::buildGet() {
718 DiagnoseUnsupportedPropertyUse();
722 if (SyntacticRefExpr)
723 SyntacticRefExpr->setIsMessagingGetter();
726 if (!Getter->isImplicit())
730 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
731 RefExpr->isObjectReceiver()) {
732 assert(InstanceReceiver || RefExpr->isSuperReceiver());
734 GenericLoc, Getter->getSelector(),
738 GenericLoc, Getter->getSelector(),
749 bool captureSetValueAsResult) {
750 if (!findSetter(
false)) {
751 DiagnoseUnsupportedPropertyUse();
755 if (SyntacticRefExpr)
756 SyntacticRefExpr->setIsMessagingSetter();
764 QualType paramType = (*Setter->param_begin())->getType()
767 Setter->getDeclContext(),
779 assert(op &&
"successful assignment left argument invalid?");
784 Expr *args[] = { op };
788 if (!Setter->isImplicit())
790 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
791 RefExpr->isObjectReceiver()) {
793 GenericLoc, SetterSelector, Setter,
798 SetterSelector, Setter,
802 if (!msg.
isInvalid() && captureSetValueAsResult) {
804 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
806 if (CanCaptureValue(arg))
807 msgExpr->
setArg(0, captureValueAsResult(arg));
814 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(
Expr *op) {
817 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
818 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
819 << RefExpr->getSourceRange();
823 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
826 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
828 Getter, RefExpr->getLocation());
832 if (RefExpr->isExplicitProperty() && result.
get()->isRValue()) {
834 QualType propType = RefExpr->getExplicitProperty()
835 ->getUsageType(receiverType);
836 if (result.
get()->getType()->isObjCIdType()) {
839 if (!ptr->isObjCIdType())
846 if (!
S.
Diags.
isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
858 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
871 QualType resultType = Getter->getReturnType();
874 result = buildRValueOperation(op);
880 ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
890 if (tryBuildGetOfReference(LHS, result)) {
896 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
897 <<
unsigned(RefExpr->isImplicitProperty())
899 << LHS->getSourceRange() << RHS->getSourceRange();
906 if (opcode != BO_Assign && !findGetter()) {
907 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
908 << LHS->getSourceRange() << RHS->getSourceRange();
913 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
917 if (
S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
934 if (tryBuildGetOfReference(op, result)) {
940 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
941 <<
unsigned(RefExpr->isImplicitProperty())
944 << op->getSourceRange();
952 assert(RefExpr->isImplicitProperty());
953 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
956 << op->getSourceRange();
960 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
964 if (
S.
getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
966 SyntacticForm->getLocStart()))
968 SyntacticRefExpr->isMessagingGetter());
970 return PseudoOpBuilder::complete(SyntacticForm);
980 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
981 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
988 ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
994 if (!findAtIndexSetter())
998 if (opcode != BO_Assign && !findAtIndexGetter())
1002 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1006 if (
S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1015 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1016 assert(InstanceBase ==
nullptr);
1020 InstanceBase = capture(RefExpr->getBaseExpr());
1021 InstanceKey = capture(RefExpr->getKeyExpr());
1024 Rebuilder(
S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1027 return InstanceBase;
1031 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1033 }).rebuild(syntacticBase);
1035 return syntacticBase;
1054 return OS_Dictionary;
1055 if (!getLangOpts().CPlusPlus ||
1059 if (isa<StringLiteral>(IndexExpr))
1063 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1069 if (RequireCompleteType(FromE->
getExprLoc(), T,
1070 diag::err_objc_index_incomplete_class_type, FromE))
1075 int NoIntegrals=0, NoObjCIdPointers=0;
1079 ->getVisibleConversionFunctions()) {
1081 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1082 QualType CT = Conversion->getConversionType().getNonReferenceType();
1085 ConversionDecls.push_back(Conversion);
1089 ConversionDecls.push_back(Conversion);
1093 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1095 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1096 return OS_Dictionary;
1097 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1099 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1103 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1105 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1106 Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
1132 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1136 Expr *BaseExpr = RefExpr->getBaseExpr();
1149 RefExpr->getKeyExpr());
1154 if (ResultType.
isNull()) {
1156 << BaseExpr->
getType() << arrayRef;
1181 if (!AtIndexGetter &&
S.
getLangOpts().DebuggerObjCLiteral) {
1201 AtIndexGetter->setMethodParams(
S.
Context, Argument, None);
1204 if (!AtIndexGetter) {
1205 if (!receiverIdType) {
1206 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1207 << BaseExpr->
getType() << 0 << arrayRef;
1212 RefExpr->getSourceRange(),
1216 if (AtIndexGetter) {
1217 QualType T = AtIndexGetter->parameters()[0]->getType();
1220 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1221 arrayRef ? diag::err_objc_subscript_index_type
1222 : diag::err_objc_subscript_key_type) << T;
1223 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1224 diag::note_parameter_type) << T;
1227 QualType R = AtIndexGetter->getReturnType();
1229 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1230 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1231 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1232 AtIndexGetter->getDeclName();
1238 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1242 Expr *BaseExpr = RefExpr->getBaseExpr();
1256 RefExpr->getKeyExpr());
1261 if (ResultType.
isNull()) {
1263 << BaseExpr->
getType() << arrayRef;
1290 if (!AtIndexSetter &&
S.
getLangOpts().DebuggerObjCLiteral) {
1308 Params.push_back(
object);
1318 Params.push_back(key);
1319 AtIndexSetter->setMethodParams(
S.
Context, Params, None);
1322 if (!AtIndexSetter) {
1323 if (!receiverIdType) {
1325 diag::err_objc_subscript_method_not_found)
1326 << BaseExpr->
getType() << 1 << arrayRef;
1331 RefExpr->getSourceRange(),
1336 if (AtIndexSetter && arrayRef) {
1337 QualType T = AtIndexSetter->parameters()[1]->getType();
1339 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1340 diag::err_objc_subscript_index_type) << T;
1341 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1342 diag::note_parameter_type) << T;
1345 T = AtIndexSetter->parameters()[0]->getType();
1347 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1348 diag::err_objc_subscript_object_type) << T << arrayRef;
1349 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1350 diag::note_parameter_type) << T;
1354 else if (AtIndexSetter && !arrayRef)
1355 for (
unsigned i=0; i <2; i++) {
1356 QualType T = AtIndexSetter->parameters()[i]->getType();
1359 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1360 diag::err_objc_subscript_key_type) << T;
1362 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1363 diag::err_objc_subscript_dic_object_type) << T;
1364 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1365 diag::note_parameter_type) << T;
1375 ExprResult ObjCSubscriptOpBuilder::buildGet() {
1376 if (!findAtIndexGetter())
1379 QualType receiverType = InstanceBase->getType();
1383 Expr *Index = InstanceKey;
1386 Expr *args[] = { Index };
1387 assert(InstanceBase);
1392 AtIndexGetterSelector, AtIndexGetter,
1403 bool captureSetValueAsResult) {
1404 if (!findAtIndexSetter())
1408 QualType receiverType = InstanceBase->getType();
1409 Expr *Index = InstanceKey;
1412 Expr *args[] = { op, Index };
1417 AtIndexSetterSelector,
1421 if (!msg.
isInvalid() && captureSetValueAsResult) {
1423 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
1425 if (CanCaptureValue(arg))
1426 msgExpr->
setArg(0, captureValueAsResult(arg));
1438 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1440 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1441 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1444 return cast<MSPropertyRefExpr>(Base);
1447 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1448 InstanceBase = capture(RefExpr->getBaseExpr());
1449 std::for_each(CallArgs.begin(), CallArgs.end(),
1450 [
this](
Expr *&Arg) { Arg = capture(Arg); });
1451 syntacticBase = Rebuilder(
S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1454 return InstanceBase;
1456 assert(Idx <= CallArgs.size());
1457 return CallArgs[Idx - 1];
1459 }).rebuild(syntacticBase);
1461 return syntacticBase;
1465 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1466 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1467 << 0 << RefExpr->getPropertyDecl();
1475 SS.
Adopt(RefExpr->getQualifierLoc());
1478 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1481 S.
Diag(RefExpr->getMemberLoc(),
1482 diag::error_cannot_find_suitable_accessor) << 0
1483 << RefExpr->getPropertyDecl();
1488 RefExpr->getSourceRange().getBegin(), CallArgs,
1489 RefExpr->getSourceRange().getEnd());
1493 bool captureSetValueAsResult) {
1494 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1495 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1496 << 1 << RefExpr->getPropertyDecl();
1504 SS.
Adopt(RefExpr->getQualifierLoc());
1507 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1510 S.
Diag(RefExpr->getMemberLoc(),
1511 diag::error_cannot_find_suitable_accessor) << 1
1512 << RefExpr->getPropertyDecl();
1517 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1518 ArgExprs.push_back(op);
1520 RefExpr->getSourceRange().getBegin(), ArgExprs,
1521 op->getSourceRange().getEnd());
1531 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1532 ObjCPropertyOpBuilder builder(*
this, refExpr);
1533 return builder.buildRValueOperation(E);
1536 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1537 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1538 return builder.buildRValueOperation(E);
1540 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1541 MSPropertyOpBuilder builder(*
this, refExpr);
1542 return builder.buildRValueOperation(E);
1544 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1545 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1546 return Builder.buildRValueOperation(E);
1548 llvm_unreachable(
"unknown pseudo-object kind!");
1563 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1564 ObjCPropertyOpBuilder builder(*
this, refExpr);
1565 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1566 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1567 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1570 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1571 MSPropertyOpBuilder builder(*
this, refExpr);
1572 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1574 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1575 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1576 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1578 llvm_unreachable(
"unknown pseudo-object kind!");
1592 ExprResult result = CheckPlaceholderExpr(RHS);
1599 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1600 ObjCPropertyOpBuilder builder(*
this, refExpr);
1601 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1603 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1604 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1605 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1607 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1608 MSPropertyOpBuilder builder(*
this, refExpr);
1609 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1611 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1612 MSPropertyOpBuilder
Builder(*
this, RefExpr);
1613 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1615 llvm_unreachable(
"unknown pseudo-object kind!");
1625 return cast<OpaqueValueExpr>(
E)->getSourceExpr();
1641 uop->getValueKind(), uop->getObjectKind(),
1642 uop->getOperatorLoc());
1644 = dyn_cast<CompoundAssignOperator>(syntax)) {
1646 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1649 cop->getValueKind(),
1650 cop->getObjectKind(),
1651 cop->getComputationLHSType(),
1652 cop->getComputationResultType(),
1653 cop->getOperatorLoc(),
false);
1654 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1656 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1658 bop->
getType(), bop->getValueKind(),
1659 bop->getObjectKind(),
1660 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)
TranslationUnitDecl * getTranslationUnitDecl() const
Defines the clang::Preprocessor interface.
ObjCMethodDecl * getImplicitPropertyGetter() const
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.
ObjCPropertyQueryKind getQueryKind() const
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.
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.