diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/ExprClassification.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 242 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 19 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
13 files changed, 217 insertions, 113 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index dbc890d292d..33ea76ea74a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3004,6 +3004,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, return true; case MSPropertyRefExprClass: + case MSPropertySubscriptExprClass: case CompoundAssignOperatorClass: case VAArgExprClass: case AtomicExprClass: diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index a5a44353a29..a47b03c0afb 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -136,6 +136,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ObjCIvarRefExprClass: case Expr::FunctionParmPackExprClass: case Expr::MSPropertyRefExprClass: + case Expr::MSPropertySubscriptExprClass: case Expr::OMPArraySectionExprClass: return Cl::CL_LValue; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index eb1c4981b25..8780d031c4e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8974,6 +8974,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::CXXTypeidExprClass: case Expr::CXXUuidofExprClass: case Expr::MSPropertyRefExprClass: + case Expr::MSPropertySubscriptExprClass: case Expr::CXXNullPtrLiteralExprClass: case Expr::UserDefinedLiteralClass: case Expr::CXXThisExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 7f2ef495a20..749c9f27b24 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2811,6 +2811,7 @@ recurse: case Expr::ParenListExprClass: case Expr::LambdaExprClass: case Expr::MSPropertyRefExprClass: + case Expr::MSPropertySubscriptExprClass: case Expr::TypoExprClass: // This should no longer exist in the AST by now. case Expr::OMPArraySectionExprClass: llvm_unreachable("unexpected statement kind"); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 37fcd93b480..551c1e05cdf 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1738,6 +1738,13 @@ void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { OS << Node->getPropertyDecl()->getDeclName(); } +void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { + PrintExpr(Node->getBase()); + OS << "["; + PrintExpr(Node->getIdx()); + OS << "]"; +} + void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { switch (Node->getLiteralOperatorKind()) { case UserDefinedLiteral::LOK_Raw: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index e81decd4b55..5711bfc8a2b 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1129,6 +1129,11 @@ void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) { VisitDecl(S->getPropertyDecl()); } +void StmtProfiler::VisitMSPropertySubscriptExpr( + const MSPropertySubscriptExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) { VisitExpr(S); ID.AddBoolean(S->isImplicit()); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index f993a28a13e..9f95e4b6069 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1179,6 +1179,7 @@ CanThrowResult Sema::canThrow(const Expr *E) { return CT_Cannot; case Expr::MSPropertyRefExprClass: + case Expr::MSPropertySubscriptExprClass: llvm_unreachable("Invalid class for expression"); #define STMT(CLASS, PARENT) case Expr::CLASS##Class: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5efd30f6efe..20f1bdbf5e1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3901,6 +3901,13 @@ static bool checkArithmeticOnObjCPointer(Sema &S, return true; } +static bool isMSPropertySubscriptExpr(Sema &S, Expr *Base) { + auto *BaseNoParens = Base->IgnoreParens(); + if (auto *MSProp = dyn_cast<MSPropertyRefExpr>(BaseNoParens)) + return MSProp->getPropertyDecl()->getType()->isArrayType(); + return isa<MSPropertySubscriptExpr>(BaseNoParens); +} + ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, Expr *idx, SourceLocation rbLoc) { @@ -3921,10 +3928,15 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, // operand might be an overloadable type, in which case the overload // resolution for the operator overload should get the first crack // at the overload. + bool IsMSPropertySubscript = false; if (base->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(base); - if (result.isInvalid()) return ExprError(); - base = result.get(); + IsMSPropertySubscript = isMSPropertySubscriptExpr(*this, base); + if (!IsMSPropertySubscript) { + ExprResult result = CheckPlaceholderExpr(base); + if (result.isInvalid()) + return ExprError(); + base = result.get(); + } } if (idx->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(idx); @@ -3939,6 +3951,21 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, VK_LValue, OK_Ordinary, rbLoc); } + // MSDN, property (C++) + // https://msdn.microsoft.com/en-us/library/yhfk0thd(v=vs.120).aspx + // This attribute can also be used in the declaration of an empty array in a + // class or structure definition. For example: + // __declspec(property(get=GetX, put=PutX)) int x[]; + // The above statement indicates that x[] can be used with one or more array + // indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), + // and p->x[a][b] = i will be turned into p->PutX(a, b, i); + if (IsMSPropertySubscript) { + // Build MS property subscript expression if base is MS property reference + // or MS property subscript. + return new (Context) MSPropertySubscriptExpr( + base, idx, Context.PseudoObjectTy, VK_LValue, OK_Ordinary, rbLoc); + } + // Use C++ overloaded-operator rules if either operand has record // type. The spec says to do this if either type is *overloadable*, // but enum types can't declare subscript operators or conversion diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 8998a7e8bc9..f94fb17c8b8 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -44,17 +44,76 @@ using namespace sema; namespace { // Basically just a very focused copy of TreeTransform. - template <class T> struct Rebuilder { + struct Rebuilder { Sema &S; - Rebuilder(Sema &S) : S(S) {} + unsigned MSPropertySubscriptCount; + typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy; + const SpecificRebuilderRefTy &SpecificCallback; + Rebuilder(Sema &S, const SpecificRebuilderRefTy &SpecificCallback) + : S(S), MSPropertySubscriptCount(0), + SpecificCallback(SpecificCallback) {} + + Expr *rebuildObjCPropertyRefExpr(ObjCPropertyRefExpr *refExpr) { + // Fortunately, the constraint that we're rebuilding something + // with a base limits the number of cases here. + if (refExpr->isClassReceiver() || refExpr->isSuperReceiver()) + return refExpr; - T &getDerived() { return static_cast<T&>(*this); } + if (refExpr->isExplicitProperty()) { + return new (S.Context) ObjCPropertyRefExpr( + refExpr->getExplicitProperty(), refExpr->getType(), + refExpr->getValueKind(), refExpr->getObjectKind(), + refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); + } + return new (S.Context) ObjCPropertyRefExpr( + refExpr->getImplicitPropertyGetter(), + refExpr->getImplicitPropertySetter(), refExpr->getType(), + refExpr->getValueKind(), refExpr->getObjectKind(), + refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); + } + Expr *rebuildObjCSubscriptRefExpr(ObjCSubscriptRefExpr *refExpr) { + assert(refExpr->getBaseExpr()); + assert(refExpr->getKeyExpr()); + + return new (S.Context) ObjCSubscriptRefExpr( + SpecificCallback(refExpr->getBaseExpr(), 0), + SpecificCallback(refExpr->getKeyExpr(), 1), refExpr->getType(), + refExpr->getValueKind(), refExpr->getObjectKind(), + refExpr->getAtIndexMethodDecl(), refExpr->setAtIndexMethodDecl(), + refExpr->getRBracket()); + } + Expr *rebuildMSPropertyRefExpr(MSPropertyRefExpr *refExpr) { + assert(refExpr->getBaseExpr()); + + return new (S.Context) MSPropertyRefExpr( + SpecificCallback(refExpr->getBaseExpr(), 0), + refExpr->getPropertyDecl(), refExpr->isArrow(), refExpr->getType(), + refExpr->getValueKind(), refExpr->getQualifierLoc(), + refExpr->getMemberLoc()); + } + Expr *rebuildMSPropertySubscriptExpr(MSPropertySubscriptExpr *refExpr) { + assert(refExpr->getBase()); + assert(refExpr->getIdx()); + + auto *NewBase = rebuild(refExpr->getBase()); + ++MSPropertySubscriptCount; + return new (S.Context) MSPropertySubscriptExpr( + NewBase, + SpecificCallback(refExpr->getIdx(), MSPropertySubscriptCount), + refExpr->getType(), refExpr->getValueKind(), refExpr->getObjectKind(), + refExpr->getRBracketLoc()); + } Expr *rebuild(Expr *e) { // Fast path: nothing to look through. - if (typename T::specific_type *specific - = dyn_cast<typename T::specific_type>(e)) - return getDerived().rebuildSpecific(specific); + if (auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e)) + return rebuildObjCPropertyRefExpr(PRE); + if (auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e)) + return rebuildObjCSubscriptRefExpr(SRE); + if (auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e)) + return rebuildMSPropertyRefExpr(MSPRE); + if (auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e)) + return rebuildMSPropertySubscriptExpr(MSPSE); // Otherwise, we should look through and rebuild anything that // IgnoreParens would. @@ -125,72 +184,6 @@ namespace { } }; - struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> { - Expr *NewBase; - ObjCPropertyRefRebuilder(Sema &S, Expr *newBase) - : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {} - - typedef ObjCPropertyRefExpr specific_type; - Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) { - // Fortunately, the constraint that we're rebuilding something - // with a base limits the number of cases here. - assert(refExpr->isObjectReceiver()); - - if (refExpr->isExplicitProperty()) { - return new (S.Context) - ObjCPropertyRefExpr(refExpr->getExplicitProperty(), - refExpr->getType(), refExpr->getValueKind(), - refExpr->getObjectKind(), refExpr->getLocation(), - NewBase); - } - return new (S.Context) - ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(), - refExpr->getImplicitPropertySetter(), - refExpr->getType(), refExpr->getValueKind(), - refExpr->getObjectKind(),refExpr->getLocation(), - NewBase); - } - }; - - struct ObjCSubscriptRefRebuilder : Rebuilder<ObjCSubscriptRefRebuilder> { - Expr *NewBase; - Expr *NewKeyExpr; - ObjCSubscriptRefRebuilder(Sema &S, Expr *newBase, Expr *newKeyExpr) - : Rebuilder<ObjCSubscriptRefRebuilder>(S), - NewBase(newBase), NewKeyExpr(newKeyExpr) {} - - typedef ObjCSubscriptRefExpr specific_type; - Expr *rebuildSpecific(ObjCSubscriptRefExpr *refExpr) { - assert(refExpr->getBaseExpr()); - assert(refExpr->getKeyExpr()); - - return new (S.Context) - ObjCSubscriptRefExpr(NewBase, - NewKeyExpr, - refExpr->getType(), refExpr->getValueKind(), - refExpr->getObjectKind(),refExpr->getAtIndexMethodDecl(), - refExpr->setAtIndexMethodDecl(), - refExpr->getRBracket()); - } - }; - - struct MSPropertyRefRebuilder : Rebuilder<MSPropertyRefRebuilder> { - Expr *NewBase; - MSPropertyRefRebuilder(Sema &S, Expr *newBase) - : Rebuilder<MSPropertyRefRebuilder>(S), NewBase(newBase) {} - - typedef MSPropertyRefExpr specific_type; - Expr *rebuildSpecific(MSPropertyRefExpr *refExpr) { - assert(refExpr->getBaseExpr()); - - return new (S.Context) - MSPropertyRefExpr(NewBase, refExpr->getPropertyDecl(), - refExpr->isArrow(), refExpr->getType(), - refExpr->getValueKind(), refExpr->getQualifierLoc(), - refExpr->getMemberLoc()); - } - }; - class PseudoOpBuilder { public: Sema &S; @@ -329,11 +322,19 @@ namespace { class MSPropertyOpBuilder : public PseudoOpBuilder { MSPropertyRefExpr *RefExpr; OpaqueValueExpr *InstanceBase; + SmallVector<Expr *, 4> CallArgs; + + MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E); public: MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), RefExpr(refExpr), InstanceBase(nullptr) {} + MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr) + : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), + InstanceBase(nullptr) { + RefExpr = getBaseMSProperty(refExpr); + } Expr *rebuildAndCaptureObject(Expr *) override; ExprResult buildGet() override; @@ -674,9 +675,9 @@ Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { // form to use the OVE as its base. if (RefExpr->isObjectReceiver()) { InstanceReceiver = capture(RefExpr->getBase()); - - syntacticBase = - ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase); + syntacticBase = Rebuilder(S, [=](Expr *, unsigned) -> Expr * { + return InstanceReceiver; + }).rebuild(syntacticBase); } if (ObjCPropertyRefExpr * @@ -994,11 +995,19 @@ Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { // form to use the OVE as its base expression. InstanceBase = capture(RefExpr->getBaseExpr()); InstanceKey = capture(RefExpr->getKeyExpr()); - + syntacticBase = - ObjCSubscriptRefRebuilder(S, InstanceBase, - InstanceKey).rebuild(syntacticBase); - + Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { + switch (Idx) { + case 0: + return InstanceBase; + case 1: + return InstanceKey; + default: + llvm_unreachable("Unexpected index for ObjCSubscriptExpr"); + } + }).rebuild(syntacticBase); + return syntacticBase; } @@ -1400,11 +1409,30 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, // MSVC __declspec(property) references //===----------------------------------------------------------------------===// +MSPropertyRefExpr * +MSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr *E) { + CallArgs.insert(CallArgs.begin(), E->getIdx()); + Expr *Base = E->getBase()->IgnoreParens(); + while (auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) { + CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx()); + Base = MSPropSubscript->getBase()->IgnoreParens(); + } + return cast<MSPropertyRefExpr>(Base); +} + Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { InstanceBase = capture(RefExpr->getBaseExpr()); - - syntacticBase = - MSPropertyRefRebuilder(S, InstanceBase).rebuild(syntacticBase); + std::for_each(CallArgs.begin(), CallArgs.end(), + [this](Expr *&Arg) { Arg = capture(Arg); }); + syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { + switch (Idx) { + case 0: + return InstanceBase; + default: + assert(Idx <= CallArgs.size()); + return CallArgs[Idx - 1]; + } + }).rebuild(syntacticBase); return syntacticBase; } @@ -1432,9 +1460,8 @@ ExprResult MSPropertyOpBuilder::buildGet() { return ExprError(); } - MultiExprArg ArgExprs; return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(), - RefExpr->getSourceRange().getBegin(), ArgExprs, + RefExpr->getSourceRange().getBegin(), CallArgs, RefExpr->getSourceRange().getEnd()); } @@ -1462,7 +1489,8 @@ ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl, return ExprError(); } - SmallVector<Expr*, 1> ArgExprs; + SmallVector<Expr*, 4> ArgExprs; + ArgExprs.append(CallArgs.begin(), CallArgs.end()); ArgExprs.push_back(op); return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(), RefExpr->getSourceRange().getBegin(), ArgExprs, @@ -1488,6 +1516,10 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) { = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { MSPropertyOpBuilder builder(*this, refExpr); return builder.buildRValueOperation(E); + } else if (MSPropertySubscriptExpr *RefExpr = + dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { + MSPropertyOpBuilder Builder(*this, RefExpr); + return Builder.buildRValueOperation(E); } else { llvm_unreachable("unknown pseudo-object kind!"); } @@ -1514,6 +1546,10 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { MSPropertyOpBuilder builder(*this, refExpr); return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); + } else if (MSPropertySubscriptExpr *RefExpr + = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { + MSPropertyOpBuilder Builder(*this, RefExpr); + return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else { llvm_unreachable("unknown pseudo-object kind!"); } @@ -1545,8 +1581,12 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (MSPropertyRefExpr *refExpr = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr); - return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); + MSPropertyOpBuilder builder(*this, refExpr); + return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); + } else if (MSPropertySubscriptExpr *RefExpr + = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { + MSPropertyOpBuilder Builder(*this, RefExpr); + return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else { llvm_unreachable("unknown pseudo-object kind!"); } @@ -1556,29 +1596,11 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, /// values. Basically, undo the behavior of rebuildAndCaptureObject. /// This should never operate in-place. static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { - Expr *opaqueRef = E->IgnoreParens(); - if (ObjCPropertyRefExpr *refExpr - = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { - // Class and super property references don't have opaque values in them. - if (refExpr->isClassReceiver() || refExpr->isSuperReceiver()) - return E; - - assert(refExpr->isObjectReceiver() && "Unknown receiver kind?"); - OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase()); - return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E); - } else if (ObjCSubscriptRefExpr *refExpr - = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { - OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr()); - OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr()); - return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(), - keyOVE->getSourceExpr()).rebuild(E); - } else if (MSPropertyRefExpr *refExpr - = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { - OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr()); - return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E); - } else { - llvm_unreachable("unknown pseudo-object kind!"); - } + return Rebuilder(S, + [=](Expr *E, unsigned) -> Expr * { + return cast<OpaqueValueExpr>(E)->getSourceExpr(); + }) + .rebuild(E); } /// Given a pseudo-object expression, recreate what it looks like diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index efc79d0c97e..1ea17981a2d 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6919,6 +6919,25 @@ TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) { } template <typename Derived> +ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr( + MSPropertySubscriptExpr *E) { + auto BaseRes = getDerived().TransformExpr(E->getBase()); + if (BaseRes.isInvalid()) + return ExprError(); + auto IdxRes = getDerived().TransformExpr(E->getIdx()); + if (IdxRes.isInvalid()) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && + BaseRes.get() == E->getBase() && + IdxRes.get() == E->getIdx()) + return E; + + return getDerived().RebuildArraySubscriptExpr( + BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc()); +} + +template <typename Derived> StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); if (TryBlock.isInvalid()) diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 3865d5dfb2b..124e0dab231 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1662,6 +1662,13 @@ void ASTStmtReader::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) { E->TheDecl = ReadDeclAs<MSPropertyDecl>(Record, Idx); } +void ASTStmtReader::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) { + VisitExpr(E); + E->setBase(Reader.ReadSubExpr()); + E->setIdx(Reader.ReadSubExpr()); + E->setRBracketLoc(ReadSourceLocation(Record, Idx)); +} + void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); E->setSourceRange(ReadSourceRange(Record, Idx)); @@ -3086,6 +3093,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_PROPERTY_REF_EXPR: S = new (Context) MSPropertyRefExpr(Empty); break; + case EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR: + S = new (Context) MSPropertySubscriptExpr(Empty); + break; case EXPR_CXX_UUIDOF_TYPE: S = new (Context) CXXUuidofExpr(Empty, false); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 1f41db3cb71..e93fa810651 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1689,6 +1689,14 @@ void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) { Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR; } +void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) { + VisitExpr(E); + Writer.AddStmt(E->getBase()); + Writer.AddStmt(E->getIdx()); + Writer.AddSourceLocation(E->getRBracketLoc(), Record); + Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR; +} + void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); Writer.AddSourceRange(E->getSourceRange(), Record); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 37e13801bda..32f055b8c4b 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -755,6 +755,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXUuidofExprClass: case Stmt::CXXFoldExprClass: case Stmt::MSPropertyRefExprClass: + case Stmt::MSPropertySubscriptExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::DependentScopeDeclRefExprClass: case Stmt::ArrayTypeTraitExprClass: |

