40#include "llvm/ADT/SmallString.h"
49 unsigned MSPropertySubscriptCount;
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());
132 S.
Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(),
133 uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(),
138 assert(!gse->isResultDependent());
139 unsigned resultIndex = gse->getResultIndex();
140 unsigned numAssocs = gse->getNumAssocs();
144 assocExprs.reserve(numAssocs);
145 assocTypes.reserve(numAssocs);
148 gse->associations()) {
149 Expr *assocExpr = assoc.getAssociationExpr();
150 if (assoc.isSelected())
151 assocExpr = rebuild(assocExpr);
152 assocExprs.push_back(assocExpr);
153 assocTypes.push_back(assoc.getTypeSourceInfo());
156 if (gse->isExprPredicate())
158 S.
Context, gse->getGenericLoc(), gse->getControllingExpr(),
159 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
160 gse->containsUnexpandedParameterPack(), resultIndex);
162 S.
Context, gse->getGenericLoc(), gse->getControllingType(),
163 assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
164 gse->containsUnexpandedParameterPack(), resultIndex);
167 if (
ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
168 assert(!ce->isConditionDependent());
170 Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
171 Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
172 rebuiltExpr = rebuild(rebuiltExpr);
175 ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS,
178 ce->isConditionTrue());
181 llvm_unreachable(
"bad expression to rebuild!");
185 class PseudoOpBuilder {
188 unsigned ResultIndex;
195 GenericLoc(genericLoc), IsUnique(IsUnique) {}
197 virtual ~PseudoOpBuilder() {}
200 void addSemanticExpr(
Expr *semantic) {
201 Semantics.push_back(semantic);
205 void addResultSemanticExpr(
Expr *resultExpr) {
207 ResultIndex = Semantics.size();
208 Semantics.push_back(resultExpr);
210 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
211 OVE->setIsUnique(
false);
228 void setResultToLastSemantic() {
230 ResultIndex = Semantics.size() - 1;
232 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
233 OVE->setIsUnique(
false);
237 static bool CanCaptureValue(
Expr *
exp) {
238 if (
exp->isGLValue())
245 return ClassDecl->isTriviallyCopyable();
249 virtual Expr *rebuildAndCaptureObject(
Expr *) = 0;
252 bool captureSetValueAsResult) = 0;
266 virtual bool captureSetValueAsResult()
const {
return true; }
270 class ObjCPropertyOpBuilder :
public PseudoOpBuilder {
282 : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
283 RefExpr(refExpr), SyntacticRefExpr(nullptr),
284 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
297 bool findSetter(
bool warn=
true);
299 void DiagnoseUnsupportedPropertyUse();
301 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
306 bool isWeakProperty()
const;
310 class ObjCSubscriptOpBuilder :
public PseudoOpBuilder {
322 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
323 RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
324 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
331 Expr *rebuildAndCaptureObject(
Expr *syntacticBase)
override;
333 bool findAtIndexGetter();
334 bool findAtIndexSetter();
340 class MSPropertyOpBuilder :
public PseudoOpBuilder {
349 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
350 RefExpr(refExpr), InstanceBase(nullptr) {}
352 : PseudoOpBuilder(S, refExpr->
getSourceRange().getBegin(), IsUnique),
353 InstanceBase(nullptr) {
354 RefExpr = getBaseMSProperty(refExpr);
357 Expr *rebuildAndCaptureObject(
Expr *)
override;
360 bool captureSetValueAsResult()
const override {
return false; }
375 addSemanticExpr(captured);
390 if (!isa<OpaqueValueExpr>(e)) {
392 setResultToLastSemantic();
400 assert(index < Semantics.size() &&
401 "captured expression not found in semantics!");
402 if (e == Semantics[index])
break;
406 cast<OpaqueValueExpr>(e)->setIsUnique(
false);
407 return cast<OpaqueValueExpr>(e);
413 Semantics, ResultIndex);
418 Expr *syntacticBase = rebuildAndCaptureObject(op);
422 addResultSemanticExpr(getExpr.
get());
424 return complete(syntacticBase);
435 Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
444 Expr *semanticRHS = capturedRHS;
447 Semantics.pop_back();
453 if (opcode == BO_Assign) {
454 result = semanticRHS;
456 opcode, capturedRHS->
getType(),
467 result = S.
BuildBinOp(Sc, opcLoc, nonCompound, opLHS.
get(), semanticRHS);
479 result = buildSet(result.
get(), opcLoc, captureSetValueAsResult());
481 addSemanticExpr(result.
get());
484 setResultToLastSemantic();
486 return complete(syntactic);
497 Expr *syntacticOp = rebuildAndCaptureObject(op);
508 result = capture(result.
get());
509 setResultToLastSemantic();
518 result = S.
BuildBinOp(Sc, opcLoc, BO_Add, result.
get(), one);
520 result = S.
BuildBinOp(Sc, opcLoc, BO_Sub, result.
get(), one);
527 captureSetValueAsResult());
529 addSemanticExpr(result.
get());
533 setResultToLastSemantic();
543 return complete(syntactic);
588bool ObjCPropertyOpBuilder::isWeakProperty()
const {
590 if (RefExpr->isExplicitProperty()) {
605bool ObjCPropertyOpBuilder::findGetter() {
606 if (Getter)
return true;
609 if (RefExpr->isImplicitProperty()) {
610 if ((Getter = RefExpr->getImplicitPropertyGetter())) {
611 GetterSelector = Getter->getSelector();
617 assert(setter &&
"both setter and getter are null - cannot happen");
630 return (Getter !=
nullptr);
637bool ObjCPropertyOpBuilder::findSetter(
bool warn) {
639 if (RefExpr->isImplicitProperty()) {
640 if (
ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
645 const IdentifierInfo *getterName = RefExpr->getImplicitPropertyGetter()
647 .getIdentifierInfoForSlot(0);
666 StringRef thisPropertyName = prop->
getName();
668 char front = thisPropertyName.front();
671 PropertyName[0] = front;
676 if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
677 S.
Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
680 S.
Diag(prop1->getLocation(), diag::note_property_declare);
695void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
700 S.
Diag(RefExpr->getLocation(),
701 diag::err_property_function_in_objc_container);
708Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
709 assert(InstanceReceiver ==
nullptr);
713 if (RefExpr->isObjectReceiver()) {
714 InstanceReceiver = capture(RefExpr->getBase());
715 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned) ->
Expr * {
716 return InstanceReceiver;
717 }).rebuild(syntacticBase);
721 refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->
IgnoreParens()))
722 SyntacticRefExpr = refE;
724 return syntacticBase;
731 DiagnoseUnsupportedPropertyUse();
735 if (SyntacticRefExpr)
736 SyntacticRefExpr->setIsMessagingGetter();
739 if (!Getter->isImplicit())
743 if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
744 RefExpr->isObjectReceiver()) {
745 assert(InstanceReceiver || RefExpr->isSuperReceiver());
747 InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(),
748 Getter, std::nullopt);
751 receiverType, RefExpr->isSuperReceiver(), GenericLoc,
752 Getter->getSelector(), Getter, std::nullopt);
762 bool captureSetValueAsResult) {
763 if (!findSetter(
false)) {
764 DiagnoseUnsupportedPropertyUse();
768 if (SyntacticRefExpr)
769 SyntacticRefExpr->setIsMessagingSetter();
777 QualType paramType = (*Setter->param_begin())->getType()
780 Setter->getDeclContext(),
781 ObjCSubstitutionContext::Parameter);
793 assert(op &&
"successful assignment left argument invalid?");
798 Expr *args[] = { op };
802 if (!Setter->isImplicit())
804 if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
805 RefExpr->isObjectReceiver()) {
807 GenericLoc, SetterSelector,
811 receiverType, RefExpr->isSuperReceiver(), GenericLoc, SetterSelector,
815 if (!msg.
isInvalid() && captureSetValueAsResult) {
819 if (CanCaptureValue(arg))
820 msgExpr->
setArg(0, captureValueAsResult(arg));
830 if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
831 S.
Diag(RefExpr->getLocation(), diag::err_getter_not_found)
832 << RefExpr->getSourceRange();
836 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
839 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
841 Getter, RefExpr->getLocation());
845 if (RefExpr->isExplicitProperty() && result.
get()->
isPRValue()) {
847 QualType propType = RefExpr->getExplicitProperty()
848 ->getUsageType(receiverType);
852 if (!ptr->isObjCIdType())
858 RefExpr->getLocation()))
869bool ObjCPropertyOpBuilder::tryBuildGetOfReference(
Expr *op,
882 QualType resultType = Getter->getReturnType();
885 result = buildRValueOperation(op);
891ObjCPropertyOpBuilder::buildAssignmentOperation(
Scope *Sc,
901 if (tryBuildGetOfReference(LHS, result)) {
907 S.
Diag(opcLoc, diag::err_nosetter_property_assignment)
908 <<
unsigned(RefExpr->isImplicitProperty())
917 if (opcode != BO_Assign && !findGetter()) {
918 S.
Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
924 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
928 if (S.
getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
945 if (tryBuildGetOfReference(op, result)) {
951 S.
Diag(opcLoc, diag::err_nosetter_property_incdec)
952 <<
unsigned(RefExpr->isImplicitProperty())
963 assert(RefExpr->isImplicitProperty());
964 S.
Diag(opcLoc, diag::err_nogetter_property_incdec)
971 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
979 SyntacticRefExpr->isMessagingGetter());
981 return PseudoOpBuilder::complete(SyntacticForm);
991ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(
Expr *op) {
992 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
999ObjCSubscriptOpBuilder::buildAssignmentOperation(
Scope *Sc,
1005 if (!findAtIndexSetter())
1009 if (opcode != BO_Assign && !findAtIndexGetter())
1013 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1017 if (S.
getLangOpts().ObjCAutoRefCount && InstanceBase) {
1026Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1027 assert(InstanceBase ==
nullptr);
1031 InstanceBase = capture(RefExpr->getBaseExpr());
1032 InstanceKey = capture(RefExpr->getKeyExpr());
1035 Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1038 return InstanceBase;
1042 llvm_unreachable(
"Unexpected index for ObjCSubscriptExpr");
1044 }).rebuild(syntacticBase);
1046 return syntacticBase;
1061 GetterSelector, ContainerT,
true );
1066 CheckedConversionKind::Implicit);
1069bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1073 Expr *BaseExpr = RefExpr->getBaseExpr();
1086 RefExpr->getKeyExpr());
1091 if (ResultType.
isNull()) {
1092 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1093 << BaseExpr->
getType() << arrayRef;
1112 AtIndexGetterSelector, ResultType,
true );
1114 if (!AtIndexGetter && S.
getLangOpts().DebuggerObjCLiteral) {
1123 ObjCImplementationControl::Required,
false);
1133 AtIndexGetter->setMethodParams(S.
Context, Argument, std::nullopt);
1136 if (!AtIndexGetter) {
1138 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_method_not_found)
1139 << BaseExpr->
getType() << 0 << arrayRef;
1143 AtIndexGetterSelector, RefExpr->getSourceRange(),
true);
1146 if (AtIndexGetter) {
1147 QualType T = AtIndexGetter->parameters()[0]->getType();
1150 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1151 arrayRef ? diag::err_objc_subscript_index_type
1152 : diag::err_objc_subscript_key_type) <<
T;
1153 S.
Diag(AtIndexGetter->parameters()[0]->getLocation(),
1154 diag::note_parameter_type) <<
T;
1157 QualType R = AtIndexGetter->getReturnType();
1159 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1160 diag::err_objc_indexing_method_result_type) << R << arrayRef;
1161 S.
Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1162 AtIndexGetter->getDeclName();
1168bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1172 Expr *BaseExpr = RefExpr->getBaseExpr();
1186 RefExpr->getKeyExpr());
1191 if (ResultType.
isNull()) {
1192 S.
Diag(BaseExpr->
getExprLoc(), diag::err_objc_subscript_base_type)
1193 << BaseExpr->
getType() << arrayRef;
1213 AtIndexSetterSelector, ResultType,
true );
1215 if (!AtIndexSetter && S.
getLangOpts().DebuggerObjCLiteral) {
1225 ObjCImplementationControl::Required,
false);
1234 Params.push_back(
object);
1244 Params.push_back(key);
1245 AtIndexSetter->setMethodParams(S.
Context, Params, std::nullopt);
1248 if (!AtIndexSetter) {
1251 diag::err_objc_subscript_method_not_found)
1252 << BaseExpr->
getType() << 1 << arrayRef;
1256 AtIndexSetterSelector, RefExpr->getSourceRange(),
true);
1260 if (AtIndexSetter && arrayRef) {
1261 QualType T = AtIndexSetter->parameters()[1]->getType();
1263 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1264 diag::err_objc_subscript_index_type) <<
T;
1265 S.
Diag(AtIndexSetter->parameters()[1]->getLocation(),
1266 diag::note_parameter_type) <<
T;
1269 T = AtIndexSetter->parameters()[0]->getType();
1271 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1272 diag::err_objc_subscript_object_type) <<
T << arrayRef;
1273 S.
Diag(AtIndexSetter->parameters()[0]->getLocation(),
1274 diag::note_parameter_type) <<
T;
1278 else if (AtIndexSetter && !arrayRef)
1279 for (
unsigned i=0; i <2; i++) {
1280 QualType T = AtIndexSetter->parameters()[i]->getType();
1283 S.
Diag(RefExpr->getKeyExpr()->getExprLoc(),
1284 diag::err_objc_subscript_key_type) <<
T;
1286 S.
Diag(RefExpr->getBaseExpr()->getExprLoc(),
1287 diag::err_objc_subscript_dic_object_type) <<
T;
1288 S.
Diag(AtIndexSetter->parameters()[i]->getLocation(),
1289 diag::note_parameter_type) <<
T;
1299ExprResult ObjCSubscriptOpBuilder::buildGet() {
1300 if (!findAtIndexGetter())
1303 QualType receiverType = InstanceBase->getType();
1307 Expr *Index = InstanceKey;
1310 Expr *args[] = { Index };
1311 assert(InstanceBase);
1315 InstanceBase, receiverType, GenericLoc, AtIndexGetterSelector,
1326 bool captureSetValueAsResult) {
1327 if (!findAtIndexSetter())
1331 QualType receiverType = InstanceBase->getType();
1332 Expr *Index = InstanceKey;
1335 Expr *args[] = { op, Index };
1339 InstanceBase, receiverType, GenericLoc, AtIndexSetterSelector,
1342 if (!msg.
isInvalid() && captureSetValueAsResult) {
1346 if (CanCaptureValue(arg))
1347 msgExpr->
setArg(0, captureValueAsResult(arg));
1359 CallArgs.insert(CallArgs.begin(), E->
getIdx());
1361 while (
auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(
Base)) {
1362 CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1363 Base = MSPropSubscript->getBase()->IgnoreParens();
1365 return cast<MSPropertyRefExpr>(
Base);
1368Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(
Expr *syntacticBase) {
1369 InstanceBase = capture(RefExpr->getBaseExpr());
1370 for (
Expr *&Arg : CallArgs)
1372 syntacticBase = Rebuilder(S, [=](
Expr *,
unsigned Idx) ->
Expr * {
1375 return InstanceBase;
1377 assert(Idx <= CallArgs.size());
1378 return CallArgs[Idx - 1];
1380 }).rebuild(syntacticBase);
1382 return syntacticBase;
1386 if (!RefExpr->getPropertyDecl()->hasGetter()) {
1387 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1388 << 0 << RefExpr->getPropertyDecl();
1393 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
1396 SS.
Adopt(RefExpr->getQualifierLoc());
1399 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1402 S.
Diag(RefExpr->getMemberLoc(),
1403 diag::err_cannot_find_suitable_accessor) << 0
1404 << RefExpr->getPropertyDecl();
1410 RefExpr->getSourceRange().getEnd());
1414 bool captureSetValueAsResult) {
1415 if (!RefExpr->getPropertyDecl()->hasSetter()) {
1416 S.
Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1417 << 1 << RefExpr->getPropertyDecl();
1422 const IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
1425 SS.
Adopt(RefExpr->getQualifierLoc());
1428 RefExpr->isArrow() ? tok::arrow : tok::period, SS,
1431 S.
Diag(RefExpr->getMemberLoc(),
1432 diag::err_cannot_find_suitable_accessor) << 1
1433 << RefExpr->getPropertyDecl();
1438 ArgExprs.append(CallArgs.begin(), CallArgs.end());
1439 ArgExprs.push_back(op);
1452 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1453 ObjCPropertyOpBuilder builder(*
this, refExpr,
true);
1454 return builder.buildRValueOperation(E);
1457 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1458 ObjCSubscriptOpBuilder builder(*
this, refExpr,
true);
1459 return builder.buildRValueOperation(E);
1461 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1462 MSPropertyOpBuilder builder(*
this, refExpr,
true);
1463 return builder.buildRValueOperation(E);
1465 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1466 MSPropertyOpBuilder Builder(*
this, RefExpr,
true);
1467 return Builder.buildRValueOperation(E);
1469 llvm_unreachable(
"unknown pseudo-object kind!");
1485 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1486 ObjCPropertyOpBuilder builder(*
this, refExpr,
false);
1487 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1488 }
else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1489 Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1492 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1493 MSPropertyOpBuilder builder(*
this, refExpr,
false);
1494 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1496 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1497 MSPropertyOpBuilder Builder(*
this, RefExpr,
false);
1498 return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1500 llvm_unreachable(
"unknown pseudo-object kind!");
1520 bool IsSimpleAssign = opcode == BO_Assign;
1523 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1524 ObjCPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1525 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1527 = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1528 ObjCSubscriptOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1529 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1531 = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1532 MSPropertyOpBuilder builder(*
this, refExpr, IsSimpleAssign);
1533 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1535 = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1536 MSPropertyOpBuilder Builder(*
this, RefExpr, IsSimpleAssign);
1537 return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1539 llvm_unreachable(
"unknown pseudo-object kind!");
1549 return cast<OpaqueValueExpr>(E)->getSourceExpr();
1565 uop->getValueKind(), uop->getObjectKind(),
1566 uop->getOperatorLoc(), uop->canOverflow(),
1569 = dyn_cast<CompoundAssignOperator>(syntax)) {
1571 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1574 cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
1576 cop->getComputationResultType());
1578 }
else if (
BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1580 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1582 bop->
getType(), bop->getValueKind(),
1583 bop->getObjectKind(), bop->getOperatorLoc(),
1586 }
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 ...
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 parethesized 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)
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.
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'.
Sema - This implements semantic analysis and AST building for C.
Scope * getCurScope() const
Retrieve the parser's current scope.
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)
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.
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.
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.
ExprResult checkPseudoObjectRValue(Expr *E)
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)