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(),
459 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
464 result.
get()->getType(),
465 result.
get()->getValueKind(),
467 opLHS.
get()->getType(),
468 result.
get()->getType(),
474 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
476 addSemanticExpr(result.
get());
477 if (!captureSetValueAsResult() && !result.
get()->getType()->isVoidType() &&
478 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
479 setResultToLastSemantic();
481 return complete(syntactic);
492 Expr *syntacticOp = rebuildAndCaptureObject(op);
502 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get()))) {
503 result = capture(result.
get());
504 setResultToLastSemantic();
513 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
515 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
522 captureSetValueAsResult());
524 addSemanticExpr(result.
get());
526 !result.
get()->getType()->isVoidType() &&
527 (result.
get()->isTypeDependent() || CanCaptureValue(result.
get())))
528 setResultToLastSemantic();
533 return complete(syntactic);
577 bool ObjCPropertyOpBuilder::isWeakProperty()
const {
579 if (RefExpr->isExplicitProperty()) {
586 T = Getter->getReturnType();
594 bool ObjCPropertyOpBuilder::findGetter() {
595 if (Getter)
return true;
598 if (RefExpr->isImplicitProperty()) {
599 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
600 GetterSelector = Getter->getSelector();
606 assert(setter &&
"both setter and getter are null - cannot happen");
619 return (Getter !=
nullptr);
626 bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
628 if (RefExpr->isImplicitProperty()) {
629 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
635 RefExpr->getImplicitPropertyGetter()->getSelector()
636 .getIdentifierInfoForSlot(0);
652 if (setter->isPropertyAccessor() && warn)
654 dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
655 StringRef thisPropertyName = prop->
getName();
657 char front = thisPropertyName.front();
660 PropertyName[0] = front;
664 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
665 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
666 << prop << prop1 << setter->getSelector();
668 S.
Diag(prop1->getLocation(), diag::note_property_declare);
683 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
688 S.
Diag(RefExpr->getLocation(),
689 diag::err_property_function_in_objc_container);
690 S.
Diag(prop->getLocation(), diag::note_property_declare);
696 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
697 assert(InstanceReceiver ==
nullptr);
701 if (RefExpr->isObjectReceiver()) {
702 InstanceReceiver = capture(RefExpr->getBase());
703 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
704 return InstanceReceiver;
705 }).rebuild(syntacticBase);
709 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
710 SyntacticRefExpr = refE;
712 return syntacticBase;
716 ExprResult ObjCPropertyOpBuilder::buildGet() {
719 DiagnoseUnsupportedPropertyUse();
723 if (SyntacticRefExpr)
724 SyntacticRefExpr->setIsMessagingGetter();
727 if (!Getter->isImplicit())
731 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
732 RefExpr->isObjectReceiver()) {
733 assert(InstanceReceiver || RefExpr->isSuperReceiver());
735 GenericLoc, Getter->getSelector(),
739 GenericLoc, Getter->getSelector(),
750 bool captureSetValueAsResult) {
751 if (!findSetter(
false)) {
752 DiagnoseUnsupportedPropertyUse();
756 if (SyntacticRefExpr)
757 SyntacticRefExpr->setIsMessagingSetter();
765 QualType paramType = (*Setter->param_begin())->getType()
768 Setter->getDeclContext(),
781 assert(op &&
"successful assignment left argument invalid?");
786 Expr *args[] = { op };
790 if (!Setter->isImplicit())
792 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
793 RefExpr->isObjectReceiver()) {
795 GenericLoc, SetterSelector, Setter,
800 SetterSelector, Setter,
804 if (!msg.
isInvalid() && captureSetValueAsResult) {
806 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
808 if (CanCaptureValue(arg))
809 msgExpr->
setArg(0, captureValueAsResult(arg));
816 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(
Expr *op) {
819 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
820 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
821 << RefExpr->getSourceRange();
825 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
828 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
830 Getter, RefExpr->getLocation());
834 if (RefExpr->isExplicitProperty() && result.
get()->isRValue()) {
836 QualType propType = RefExpr->getExplicitProperty()
837 ->getUsageType(receiverType);
838 if (result.
get()->getType()->isObjCIdType()) {
841 if (!ptr->isObjCIdType())
847 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())
906 if (opcode != BO_Assign && !findGetter()) {
907 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
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())
952 assert(RefExpr->isImplicitProperty());
953 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
960 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
964 if (isWeakProperty() &&
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)
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(),
1107 diag::note_conv_function_declared_at);
1133 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1137 Expr *BaseExpr = RefExpr->getBaseExpr();
1150 RefExpr->getKeyExpr());
1155 if (ResultType.
isNull()) {
1156 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1157 << BaseExpr->
getType() << arrayRef;
1180 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1200 AtIndexGetter->setMethodParams(S.
Context, Argument, None);
1203 if (!AtIndexGetter) {
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()) {
1261 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1262 << BaseExpr->
getType() << arrayRef;
1286 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1304 Params.push_back(
object);
1314 Params.push_back(key);
1315 AtIndexSetter->setMethodParams(S.
Context, Params, None);
1318 if (!AtIndexSetter) {
1321 diag::err_objc_subscript_method_not_found)
1322 << BaseExpr->
getType() << 1 << arrayRef;
1327 RefExpr->getSourceRange(),
1332 if (AtIndexSetter && arrayRef) {
1333 QualType T = AtIndexSetter->parameters()[1]->getType();
1335 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1336 diag::err_objc_subscript_index_type) << T;
1337 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1338 diag::note_parameter_type) << T;
1341 T = AtIndexSetter->parameters()[0]->getType();
1343 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1344 diag::err_objc_subscript_object_type) << T << arrayRef;
1345 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1346 diag::note_parameter_type) << T;
1350 else if (AtIndexSetter && !arrayRef)
1351 for (
unsigned i=0; i <2; i++) {
1352 QualType T = AtIndexSetter->parameters()[i]->getType();
1355 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1356 diag::err_objc_subscript_key_type) << T;
1358 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1359 diag::err_objc_subscript_dic_object_type) << T;
1360 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1361 diag::note_parameter_type) << T;
1371 ExprResult ObjCSubscriptOpBuilder::buildGet() {
1372 if (!findAtIndexGetter())
1375 QualType receiverType = InstanceBase->getType();
1379 Expr *Index = InstanceKey;
1382 Expr *args[] = { Index };
1383 assert(InstanceBase);
1388 AtIndexGetterSelector, AtIndexGetter,
1399 bool captureSetValueAsResult) {
1400 if (!findAtIndexSetter())
1404 QualType receiverType = InstanceBase->getType();
1405 Expr *Index = InstanceKey;
1408 Expr *args[] = { op, Index };
1413 AtIndexSetterSelector,
1417 if (!msg.
isInvalid() && captureSetValueAsResult) {
1419 cast<ObjCMessageExpr>(msg.
get()->IgnoreImplicit());
1421 if (CanCaptureValue(arg))
1422 msgExpr->
setArg(0, captureValueAsResult(arg));
1434 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1436 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1437 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1440 return cast<MSPropertyRefExpr>(Base);
1443 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1444 InstanceBase = capture(RefExpr->getBaseExpr());
1445 llvm::for_each(CallArgs, [
this](
Expr *&Arg) { Arg = capture(Arg); });
1446 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1449 return InstanceBase;
1451 assert(Idx <= CallArgs.size());
1452 return CallArgs[Idx - 1];
1454 }).rebuild(syntacticBase);
1456 return syntacticBase;
1460 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1461 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1462 << 0 << RefExpr->getPropertyDecl();
1470 SS.
Adopt(RefExpr->getQualifierLoc());
1473 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1476 S.
Diag(RefExpr->getMemberLoc(),
1477 diag::err_cannot_find_suitable_accessor) << 0
1478 << RefExpr->getPropertyDecl();
1483 RefExpr->getSourceRange().getBegin(), CallArgs,
1484 RefExpr->getSourceRange().getEnd());
1488 bool captureSetValueAsResult) {
1489 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1490 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1491 << 1 << RefExpr->getPropertyDecl();
1499 SS.
Adopt(RefExpr->getQualifierLoc());
1502 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1505 S.
Diag(RefExpr->getMemberLoc(),
1506 diag::err_cannot_find_suitable_accessor) << 1
1507 << RefExpr->getPropertyDecl();
1512 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1513 ArgExprs.push_back(op);
1515 RefExpr->getSourceRange().getBegin(), ArgExprs,
1526 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1527 ObjCPropertyOpBuilder builder(*
this, refExpr);
1528 return builder.buildRValueOperation(E);
1531 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1532 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1533 return builder.buildRValueOperation(E);
1535 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1536 MSPropertyOpBuilder builder(*
this, refExpr);
1537 return builder.buildRValueOperation(E);
1539 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1540 MSPropertyOpBuilder Builder(*
this, RefExpr);
1541 return Builder.buildRValueOperation(E);
1543 llvm_unreachable(
"unknown pseudo-object kind!");
1558 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1559 ObjCPropertyOpBuilder builder(*
this, refExpr);
1560 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1561 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1562 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1565 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1566 MSPropertyOpBuilder builder(*
this, refExpr);
1567 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1569 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1570 MSPropertyOpBuilder Builder(*
this, RefExpr);
1571 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1573 llvm_unreachable(
"unknown pseudo-object kind!");
1588 ExprResult result = CheckPlaceholderExpr(RHS);
1595 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1596 ObjCPropertyOpBuilder builder(*
this, refExpr);
1597 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1599 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1600 ObjCSubscriptOpBuilder builder(*
this, refExpr);
1601 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1603 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1604 MSPropertyOpBuilder builder(*
this, refExpr);
1605 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1607 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1608 MSPropertyOpBuilder Builder(*
this, RefExpr);
1609 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1611 llvm_unreachable(
"unknown pseudo-object kind!");
1621 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1637 uop->getValueKind(), uop->getObjectKind(),
1638 uop->getOperatorLoc());
1640 = dyn_cast<CompoundAssignOperator>(syntax)) {
1642 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1645 cop->getValueKind(),
1646 cop->getObjectKind(),
1647 cop->getComputationLHSType(),
1648 cop->getComputationResultType(),
1649 cop->getOperatorLoc(),
1651 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1653 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1655 bop->
getType(), bop->getValueKind(),
1656 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)
ParmVarDecl - 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.
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 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...
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.
MutableArrayRef< Expr * > MultiExprArg
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.
void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true)
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.
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics...
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
getName - 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
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.
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.