39#include "llvm/ADT/SmallString.h"
48 unsigned MSPropertySubscriptCount;
50 const SpecificRebuilderRefTy &SpecificCallback;
51 Rebuilder(
Sema &S,
const SpecificRebuilderRefTy &SpecificCallback)
52 : S(S), MSPropertySubscriptCount(0),
53 SpecificCallback(SpecificCallback) {}
97 auto *NewBase = rebuild(refExpr->
getBase());
98 ++MSPropertySubscriptCount;
101 SpecificCallback(refExpr->
getIdx(), MSPropertySubscriptCount),
108 if (
auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e))
109 return rebuildObjCPropertyRefExpr(PRE);
110 if (
auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e))
111 return rebuildObjCSubscriptRefExpr(SRE);
112 if (
auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e))
113 return rebuildMSPropertyRefExpr(MSPRE);
114 if (
auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e))
115 return rebuildMSPropertySubscriptExpr(MSPSE);
120 if (
ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
121 e = rebuild(parens->getSubExpr());
128 assert(uop->getOpcode() == UO_Extension);
129 e = rebuild(uop->getSubExpr());
131 S.
Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(),
132 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(),
137 assert(!gse->isResultDependent());
138 unsigned resultIndex = gse->getResultIndex();
139 unsigned numAssocs = gse->getNumAssocs();
143 assocExprs.reserve(numAssocs);
144 assocTypes.reserve(numAssocs);
147 gse->associations()) {
148 Expr *assocExpr = assoc.getAssociationExpr();
149 if (assoc.isSelected())
150 assocExpr = rebuild(assocExpr);
151 assocExprs.push_back(assocExpr);
152 assocTypes.push_back(assoc.getTypeSourceInfo());
156 S.
Context, gse->getGenericLoc(), gse->getControllingExpr(),
157 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
158 gse->containsUnexpandedParameterPack(), resultIndex);
161 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
162 assert(!ce->isConditionDependent());
164 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
165 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
166 rebuiltExpr = rebuild(rebuiltExpr);
169 ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS,
172 ce->isConditionTrue());
175 llvm_unreachable(
"bad expression to rebuild!");
179 class PseudoOpBuilder {
182 unsigned ResultIndex;
189 GenericLoc(genericLoc), IsUnique(IsUnique) {}
191 virtual ~PseudoOpBuilder() {}
194 void addSemanticExpr(
Expr *semantic) {
195 Semantics.push_back(semantic);
199 void addResultSemanticExpr(
Expr *resultExpr) {
201 ResultIndex = Semantics.size();
202 Semantics.push_back(resultExpr);
204 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
205 OVE->setIsUnique(
false);
222 void setResultToLastSemantic() {
224 ResultIndex = Semantics.size() - 1;
226 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
227 OVE->setIsUnique(
false);
231 static bool CanCaptureValue(
Expr *
exp) {
232 if (
exp->isGLValue())
239 return ClassDecl->isTriviallyCopyable();
243 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
246 bool captureSetValueAsResult) = 0;
260 virtual bool captureSetValueAsResult()
const {
return true; }
264 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
276 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
277 RefExpr(refExpr), SyntacticRefExpr(nullptr),
278 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
291 bool findSetter(
bool warn=
true);
293 void DiagnoseUnsupportedPropertyUse();
295 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
300 bool isWeakProperty()
const;
304 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
316 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
317 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
318 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
325 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
327 bool findAtIndexGetter();
328 bool findAtIndexSetter();
334 class MSPropertyOpBuilder :
public PseudoOpBuilder {
343 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
344 RefExpr(refExpr), InstanceBase(nullptr) {}
346 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
347 InstanceBase(nullptr) {
348 RefExpr = getBaseMSProperty(refExpr);
351 Expr *rebuildAndCaptureObject(
Expr *)
override;
354 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;
400 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
401 return cast<OpaqueValueExpr>(e);
407 Semantics, ResultIndex);
412 Expr *syntacticBase = rebuildAndCaptureObject(op);
416 addResultSemanticExpr(getExpr.
get());
418 return complete(syntacticBase);
429 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
438 Expr *semanticRHS = capturedRHS;
441 Semantics.pop_back();
447 if (opcode == BO_Assign) {
448 result = semanticRHS;
450 opcode, capturedRHS->
getType(),
461 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
473 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
475 addSemanticExpr(result.
get());
478 setResultToLastSemantic();
480 return complete(syntactic);
491 Expr *syntacticOp = rebuildAndCaptureObject(op);
502 result = capture(result.
get());
503 setResultToLastSemantic();
512 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
514 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
521 captureSetValueAsResult());
523 addSemanticExpr(result.
get());
527 setResultToLastSemantic();
537 return complete(syntactic);
581bool ObjCPropertyOpBuilder::isWeakProperty()
const {
583 if (RefExpr->isExplicitProperty()) {
590 T = Getter->getReturnType();
598bool ObjCPropertyOpBuilder::findGetter() {
599 if (Getter)
return true;
602 if (RefExpr->isImplicitProperty()) {
603 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
604 GetterSelector = Getter->getSelector();
610 assert(setter &&
"both setter and getter are null - cannot happen");
623 return (Getter !=
nullptr);
630bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
632 if (RefExpr->isImplicitProperty()) {
633 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
639 RefExpr->getImplicitPropertyGetter()->getSelector()
640 .getIdentifierInfoForSlot(0);
659 StringRef thisPropertyName = prop->
getName();
661 char front = thisPropertyName.front();
664 PropertyName[0] = front;
668 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
669 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
672 S.
Diag(prop1->getLocation(), diag::note_property_declare);
687void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
692 S.
Diag(RefExpr->getLocation(),
693 diag::err_property_function_in_objc_container);
700Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
701 assert(InstanceReceiver ==
nullptr);
705 if (RefExpr->isObjectReceiver()) {
706 InstanceReceiver = capture(RefExpr->getBase());
707 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
708 return InstanceReceiver;
709 }).rebuild(syntacticBase);
713 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
714 SyntacticRefExpr = refE;
716 return syntacticBase;
723 DiagnoseUnsupportedPropertyUse();
727 if (SyntacticRefExpr)
728 SyntacticRefExpr->setIsMessagingGetter();
731 if (!Getter->isImplicit())
735 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
736 RefExpr->isObjectReceiver()) {
737 assert(InstanceReceiver || RefExpr->isSuperReceiver());
739 GenericLoc, Getter->getSelector(),
740 Getter, std::nullopt);
743 GenericLoc, Getter->getSelector(), Getter,
754 bool captureSetValueAsResult) {
755 if (!findSetter(
false)) {
756 DiagnoseUnsupportedPropertyUse();
760 if (SyntacticRefExpr)
761 SyntacticRefExpr->setIsMessagingSetter();
769 QualType paramType = (*Setter->param_begin())->getType()
772 Setter->getDeclContext(),
773 ObjCSubstitutionContext::Parameter);
785 assert(op &&
"successful assignment left argument invalid?");
790 Expr *args[] = { op };
794 if (!Setter->isImplicit())
796 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
797 RefExpr->isObjectReceiver()) {
799 GenericLoc, SetterSelector, Setter,
804 SetterSelector, Setter,
808 if (!msg.
isInvalid() && captureSetValueAsResult) {
812 if (CanCaptureValue(arg))
813 msgExpr->
setArg(0, captureValueAsResult(arg));
823 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
824 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
825 << RefExpr->getSourceRange();
829 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
832 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
834 Getter, RefExpr->getLocation());
838 if (RefExpr->isExplicitProperty() && result.
get()->
isPRValue()) {
840 QualType propType = RefExpr->getExplicitProperty()
841 ->getUsageType(receiverType);
845 if (!ptr->isObjCIdType())
851 RefExpr->getLocation()))
862bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
875 QualType resultType = Getter->getReturnType();
878 result = buildRValueOperation(op);
884ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
894 if (tryBuildGetOfReference(LHS, result)) {
900 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
901 <<
unsigned(RefExpr->isImplicitProperty())
910 if (opcode != BO_Assign && !findGetter()) {
911 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
917 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
921 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
938 if (tryBuildGetOfReference(op, result)) {
944 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
945 <<
unsigned(RefExpr->isImplicitProperty())
956 assert(RefExpr->isImplicitProperty());
957 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
964 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
972 SyntacticRefExpr->isMessagingGetter());
974 return PseudoOpBuilder::complete(SyntacticForm);
984ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
985 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
992ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
998 if (!findAtIndexSetter())
1002 if (opcode != BO_Assign && !findAtIndexGetter())
1006 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1010 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1019Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1020 assert(InstanceBase ==
nullptr);
1024 InstanceBase = capture(RefExpr->getBaseExpr());
1025 InstanceKey = capture(RefExpr->getKeyExpr());
1028 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1031 return InstanceBase;
1035 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1037 }).rebuild(syntacticBase);
1039 return syntacticBase;
1063 if (isa<StringLiteral>(IndexExpr))
1067 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1074 diag::err_objc_index_incomplete_class_type, FromE))
1079 int NoIntegrals=0, NoObjCIdPointers=0;
1083 ->getVisibleConversionFunctions()) {
1085 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1086 QualType CT = Conversion->getConversionType().getNonReferenceType();
1089 ConversionDecls.push_back(Conversion);
1093 ConversionDecls.push_back(Conversion);
1097 if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1099 if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1101 if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1103 Diag(FromE->
getExprLoc(), diag::err_objc_subscript_type_conversion)
1107 Diag(FromE->
getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1109 for (
unsigned int i = 0; i < ConversionDecls.size(); i++)
1110 Diag(ConversionDecls[i]->getLocation(),
1111 diag::note_conv_function_declared_at);
1137bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1141 Expr *BaseExpr = RefExpr->getBaseExpr();
1154 RefExpr->getKeyExpr());
1159 if (ResultType.
isNull()) {
1160 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1161 << BaseExpr->
getType() << arrayRef;
1184 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1203 AtIndexGetter->setMethodParams(S.
Context, Argument, std::nullopt);
1206 if (!AtIndexGetter) {
1208 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1209 << BaseExpr->
getType() << 0 << arrayRef;
1214 RefExpr->getSourceRange(),
1218 if (AtIndexGetter) {
1219 QualType T = AtIndexGetter->parameters()[0]->getType();
1222 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1223 arrayRef ? diag::err_objc_subscript_index_type
1224 : diag::err_objc_subscript_key_type) << T;
1225 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1226 diag::note_parameter_type) << T;
1229 QualType R = AtIndexGetter->getReturnType();
1231 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1232 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1233 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1234 AtIndexGetter->getDeclName();
1240bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1244 Expr *BaseExpr = RefExpr->getBaseExpr();
1258 RefExpr->getKeyExpr());
1263 if (ResultType.
isNull()) {
1264 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1265 << BaseExpr->
getType() << arrayRef;
1289 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1308 Params.push_back(
object);
1318 Params.push_back(key);
1319 AtIndexSetter->setMethodParams(S.
Context, Params, std::nullopt);
1322 if (!AtIndexSetter) {
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;
1375ExprResult 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) {
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());
1442 Base = MSPropSubscript->getBase()->IgnoreParens();
1444 return cast<MSPropertyRefExpr>(
Base);
1447Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1448 InstanceBase = capture(RefExpr->getBaseExpr());
1449 llvm::for_each(CallArgs, [
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::err_cannot_find_suitable_accessor) << 0
1482 << RefExpr->getPropertyDecl();
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::err_cannot_find_suitable_accessor) << 1
1511 << RefExpr->getPropertyDecl();
1516 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1517 ArgExprs.push_back(op);
1530 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1531 ObjCPropertyOpBuilder builder(*
this, refExpr,
true);
1532 return builder.buildRValueOperation(E);
1535 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1536 ObjCSubscriptOpBuilder builder(*
this, refExpr,
true);
1537 return builder.buildRValueOperation(E);
1539 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1540 MSPropertyOpBuilder builder(*
this, refExpr,
true);
1541 return builder.buildRValueOperation(E);
1543 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1544 MSPropertyOpBuilder Builder(*
this, RefExpr,
true);
1545 return Builder.buildRValueOperation(E);
1547 llvm_unreachable(
"unknown pseudo-object kind!");
1563 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1564 ObjCPropertyOpBuilder builder(*
this, refExpr,
false);
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,
false);
1572 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1574 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1575 MSPropertyOpBuilder Builder(*
this, RefExpr,
false);
1576 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1578 llvm_unreachable(
"unknown pseudo-object kind!");
1598 bool IsSimpleAssign = opcode == BO_Assign;
1601 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1602 ObjCPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1603 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1605 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1606 ObjCSubscriptOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1607 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1609 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1610 MSPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1611 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1613 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1614 MSPropertyOpBuilder Builder(*
this, RefExpr, IsSimpleAssign);
1615 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1617 llvm_unreachable(
"unknown pseudo-object kind!");
1627 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1643 uop->getValueKind(), uop->getObjectKind(),
1644 uop->getOperatorLoc(), uop->canOverflow(),
1647 = dyn_cast<CompoundAssignOperator>(syntax)) {
1649 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1652 cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
1654 cop->getComputationResultType());
1656 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1658 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1660 bop->
getType(), bop->getValueKind(),
1661 bop->getObjectKind(), bop->getOperatorLoc(),
1664 }
else if (isa<CallExpr>(syntax)) {
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::Preprocessor interface.
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 Expr * stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E)
Given a pseudo-object reference, rebuild it without the opaque values.
static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, Expr *Key)
CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF objects used as dictionary ...
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
SelectorTable & Selectors
CanQualType UnsignedLongTy
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
bool isAssignmentOp() const
Represents a C++ conversion function within a class.
Represents a C++ struct/union/class.
Represents a C++ nested-name-specifier or a global scope specifier.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
CompoundAssignOperator - For compound assignments (e.g.
static CompoundAssignOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures, QualType CompLHSType=QualType(), QualType CompResultType=QualType())
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
bool isObjCContainer() const
Decl::Kind getDeclKind() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
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.
Represents a C11 generic selection.
AssociationTy< false > Association
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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'.
A member reference to an MSPropertyDecl.
NestedNameSpecifierLoc getQualifierLoc() const
MSPropertyDecl * getPropertyDecl() const
Expr * getBaseExpr() const
SourceLocation getMemberLoc() const
MS property subscript expression.
SourceLocation getRBracketLoc() const
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents an ObjC class declaration.
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
ObjCMethodDecl - Represents an instance or class method declaration.
ArrayRef< ParmVarDecl * > parameters() const
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 isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ImplementationControl impControl=None, bool HasRelatedResultType=false)
bool isPropertyAccessor() const
Selector getSelector() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
bool isObjCClassType() const
True if this is equivalent to the 'Class' type, i.e.
Represents one property declaration in an Objective-C interface.
ObjCPropertyQueryKind getQueryKind() const
Selector getSetterName() const
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
const Expr * getBase() const
bool isObjectReceiver() const
bool isExplicitProperty() const
QualType getSuperReceiverType() const
ObjCMethodDecl * getImplicitPropertySetter() const
ObjCInterfaceDecl * getClassReceiver() const
SourceLocation getLocation() const
bool isClassReceiver() const
bool isSuperReceiver() const
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Expr * getKeyExpr() const
Expr * getBaseExpr() const
ObjCMethodDecl * getAtIndexMethodDecl() const
SourceLocation getRBracket() const
ObjCMethodDecl * setAtIndexMethodDecl() const
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parethesized expression, e.g.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
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...
@ OCL_Weak
Reading or writing from this object requires a barrier call.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
Selector getNullarySelector(IdentifierInfo *ID)
Smart pointer class that efficiently represents Objective-C method names.
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
Sema - This implements semantic analysis and AST building for C.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
FPOptionsOverride CurFPFeatureOverrides()
ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
const LangOptions & getLangOpts() const
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op)
Check an increment or decrement of a pseudo-object expression.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CCK_ImplicitConversion)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
DeclContext * getCurLexicalContext() const
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
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.
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 .
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
@ CCK_ImplicitConversion
An implicit conversion.
ExprResult checkPseudoObjectRValue(Expr *E)
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 ...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
DiagnosticsEngine & Diags
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
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...
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
Encodes a location in the source.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
A container of type source information.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isVoidPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isObjCIdType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
bool isDecrementOp() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
bool isIncrementDecrementOp() const
bool isIncrementOp() const
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
@ OK_Ordinary
An ordinary object is located at an address in memory.
LLVM_READONLY bool isLowercase(unsigned char c)
Return true if this character is a lowercase ASCII letter: [a-z].
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
MutableArrayRef< Expr * > MultiExprArg
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)