41#include "llvm/ADT/SmallString.h"
50 unsigned MSPropertySubscriptCount;
52 const SpecificRebuilderRefTy &SpecificCallback;
53 Rebuilder(
Sema &S,
const SpecificRebuilderRefTy &SpecificCallback)
54 : S(S), MSPropertySubscriptCount(0),
55 SpecificCallback(SpecificCallback) {}
99 auto *NewBase = rebuild(refExpr->
getBase());
100 ++MSPropertySubscriptCount;
103 SpecificCallback(refExpr->
getIdx(), MSPropertySubscriptCount),
110 if (
auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e))
111 return rebuildObjCPropertyRefExpr(PRE);
112 if (
auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e))
113 return rebuildObjCSubscriptRefExpr(SRE);
114 if (
auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e))
115 return rebuildMSPropertyRefExpr(MSPRE);
116 if (
auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e))
117 return rebuildMSPropertySubscriptExpr(MSPSE);
122 if (
ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
123 e = rebuild(parens->getSubExpr());
130 assert(uop->getOpcode() == UO_Extension);
131 e = rebuild(uop->getSubExpr());
133 S.
Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(),
134 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(),
139 assert(!gse->isResultDependent());
140 unsigned resultIndex = gse->getResultIndex();
141 unsigned numAssocs = gse->getNumAssocs();
145 assocExprs.reserve(numAssocs);
146 assocTypes.reserve(numAssocs);
149 gse->associations()) {
150 Expr *assocExpr = assoc.getAssociationExpr();
151 if (assoc.isSelected())
152 assocExpr = rebuild(assocExpr);
153 assocExprs.push_back(assocExpr);
154 assocTypes.push_back(assoc.getTypeSourceInfo());
157 if (gse->isExprPredicate())
159 S.
Context, gse->getGenericLoc(), gse->getControllingExpr(),
160 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
161 gse->containsUnexpandedParameterPack(), resultIndex);
163 S.
Context, gse->getGenericLoc(), gse->getControllingType(),
164 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
165 gse->containsUnexpandedParameterPack(), resultIndex);
168 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
169 assert(!ce->isConditionDependent());
171 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
172 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
173 rebuiltExpr = rebuild(rebuiltExpr);
176 ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS,
179 ce->isConditionTrue());
182 llvm_unreachable(
"bad expression to rebuild!");
186 class PseudoOpBuilder {
189 unsigned ResultIndex;
196 GenericLoc(genericLoc), IsUnique(IsUnique) {}
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);
211 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
212 OVE->setIsUnique(
false);
229 void setResultToLastSemantic() {
231 ResultIndex = Semantics.size() - 1;
233 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
234 OVE->setIsUnique(
false);
238 static bool CanCaptureValue(
Expr *
exp) {
239 if (
exp->isGLValue())
246 return ClassDecl->isTriviallyCopyable();
250 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
253 bool captureSetValueAsResult) = 0;
267 virtual bool captureSetValueAsResult()
const {
return true; }
271 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
283 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
284 RefExpr(refExpr), SyntacticRefExpr(nullptr),
285 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
298 bool findSetter(
bool warn=
true);
300 void DiagnoseUnsupportedPropertyUse();
302 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
307 bool isWeakProperty()
const;
311 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
323 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
324 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
325 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
332 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
334 bool findAtIndexGetter();
335 bool findAtIndexSetter();
341 class MSPropertyOpBuilder :
public PseudoOpBuilder {
350 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
351 RefExpr(refExpr), InstanceBase(nullptr) {}
353 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
354 InstanceBase(nullptr) {
355 RefExpr = getBaseMSProperty(refExpr);
358 Expr *rebuildAndCaptureObject(
Expr *)
override;
361 bool captureSetValueAsResult()
const override {
return false; }
376 addSemanticExpr(captured);
391 if (!isa<OpaqueValueExpr>(e)) {
393 setResultToLastSemantic();
401 assert(index < Semantics.size() &&
402 "captured expression not found in semantics!");
403 if (e == Semantics[index])
break;
407 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
408 return cast<OpaqueValueExpr>(e);
414 Semantics, ResultIndex);
419 Expr *syntacticBase = rebuildAndCaptureObject(op);
423 addResultSemanticExpr(getExpr.
get());
425 return complete(syntacticBase);
436 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
445 Expr *semanticRHS = capturedRHS;
448 Semantics.pop_back();
454 if (opcode == BO_Assign) {
455 result = semanticRHS;
457 opcode, capturedRHS->
getType(),
468 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
480 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
482 addSemanticExpr(result.
get());
485 setResultToLastSemantic();
487 return complete(syntactic);
498 Expr *syntacticOp = rebuildAndCaptureObject(op);
509 result = capture(result.
get());
510 setResultToLastSemantic();
519 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
521 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
528 captureSetValueAsResult());
530 addSemanticExpr(result.
get());
534 setResultToLastSemantic();
544 return complete(syntactic);
589bool ObjCPropertyOpBuilder::isWeakProperty()
const {
591 if (RefExpr->isExplicitProperty()) {
606bool ObjCPropertyOpBuilder::findGetter() {
607 if (Getter)
return true;
610 if (RefExpr->isImplicitProperty()) {
611 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
612 GetterSelector = Getter->getSelector();
618 assert(setter &&
"both setter and getter are null - cannot happen");
631 return (Getter !=
nullptr);
638bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
640 if (RefExpr->isImplicitProperty()) {
641 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
646 const IdentifierInfo *getterName = RefExpr->getImplicitPropertyGetter()
648 .getIdentifierInfoForSlot(0);
667 StringRef thisPropertyName = prop->
getName();
669 char front = thisPropertyName.front();
672 PropertyName[0] = front;
677 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
678 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
681 S.
Diag(prop1->getLocation(), diag::note_property_declare);
696void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
701 S.
Diag(RefExpr->getLocation(),
702 diag::err_property_function_in_objc_container);
709Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
710 assert(InstanceReceiver ==
nullptr);
714 if (RefExpr->isObjectReceiver()) {
715 InstanceReceiver = capture(RefExpr->getBase());
716 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
717 return InstanceReceiver;
718 }).rebuild(syntacticBase);
722 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
723 SyntacticRefExpr = refE;
725 return syntacticBase;
732 DiagnoseUnsupportedPropertyUse();
736 if (SyntacticRefExpr)
737 SyntacticRefExpr->setIsMessagingGetter();
740 if (!Getter->isImplicit())
744 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
745 RefExpr->isObjectReceiver()) {
746 assert(InstanceReceiver || RefExpr->isSuperReceiver());
748 InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(),
749 Getter, std::nullopt);
752 receiverType, RefExpr->isSuperReceiver(), GenericLoc,
753 Getter->getSelector(), Getter, std::nullopt);
763 bool captureSetValueAsResult) {
764 if (!findSetter(
false)) {
765 DiagnoseUnsupportedPropertyUse();
769 if (SyntacticRefExpr)
770 SyntacticRefExpr->setIsMessagingSetter();
778 QualType paramType = (*Setter->param_begin())->getType()
781 Setter->getDeclContext(),
782 ObjCSubstitutionContext::Parameter);
794 assert(op &&
"successful assignment left argument invalid?");
799 Expr *args[] = { op };
803 if (!Setter->isImplicit())
805 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
806 RefExpr->isObjectReceiver()) {
808 GenericLoc, SetterSelector,
812 receiverType, RefExpr->isSuperReceiver(), GenericLoc, SetterSelector,
816 if (!msg.
isInvalid() && captureSetValueAsResult) {
820 if (CanCaptureValue(arg))
821 msgExpr->
setArg(0, captureValueAsResult(arg));
831 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
832 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
833 << RefExpr->getSourceRange();
837 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
840 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
842 Getter, RefExpr->getLocation());
846 if (RefExpr->isExplicitProperty() && result.
get()->
isPRValue()) {
848 QualType propType = RefExpr->getExplicitProperty()
849 ->getUsageType(receiverType);
853 if (!ptr->isObjCIdType())
859 RefExpr->getLocation()))
870bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
883 QualType resultType = Getter->getReturnType();
886 result = buildRValueOperation(op);
892ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
902 if (tryBuildGetOfReference(LHS, result)) {
908 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
909 <<
unsigned(RefExpr->isImplicitProperty())
918 if (opcode != BO_Assign && !findGetter()) {
919 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
925 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
929 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
946 if (tryBuildGetOfReference(op, result)) {
952 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
953 <<
unsigned(RefExpr->isImplicitProperty())
964 assert(RefExpr->isImplicitProperty());
965 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
972 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
980 SyntacticRefExpr->isMessagingGetter());
982 return PseudoOpBuilder::complete(SyntacticForm);
992ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
993 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
1000ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
1006 if (!findAtIndexSetter())
1010 if (opcode != BO_Assign && !findAtIndexGetter())
1014 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1018 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1027Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1028 assert(InstanceBase ==
nullptr);
1032 InstanceBase = capture(RefExpr->getBaseExpr());
1033 InstanceKey = capture(RefExpr->getKeyExpr());
1036 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1039 return InstanceBase;
1043 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1045 }).rebuild(syntacticBase);
1047 return syntacticBase;
1062 GetterSelector, ContainerT,
true );
1067 CheckedConversionKind::Implicit);
1070bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1074 Expr *BaseExpr = RefExpr->getBaseExpr();
1087 RefExpr->getKeyExpr());
1092 if (ResultType.
isNull()) {
1093 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1094 << BaseExpr->
getType() << arrayRef;
1113 AtIndexGetterSelector, ResultType,
true );
1115 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1124 ObjCImplementationControl::Required,
false);
1134 AtIndexGetter->setMethodParams(S.
Context, Argument, std::nullopt);
1137 if (!AtIndexGetter) {
1139 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1140 << BaseExpr->
getType() << 0 << arrayRef;
1144 AtIndexGetterSelector, RefExpr->getSourceRange(),
true);
1147 if (AtIndexGetter) {
1148 QualType T = AtIndexGetter->parameters()[0]->getType();
1151 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1152 arrayRef ? diag::err_objc_subscript_index_type
1153 : diag::err_objc_subscript_key_type) <<
T;
1154 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1155 diag::note_parameter_type) <<
T;
1158 QualType R = AtIndexGetter->getReturnType();
1160 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1161 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1162 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1163 AtIndexGetter->getDeclName();
1169bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1173 Expr *BaseExpr = RefExpr->getBaseExpr();
1187 RefExpr->getKeyExpr());
1192 if (ResultType.
isNull()) {
1193 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1194 << BaseExpr->
getType() << arrayRef;
1214 AtIndexSetterSelector, ResultType,
true );
1216 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1226 ObjCImplementationControl::Required,
false);
1235 Params.push_back(
object);
1245 Params.push_back(key);
1246 AtIndexSetter->setMethodParams(S.
Context, Params, std::nullopt);
1249 if (!AtIndexSetter) {
1252 diag::err_objc_subscript_method_not_found)
1253 << BaseExpr->
getType() << 1 << arrayRef;
1257 AtIndexSetterSelector, RefExpr->getSourceRange(),
true);
1261 if (AtIndexSetter && arrayRef) {
1262 QualType T = AtIndexSetter->parameters()[1]->getType();
1264 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1265 diag::err_objc_subscript_index_type) <<
T;
1266 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1267 diag::note_parameter_type) <<
T;
1270 T = AtIndexSetter->parameters()[0]->getType();
1272 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1273 diag::err_objc_subscript_object_type) <<
T << arrayRef;
1274 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1275 diag::note_parameter_type) <<
T;
1279 else if (AtIndexSetter && !arrayRef)
1280 for (
unsigned i=0; i <2; i++) {
1281 QualType T = AtIndexSetter->parameters()[i]->getType();
1284 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1285 diag::err_objc_subscript_key_type) <<
T;
1287 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1288 diag::err_objc_subscript_dic_object_type) <<
T;
1289 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1290 diag::note_parameter_type) <<
T;
1300ExprResult ObjCSubscriptOpBuilder::buildGet() {
1301 if (!findAtIndexGetter())
1304 QualType receiverType = InstanceBase->getType();
1308 Expr *Index = InstanceKey;
1311 Expr *args[] = { Index };
1312 assert(InstanceBase);
1316 InstanceBase, receiverType, GenericLoc, AtIndexGetterSelector,
1327 bool captureSetValueAsResult) {
1328 if (!findAtIndexSetter())
1332 QualType receiverType = InstanceBase->getType();
1333 Expr *Index = InstanceKey;
1336 Expr *args[] = { op, Index };
1340 InstanceBase, receiverType, GenericLoc, AtIndexSetterSelector,
1343 if (!msg.
isInvalid() && captureSetValueAsResult) {
1347 if (CanCaptureValue(arg))
1348 msgExpr->
setArg(0, captureValueAsResult(arg));
1360 CallArgs.insert(CallArgs.begin(),
E->getIdx());
1362 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(
Base)) {
1363 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1364 Base = MSPropSubscript->getBase()->IgnoreParens();
1366 return cast<MSPropertyRefExpr>(
Base);
1369Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1370 InstanceBase = capture(RefExpr->getBaseExpr());
1371 for (
Expr *&Arg : CallArgs)
1373 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1376 return InstanceBase;
1378 assert(Idx <= CallArgs.size());
1379 return CallArgs[Idx - 1];
1381 }).rebuild(syntacticBase);
1383 return syntacticBase;
1387 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1388 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1389 << 0 << RefExpr->getPropertyDecl();
1394 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
1397 SS.
Adopt(RefExpr->getQualifierLoc());
1400 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1403 S.
Diag(RefExpr->getMemberLoc(),
1404 diag::err_cannot_find_suitable_accessor) << 0
1405 << RefExpr->getPropertyDecl();
1411 RefExpr->getSourceRange().getEnd());
1415 bool captureSetValueAsResult) {
1416 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1417 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1418 << 1 << RefExpr->getPropertyDecl();
1423 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
1426 SS.
Adopt(RefExpr->getQualifierLoc());
1429 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1432 S.
Diag(RefExpr->getMemberLoc(),
1433 diag::err_cannot_find_suitable_accessor) << 1
1434 << RefExpr->getPropertyDecl();
1439 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1440 ArgExprs.push_back(op);
1453 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1454 ObjCPropertyOpBuilder builder(
SemaRef, refExpr,
true);
1455 return builder.buildRValueOperation(
E);
1458 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1459 ObjCSubscriptOpBuilder builder(
SemaRef, refExpr,
true);
1460 return builder.buildRValueOperation(
E);
1462 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1463 MSPropertyOpBuilder builder(
SemaRef, refExpr,
true);
1464 return builder.buildRValueOperation(
E);
1466 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1467 MSPropertyOpBuilder Builder(
SemaRef, RefExpr,
true);
1468 return Builder.buildRValueOperation(
E);
1470 llvm_unreachable(
"unknown pseudo-object kind!");
1486 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1487 ObjCPropertyOpBuilder builder(
SemaRef, refExpr,
false);
1488 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1489 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1490 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1493 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1494 MSPropertyOpBuilder builder(
SemaRef, refExpr,
false);
1495 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1497 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1498 MSPropertyOpBuilder Builder(
SemaRef, RefExpr,
false);
1499 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1501 llvm_unreachable(
"unknown pseudo-object kind!");
1521 bool IsSimpleAssign = opcode == BO_Assign;
1524 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1525 ObjCPropertyOpBuilder builder(
SemaRef, refExpr, IsSimpleAssign);
1526 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1528 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1529 ObjCSubscriptOpBuilder builder(
SemaRef, refExpr, IsSimpleAssign);
1530 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1532 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1533 MSPropertyOpBuilder builder(
SemaRef, refExpr, IsSimpleAssign);
1534 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1536 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1537 MSPropertyOpBuilder Builder(
SemaRef, RefExpr, IsSimpleAssign);
1538 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1540 llvm_unreachable(
"unknown pseudo-object kind!");
1550 return cast<OpaqueValueExpr>(
E)->getSourceExpr();
1562 Expr *syntax =
E->getSyntacticForm();
1567 uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(),
1570 = dyn_cast<CompoundAssignOperator>(syntax)) {
1572 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1575 cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
1577 cop->getComputationResultType());
1579 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1581 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1583 bop->
getType(), bop->getValueKind(),
1584 bop->getObjectKind(), bop->getOperatorLoc(),
1587 }
else if (isa<CallExpr>(syntax)) {
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::Preprocessor interface.
This file declares semantic analysis for Objective-C.
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 ...
This file declares semantic analysis for expressions involving.
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++ 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 * 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.
QualType getReturnType() const
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 accepting an expression predicate.
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
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
bool isPropertyAccessor() 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, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
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 parenthesized expression, e.g.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const 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)
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.
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 getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
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 ...
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE)
CheckSubscriptingKind - This routine decide what type of indexing represented by "FromE" is being don...
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
SemaPseudoObject(Sema &S)
ExprResult checkAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
ExprResult checkIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op)
Check an increment or decrement of a pseudo-object expression.
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
ExprResult checkRValue(Expr *E)
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
FPOptionsOverride CurFPFeatureOverrides()
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
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.
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.
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.
DiagnosticsEngine & Diags
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)
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...
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.
The JSON file list parser is used to communicate input to InstallAPI.
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.
const FunctionProtoType * T
MutableArrayRef< Expr * > MultiExprArg
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)