From 7decc9e4ea6c56ffce14d25f542f5eda3eeba97a Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 18 Nov 2010 06:31:45 +0000 Subject: [PATCH] Calculate the value kind of an expression when it's created and store it on the expression node. Also store an "object kind", which distinguishes ordinary "addressed" l-values (like variable references and pointer dereferences) and bitfield, @property, and vector-component l-values. Currently we're not using these for much, but I aim to switch pretty much everything calculating l-valueness over to them. For now they shouldn't necessarily be trusted. llvm-svn: 119685 --- clang/include/clang/AST/Expr.h | 209 ++++++++++------- clang/include/clang/AST/ExprCXX.h | 112 +++++---- clang/include/clang/AST/ExprObjC.h | 92 +++++--- clang/include/clang/AST/Stmt.h | 3 +- clang/include/clang/Basic/Specifiers.h | 17 ++ clang/include/clang/Sema/Sema.h | 19 +- clang/lib/AST/ASTImporter.cpp | 15 +- clang/lib/AST/DeclTemplate.cpp | 1 + clang/lib/AST/Expr.cpp | 62 +++-- clang/lib/AST/ExprCXX.cpp | 34 +-- clang/lib/AST/ExprClassification.cpp | 4 +- clang/lib/AST/StmtDumper.cpp | 32 +-- clang/lib/CodeGen/CGBlocks.cpp | 28 +-- clang/lib/CodeGen/CGObjC.cpp | 8 +- clang/lib/Rewrite/RewriteObjC.cpp | 152 +++++++----- clang/lib/Sema/SemaCXXCast.cpp | 55 +++-- clang/lib/Sema/SemaChecking.cpp | 5 +- clang/lib/Sema/SemaDeclCXX.cpp | 35 ++- clang/lib/Sema/SemaExpr.cpp | 218 +++++++++++++----- clang/lib/Sema/SemaExprCXX.cpp | 76 ++++-- clang/lib/Sema/SemaExprObjC.cpp | 57 +++-- clang/lib/Sema/SemaObjCProperty.cpp | 12 +- clang/lib/Sema/SemaOverload.cpp | 108 +++++---- clang/lib/Sema/SemaTemplate.cpp | 20 +- clang/lib/Sema/TreeTransform.h | 54 +++-- clang/lib/Serialization/ASTReaderStmt.cpp | 10 +- clang/lib/Serialization/ASTWriterStmt.cpp | 6 +- .../dcl.init/dcl.init.ref/p5-examples.cpp | 10 +- 28 files changed, 903 insertions(+), 551 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index c1c687b1d92a..20fd7905eb73 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -55,24 +55,18 @@ class Expr : public Stmt { virtual void ANCHOR(); // key function. protected: - Expr(StmtClass SC, QualType T, bool TD, bool VD) : Stmt(SC) { + Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, + bool TD, bool VD) : Stmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; - ExprBits.ValueKind = 0; + ExprBits.ValueKind = VK; + ExprBits.ObjectKind = OK; setType(T); } /// \brief Construct an empty expression. explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } - /// getValueKind - The value kind that this cast produces. - ExprValueKind getValueKind() const { - return static_cast(ExprBits.ValueKind); - } - - /// setValueKind - Set the value kind this cast produces. - void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; } - public: QualType getType() const { return TR; } void setType(QualType t) { @@ -269,6 +263,32 @@ public: return ClassifyImpl(Ctx, &Loc); } + /// getValueKindForType - Given a formal return or parameter type, + /// give its value kind. + static ExprValueKind getValueKindForType(QualType T) { + if (const ReferenceType *RT = T->getAs()) + return isa(RT) ? VK_LValue : VK_XValue; + return VK_RValue; + } + + /// getValueKind - The value kind that this expression produces. + ExprValueKind getValueKind() const { + return static_cast(ExprBits.ValueKind); + } + + /// getObjectKind - The object kind that this expression produces. + /// Object kinds are meaningful only for expressions that yield an + /// l-value or x-value. + ExprObjectKind getObjectKind() const { + return static_cast(ExprBits.ObjectKind); + } + + /// setValueKind - Set the value kind produced by this expression. + void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; } + + /// setObjectKind - Set the object kind produced by this expression. + void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; } + private: Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const; @@ -551,12 +571,12 @@ class DeclRefExpr : public Expr { DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T); + QualType T, ExprValueKind VK); DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, - QualType T); + QualType T, ExprValueKind VK); /// \brief Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) @@ -567,8 +587,9 @@ class DeclRefExpr : public Expr { void computeDependence(); public: - DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) : - Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { + DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) : + Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false), + DecoratedD(d, 0), Loc(l) { computeDependence(); } @@ -577,7 +598,7 @@ public: SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, - QualType T, + QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs = 0); static DeclRefExpr *Create(ASTContext &Context, @@ -585,7 +606,7 @@ public: SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, - QualType T, + QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs = 0); /// \brief Construct an empty declaration reference expression. @@ -730,8 +751,9 @@ private: IdentType Type; public: PredefinedExpr(SourceLocation l, QualType type, IdentType IT) - : Expr(PredefinedExprClass, type, type->isDependentType(), - type->isDependentType()), Loc(l), Type(IT) {} + : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, + type->isDependentType(), type->isDependentType()), + Loc(l), Type(IT) {} /// \brief Construct an empty predefined expression. explicit PredefinedExpr(EmptyShell Empty) @@ -817,7 +839,8 @@ public: // or UnsignedLongLongTy IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) - : Expr(IntegerLiteralClass, type, false, false), Loc(l) { + : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false), + Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); setValue(C, V); } @@ -854,8 +877,8 @@ class CharacterLiteral : public Expr { public: // type should be IntTy CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) - : Expr(CharacterLiteralClass, type, false, false), Value(value), Loc(l), - IsWide(iswide) { + : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false), + Value(value), Loc(l), IsWide(iswide) { } /// \brief Construct an empty character literal. @@ -889,7 +912,7 @@ class FloatingLiteral : public Expr { FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, false, false), + : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false), IsExact(isexact), Loc(L) { setValue(C, V); } @@ -940,7 +963,8 @@ class ImaginaryLiteral : public Expr { Stmt *Val; public: ImaginaryLiteral(Expr *val, QualType Ty) - : Expr(ImaginaryLiteralClass, Ty, false, false), Val(val) {} + : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false), + Val(val) {} /// \brief Build an empty imaginary literal. explicit ImaginaryLiteral(EmptyShell Empty) @@ -984,7 +1008,8 @@ class StringLiteral : public Expr { unsigned NumConcatenated; SourceLocation TokLocs[1]; - StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {} + StringLiteral(QualType Ty) : + Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false) {} public: /// This is the "fully general" constructor that allows representation of @@ -1071,6 +1096,7 @@ class ParenExpr : public Expr { public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) : Expr(ParenExprClass, val->getType(), + val->getValueKind(), val->getObjectKind(), val->isTypeDependent(), val->isValueDependent()), L(l), R(r), Val(val) {} @@ -1123,8 +1149,9 @@ private: Stmt *Val; public: - UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l) - : Expr(UnaryOperatorClass, type, + UnaryOperator(Expr *input, Opcode opc, QualType type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l) + : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), input->isValueDependent()), Opc(opc), Loc(l), Val(input) {} @@ -1410,7 +1437,7 @@ public: SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfExprClass, resultType, + Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. TInfo->getType()->isDependentType()), @@ -1421,7 +1448,7 @@ public: SizeOfAlignOfExpr(bool issizeof, Expr *E, QualType resultType, SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfExprClass, resultType, + Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. E->isTypeDependent()), @@ -1495,8 +1522,9 @@ class ArraySubscriptExpr : public Expr { SourceLocation RBracketLoc; public: ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation rbracketloc) - : Expr(ArraySubscriptExprClass, t, + : Expr(ArraySubscriptExprClass, t, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent()), RBracketLoc(rbracketloc) { @@ -1576,11 +1604,11 @@ class CallExpr : public Expr { protected: // This version of the constructor is for derived classes. CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs, - QualType t, SourceLocation rparenloc); + QualType t, ExprValueKind VK, SourceLocation rparenloc); public: CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, - SourceLocation rparenloc); + ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty); @@ -1716,8 +1744,9 @@ class MemberExpr : public Expr { public: MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - const DeclarationNameInfo &NameInfo, QualType ty) - : Expr(MemberExprClass, ty, + const DeclarationNameInfo &NameInfo, QualType ty, + ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), base->isValueDependent()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), @@ -1730,8 +1759,9 @@ public: // (i.e., source locations for C++ operator names or type source info // for constructors, destructors and conversion oeprators). MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - SourceLocation l, QualType ty) - : Expr(MemberExprClass, ty, + SourceLocation l, QualType ty, + ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), base->isValueDependent()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), @@ -1742,7 +1772,7 @@ public: ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *targs, - QualType ty); + QualType ty, ExprValueKind VK, ExprObjectKind OK); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast(Base); } @@ -1920,8 +1950,8 @@ class CompoundLiteralExpr : public Expr { public: // FIXME: Can compound literals be value-dependent? CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, - QualType T, Expr *init, bool fileScope) - : Expr(CompoundLiteralExprClass, T, + QualType T, ExprValueKind VK, Expr *init, bool fileScope) + : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, tinfo->getType()->isDependentType(), false), LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} @@ -2036,9 +2066,9 @@ private: CXXBaseSpecifier **path_buffer(); protected: - CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op, - unsigned BasePathSize) : - Expr(SC, ty, + CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, + const CastKind kind, Expr *op, unsigned BasePathSize) : + Expr(SC, ty, VK, OK_Ordinary, // Cast expressions are type-dependent if the type is // dependent (C++ [temp.dep.expr]p3). ty->isDependentType(), @@ -2121,8 +2151,7 @@ class ImplicitCastExpr : public CastExpr { private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) { - setValueKind(VK); + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { } /// \brief Construct an empty implicit cast. @@ -2133,8 +2162,7 @@ public: enum OnStack_t { OnStack }; ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, kind, op, 0) { - setValueKind(VK); + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } static ImplicitCastExpr *Create(ASTContext &Context, QualType T, @@ -2148,9 +2176,6 @@ public: return getSubExpr()->getSourceRange(); } - using Expr::getValueKind; - using Expr::setValueKind; - static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } @@ -2179,9 +2204,10 @@ class ExplicitCastExpr : public CastExpr { TypeSourceInfo *TInfo; protected: - ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind, - Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy) - : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {} + ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK, + CastKind kind, Expr *op, unsigned PathSize, + TypeSourceInfo *writtenTy) + : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) @@ -2211,10 +2237,10 @@ class CStyleCastExpr : public ExplicitCastExpr { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren - CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, + CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r) - : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize, + : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize, writtenTy), LPLoc(l), RPLoc(r) {} /// \brief Construct an empty C-style explicit cast. @@ -2222,7 +2248,8 @@ class CStyleCastExpr : public ExplicitCastExpr { : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } public: - static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K, + static CStyleCastExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R); @@ -2275,8 +2302,9 @@ private: public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc) - : Expr(BinaryOperatorClass, ResTy, + : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent()), Opc(opc), OpLoc(opLoc) { @@ -2362,8 +2390,9 @@ public: protected: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, bool dead) - : Expr(CompoundAssignOperatorClass, ResTy, + : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent()), Opc(opc), OpLoc(opLoc) { @@ -2385,11 +2414,11 @@ class CompoundAssignOperator : public BinaryOperator { QualType ComputationLHSType; QualType ComputationResultType; public: - CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, - QualType ResType, QualType CompLHSType, - QualType CompResultType, + CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, + ExprValueKind VK, ExprObjectKind OK, + QualType CompLHSType, QualType CompResultType, SourceLocation OpLoc) - : BinaryOperator(lhs, rhs, opc, ResType, OpLoc, true), + : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true), ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && @@ -2425,8 +2454,9 @@ class ConditionalOperator : public Expr { SourceLocation QuestionLoc, ColonLoc; public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, - SourceLocation CLoc, Expr *rhs, Expr *save, QualType t) - : Expr(ConditionalOperatorClass, t, + SourceLocation CLoc, Expr *rhs, Expr *save, + QualType t, ExprValueKind VK) + : Expr(ConditionalOperatorClass, t, VK, OK_Ordinary, // FIXME: the type of the conditional operator doesn't // depend on the type of the conditional, but the standard // seems to imply that it could. File a bug! @@ -2503,7 +2533,7 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, QualType t) - : Expr(AddrLabelExprClass, t, false, false), + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. @@ -2535,6 +2565,9 @@ public: /// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). /// The StmtExpr contains a single CompoundStmt node, which it evaluates and /// takes the value of the last subexpression. +/// +/// A StmtExpr is always an r-value; values "returned" out of a +/// StmtExpr will be copied. class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; @@ -2542,7 +2575,8 @@ public: // FIXME: Does type-dependence need to be computed differently? StmtExpr(CompoundStmt *substmt, QualType T, SourceLocation lp, SourceLocation rp) : - Expr(StmtExprClass, T, T->isDependentType(), false), + Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, + T->isDependentType(), false), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// \brief Build an empty statement expression. @@ -2583,7 +2617,8 @@ public: TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc, TypeSourceInfo *tinfo1, TypeSourceInfo *tinfo2, SourceLocation RP) : - Expr(TypesCompatibleExprClass, ReturnType, false, false), + Expr(TypesCompatibleExprClass, ReturnType, VK_RValue, OK_Ordinary, + false, false), TInfo1(tinfo1), TInfo2(tinfo2), BuiltinLoc(BLoc), RParenLoc(RP) {} /// \brief Build an empty __builtin_type_compatible_p expression. @@ -2639,7 +2674,8 @@ public: ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, QualType Type, SourceLocation BLoc, SourceLocation RP) : - Expr(ShuffleVectorExprClass, Type, Type->isDependentType(), false), + Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, + Type->isDependentType(), false), BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) { SubExprs = new (C) Stmt*[nexpr]; @@ -2706,9 +2742,10 @@ class ChooseExpr : public Expr { Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; public: - ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, + ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, + QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool TypeDependent, bool ValueDependent) - : Expr(ChooseExprClass, t, TypeDependent, ValueDependent), + : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent), BuiltinLoc(BLoc), RParenLoc(RP) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; @@ -2766,7 +2803,8 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, false, false), TokenLoc(Loc) { } + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + TokenLoc(Loc) { } /// \brief Build an empty GNU __null expression. explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { } @@ -2796,7 +2834,8 @@ class VAArgExpr : public Expr { public: VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo, SourceLocation RPLoc, QualType t) - : Expr(VAArgExprClass, t, t->isDependentType(), false), + : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, + t->isDependentType(), false), Val(e), TInfo(TInfo), BuiltinLoc(BLoc), RParenLoc(RPLoc) { } @@ -3296,7 +3335,8 @@ public: class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) - : Expr(ImplicitValueInitExprClass, ty, false, false) { } + : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, + false, false) { } /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -3380,10 +3420,10 @@ class ExtVectorElementExpr : public Expr { IdentifierInfo *Accessor; SourceLocation AccessorLoc; public: - ExtVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor, - SourceLocation loc) - : Expr(ExtVectorElementExprClass, ty, base->isTypeDependent(), - base->isValueDependent()), + ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base, + IdentifierInfo &accessor, SourceLocation loc) + : Expr(ExtVectorElementExprClass, ty, VK, OK_VectorComponent, + base->isTypeDependent(), base->isValueDependent()), Base(base), Accessor(&accessor), AccessorLoc(loc) {} /// \brief Build an empty vector element expression. @@ -3438,7 +3478,8 @@ protected: bool HasBlockDeclRefExprs; public: BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs) - : Expr(BlockExprClass, ty, ty->isDependentType(), false), + : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, + ty->isDependentType(), false), TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {} /// \brief Build an empty block expression. @@ -3485,10 +3526,11 @@ class BlockDeclRefExpr : public Expr { Stmt *CopyConstructorVal; public: // FIXME: Fix type/value dependence! - BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef, - bool constAdded = false, + BlockDeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, + SourceLocation l, bool ByRef, bool constAdded = false, Stmt *copyConstructorVal = 0) - : Expr(BlockDeclRefExprClass, t, (!t.isNull() && t->isDependentType()),false), + : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, + (!t.isNull() && t->isDependentType()), false), D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) {} @@ -3536,17 +3578,14 @@ public: class OpaqueValueExpr : public Expr { friend class ASTStmtReader; public: - OpaqueValueExpr(QualType T, ExprValueKind VK) - : Expr(OpaqueValueExprClass, T, T->isDependentType(), - T->isDependentType()) { - setValueKind(VK); + OpaqueValueExpr(QualType T, ExprValueKind VK, ExprObjectKind OK = OK_Ordinary) + : Expr(OpaqueValueExprClass, T, VK, OK, + T->isDependentType(), T->isDependentType()) { } explicit OpaqueValueExpr(EmptyShell Empty) : Expr(OpaqueValueExprClass, Empty) { } - using Expr::getValueKind; - virtual SourceRange getSourceRange() const; virtual child_iterator child_begin(); virtual child_iterator child_end(); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 78edd4beecc7..a1d464e6fd49 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -51,8 +51,9 @@ class CXXOperatorCallExpr : public CallExpr { public: CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, Expr **args, unsigned numargs, QualType t, - SourceLocation operatorloc) - : CallExpr(C, CXXOperatorCallExprClass, fn, args, numargs, t, operatorloc), + ExprValueKind VK, SourceLocation operatorloc) + : CallExpr(C, CXXOperatorCallExprClass, fn, args, numargs, t, VK, + operatorloc), Operator(Op) {} explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) : CallExpr(C, CXXOperatorCallExprClass, Empty) { } @@ -89,8 +90,8 @@ public: class CXXMemberCallExpr : public CallExpr { public: CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs, - QualType t, SourceLocation rparenloc) - : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {} + QualType t, ExprValueKind VK, SourceLocation RP) + : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -127,10 +128,10 @@ private: SourceLocation Loc; // the location of the casting op protected: - CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op, - unsigned PathSize, TypeSourceInfo *writtenTy, - SourceLocation l) - : ExplicitCastExpr(SC, ty, kind, op, PathSize, writtenTy), Loc(l) {} + CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, + CastKind kind, Expr *op, unsigned PathSize, + TypeSourceInfo *writtenTy, SourceLocation l) + : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l) {} explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) : ExplicitCastExpr(SC, Shell, PathSize) { } @@ -165,10 +166,10 @@ public: /// This expression node represents a C++ static cast, e.g., /// @c static_cast(1.0). class CXXStaticCastExpr : public CXXNamedCastExpr { - CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op, + CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l) - : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, pathSize, + : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, writtenTy, l) {} explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize) @@ -176,7 +177,7 @@ class CXXStaticCastExpr : public CXXNamedCastExpr { public: static CXXStaticCastExpr *Create(ASTContext &Context, QualType T, - CastKind K, Expr *Op, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L); static CXXStaticCastExpr *CreateEmpty(ASTContext &Context, @@ -195,10 +196,10 @@ public: /// This expression node represents a dynamic cast, e.g., /// @c dynamic_cast(BasePtr). class CXXDynamicCastExpr : public CXXNamedCastExpr { - CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, - unsigned pathSize, TypeSourceInfo *writtenTy, + CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, + Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l) - : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, pathSize, + : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, writtenTy, l) {} explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) @@ -206,7 +207,7 @@ class CXXDynamicCastExpr : public CXXNamedCastExpr { public: static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T, - CastKind Kind, Expr *Op, + ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L); @@ -226,19 +227,19 @@ public: /// This expression node represents a reinterpret cast, e.g., /// @c reinterpret_cast(VoidPtr). class CXXReinterpretCastExpr : public CXXNamedCastExpr { - CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, - unsigned pathSize, + CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, + Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l) - : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, pathSize, - writtenTy, l) {} + : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, + pathSize, writtenTy, l) {} CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { } public: static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T, - CastKind Kind, Expr *Op, - const CXXCastPath *Path, + ExprValueKind VK, CastKind Kind, + Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L); static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context, unsigned pathSize); @@ -255,16 +256,17 @@ public: /// This expression node represents a const cast, e.g., /// @c const_cast(PtrToConstChar). class CXXConstCastExpr : public CXXNamedCastExpr { - CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy, - SourceLocation l) - : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, + CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, + TypeSourceInfo *writtenTy, SourceLocation l) + : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0, writtenTy, l) {} explicit CXXConstCastExpr(EmptyShell Empty) : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { } public: - static CXXConstCastExpr *Create(ASTContext &Context, QualType T, Expr *Op, + static CXXConstCastExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L); static CXXConstCastExpr *CreateEmpty(ASTContext &Context); @@ -281,7 +283,8 @@ class CXXBoolLiteralExpr : public Expr { SourceLocation Loc; public: CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : - Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {} + Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + Value(val), Loc(l) {} explicit CXXBoolLiteralExpr(EmptyShell Empty) : Expr(CXXBoolLiteralExprClass, Empty) { } @@ -309,7 +312,8 @@ class CXXNullPtrLiteralExpr : public Expr { SourceLocation Loc; public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : - Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {} + Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + Loc(l) {} explicit CXXNullPtrLiteralExpr(EmptyShell Empty) : Expr(CXXNullPtrLiteralExprClass, Empty) { } @@ -340,7 +344,7 @@ private: public: CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, // typeid is never type-dependent (C++ [temp.dep.expr]p4) false, // typeid is value-dependent if the type or expression are dependent @@ -348,7 +352,7 @@ public: Operand(Operand), Range(R) { } CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, // typeid is never type-dependent (C++ [temp.dep.expr]p4) false, // typeid is value-dependent if the type or expression are dependent @@ -414,12 +418,12 @@ private: public: CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, + : Expr(CXXUuidofExprClass, Ty, VK_RValue, OK_Ordinary, false, Operand->getType()->isDependentType()), Operand(Operand), Range(R) { } CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, + : Expr(CXXUuidofExprClass, Ty, /*FIXME*/ VK_LValue, OK_Ordinary, false, Operand->isTypeDependent()), Operand(Operand), Range(R) { } @@ -488,7 +492,7 @@ class CXXThisExpr : public Expr { public: CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit) - : Expr(CXXThisExprClass, Type, + : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary, // 'this' is type-dependent if the class type of the enclosing // member function is dependent (C++ [temp.dep.expr]p2) Type->isDependentType(), Type->isDependentType()), @@ -526,7 +530,8 @@ public: // exepression. The l is the location of the throw keyword. expr // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : - Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {} + Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + Op(expr), ThrowLoc(l) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} const Expr *getSubExpr() const { return cast_or_null(Op); } @@ -572,12 +577,13 @@ class CXXDefaultArgExpr : public Expr { param->hasUnparsedDefaultArg() ? param->getType().getNonReferenceType() : param->getDefaultArg()->getType(), - false, false), + getValueKindForType(param->getType()), OK_Ordinary, false, false), Param(param, false), Loc(Loc) { } CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) - : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) { + : Expr(SC, SubExpr->getType(), SubExpr->getValueKind(), OK_Ordinary, + false, false), Param(param, true), Loc(Loc) { *reinterpret_cast(this + 1) = SubExpr; } @@ -674,7 +680,8 @@ class CXXBindTemporaryExpr : public Expr { CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr, bool TD=false, bool VD=false) - : Expr(CXXBindTemporaryExprClass, subexpr->getType(), TD, VD), + : Expr(CXXBindTemporaryExprClass, subexpr->getType(), + VK_RValue, OK_Ordinary, TD, VD), Temp(temp), SubExpr(subexpr) { } public: @@ -833,12 +840,13 @@ class CXXFunctionalCastExpr : public ExplicitCastExpr { SourceLocation TyBeginLoc; SourceLocation RParenLoc; - CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy, + CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, + TypeSourceInfo *writtenTy, SourceLocation tyBeginLoc, CastKind kind, Expr *castExpr, unsigned pathSize, SourceLocation rParenLoc) - : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, - pathSize, writtenTy), + : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, + castExpr, pathSize, writtenTy), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize) @@ -846,6 +854,7 @@ class CXXFunctionalCastExpr : public ExplicitCastExpr { public: static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, TypeSourceInfo *Written, SourceLocation TyBeginLoc, CastKind Kind, Expr *Op, @@ -923,7 +932,8 @@ public: CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, SourceLocation rParenLoc ) : - Expr(CXXScalarValueInitExprClass, Type, false, false), + Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, + false, false), RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -1135,7 +1145,8 @@ public: CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, bool arrayFormAsWritten, FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) - : Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete), + : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false), + GlobalDelete(globalDelete), ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), OperatorDelete(operatorDelete), Argument(arg), Loc(loc) { } explicit CXXDeleteExpr(EmptyShell Shell) @@ -1271,6 +1282,7 @@ public: false, 0, false, false, 0, 0, FunctionType::ExtInfo())), + VK_RValue, OK_Ordinary, /*isTypeDependent=*/(Base->isTypeDependent() || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), @@ -1408,8 +1420,8 @@ public: UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt, TypeSourceInfo *queried, bool value, SourceLocation rparen, QualType ty) - : Expr(UnaryTypeTraitExprClass, ty, false, - queried->getType()->isDependentType()), + : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, + false, queried->getType()->isDependentType()), UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { } explicit UnaryTypeTraitExpr(EmptyShell Empty) @@ -1608,8 +1620,9 @@ class UnresolvedLookupExpr : public OverloadExpr { const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, bool HasTemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier, - QRange, NameInfo, HasTemplateArgs, Begin, End), + : OverloadExpr(UnresolvedLookupExprClass, C, T, + Dependent, Qualifier, QRange, NameInfo, HasTemplateArgs, + Begin, End), RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) {} @@ -1760,7 +1773,8 @@ class DependentScopeDeclRefExpr : public Expr { SourceRange QualifierRange, const DeclarationNameInfo &NameInfo, bool HasExplicitTemplateArgs) - : Expr(DependentScopeDeclRefExprClass, T, true, true), + : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, + true, true), NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier), HasExplicitTemplateArgs(HasExplicitTemplateArgs) {} @@ -2096,7 +2110,8 @@ public: SourceRange QualifierRange, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, + VK_LValue, OK_Ordinary, true, true), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), @@ -2478,7 +2493,8 @@ class CXXNoexceptExpr : public Expr { public: CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, SourceLocation Keyword, SourceLocation RParen) - : Expr(CXXNoexceptExprClass, Ty, /*TypeDependent*/false, + : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, + /*TypeDependent*/false, /*ValueDependent*/Val == CT_Dependent), Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) { } diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index edcbe3d6caf5..75e02e768e26 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -30,7 +30,8 @@ class ObjCStringLiteral : public Expr { SourceLocation AtLoc; public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) - : Expr(ObjCStringLiteralClass, T, false, false), String(SL), AtLoc(L) {} + : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false), + String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -64,7 +65,8 @@ class ObjCEncodeExpr : public Expr { public: ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, SourceLocation rp) - : Expr(ObjCEncodeExprClass, T, EncodedType->getType()->isDependentType(), + : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, + EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType()), EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} @@ -104,8 +106,8 @@ class ObjCSelectorExpr : public Expr { public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T, false, false), SelName(selInfo), AtLoc(at), - RParenLoc(rp){} + : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false), + SelName(selInfo), AtLoc(at), RParenLoc(rp){} explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -144,8 +146,8 @@ class ObjCProtocolExpr : public Expr { public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T, false, false), TheProtocol(protocol), - AtLoc(at), RParenLoc(rp) {} + : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false), + TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -180,11 +182,11 @@ class ObjCIvarRefExpr : public Expr { bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). public: - ObjCIvarRefExpr(ObjCIvarDecl *d, - QualType t, SourceLocation l, Expr *base, + ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, + SourceLocation l, Expr *base, bool arrow = false, bool freeIvar = false) : - Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false, - base->isValueDependent()), D(d), + Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, + /*TypeDependent=*/false, base->isValueDependent()), D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} @@ -241,15 +243,18 @@ private: public: ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l, Expr *base) - : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, - base->isValueDependent()), + : Expr(ObjCPropertyRefExprClass, t, VK, OK, + /*TypeDependent=*/false, base->isValueDependent()), AsProperty(PD), IdLoc(l), BaseExprOrSuperType(base) { } ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, false), + : Expr(ObjCPropertyRefExprClass, t, VK, OK, + /*TypeDependent=*/false, false), AsProperty(PD), IdLoc(l), SuperLoc(sl), BaseExprOrSuperType(st.getTypePtr()) { } @@ -337,33 +342,33 @@ class ObjCImplicitSetterGetterRefExpr : public Expr { QualType SuperTy; public: - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, - QualType t, - ObjCMethodDecl *setter, - SourceLocation l, Expr *base) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, - base->isValueDependent()), + ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, + ExprValueKind VK, ExprObjectKind OK, + ObjCMethodDecl *setter, + SourceLocation l, Expr *base) + : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, + /*TypeDependent=*/false, base->isValueDependent()), Setter(setter), Getter(getter), MemberLoc(l), Base(base), InterfaceDecl(0), ClassLoc(SourceLocation()) {} - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, - QualType t, + ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, + ExprValueKind VK, ExprObjectKind OK, ObjCMethodDecl *setter, SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, - false), - Setter(setter), Getter(getter), MemberLoc(l), - Base(0), InterfaceDecl(0), ClassLoc(SourceLocation()), - SuperLoc(sl), SuperTy(st) { + : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, + /*TypeDependent=*/false, false), + Setter(setter), Getter(getter), MemberLoc(l), + Base(0), InterfaceDecl(0), ClassLoc(SourceLocation()), + SuperLoc(sl), SuperTy(st) { } - ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, - QualType t, - ObjCMethodDecl *setter, + ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, + ExprValueKind VK, ExprObjectKind OK, + ObjCMethodDecl *setter, SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) - : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false), + : Expr(ObjCImplicitSetterGetterRefExprClass, t, VK, OK, false, false), Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C), ClassLoc(CL) {} explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty) @@ -471,7 +476,7 @@ class ObjCMessageExpr : public Expr { : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), HasMethod(0), SelectorOrMethod(0) { } - ObjCMessageExpr(QualType T, + ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -480,14 +485,14 @@ class ObjCMessageExpr : public Expr { ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); - ObjCMessageExpr(QualType T, + ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); - ObjCMessageExpr(QualType T, + ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, @@ -525,6 +530,10 @@ public: /// /// \param T The result type of this message. /// + /// \param VK The value kind of this message. A message returning + /// a l-value or r-value reference will be an l-value or x-value, + /// respectively. + /// /// \param LBrac The location of the open square bracket '['. /// /// \param SuperLoc The location of the "super" keyword. @@ -542,7 +551,8 @@ public: /// \param NumArgs The number of arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -558,6 +568,10 @@ public: /// /// \param T The result type of this message. /// + /// \param VK The value kind of this message. A message returning + /// a l-value or r-value reference will be an l-value or x-value, + /// respectively. + /// /// \param LBrac The location of the open square bracket '['. /// /// \param Receiver The type of the receiver, including @@ -574,6 +588,7 @@ public: /// /// \param RBracLoc The location of the closing square bracket ']'. static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, @@ -587,6 +602,10 @@ public: /// /// \param T The result type of this message. /// + /// \param VK The value kind of this message. A message returning + /// a l-value or r-value reference will be an l-value or x-value, + /// respectively. + /// /// \param LBrac The location of the open square bracket '['. /// /// \param Receiver The expression used to produce the object that @@ -603,6 +622,7 @@ public: /// /// \param RBracLoc The location of the closing square bracket ']'. static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, @@ -816,8 +836,8 @@ class ObjCIsaExpr : public Expr { bool IsArrow; public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) - : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false, - base->isValueDependent()), + : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, + /*TypeDependent=*/false, base->isValueDependent()), Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} /// \brief Build an empty expression. diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 3c5d306af891..678712586327 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -147,10 +147,11 @@ protected: unsigned : NumStmtBits; unsigned ValueKind : 2; + unsigned ObjectKind : 2; unsigned TypeDependent : 1; unsigned ValueDependent : 1; }; - enum { NumExprBits = 12 }; + enum { NumExprBits = 14 }; class CastExprBitfields { friend class CastExpr; diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index e757a2f4a185..e6b6218100ad 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -95,6 +95,23 @@ namespace clang { VK_XValue }; + /// A further classification of the kind of object referenced by an + /// l-value or x-value. + enum ExprObjectKind { + /// An ordinary object is located at an address in memory. + OK_Ordinary, + + /// A bitfield object is a bitfield on a C or C++ record. + OK_BitField, + + /// A vector component is an element or range of elements on a vector. + OK_VectorComponent, + + /// An Objective C property is a logical field of an Objective-C + /// object which is read and written via Objective C method calls. + OK_ObjCProperty + }; + // \brief Describes the kind of template specialization that a // particular template specialization declaration represents. enum TemplateSpecializationKind { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index aac36bb15581..26c775fcfad2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1731,9 +1731,11 @@ public: const TemplateArgumentListInfo *TemplateArgs); ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS = 0); ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS = 0); VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field, @@ -4173,7 +4175,8 @@ public: /// type checking binary operators (subroutines of CreateBuiltinBinOp). QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex); QualType CheckPointerToMemberOperands( // C++ 5.5 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect); + Expr *&lex, Expr *&rex, ExprValueKind &VK, + SourceLocation OpLoc, bool isIndirect); QualType CheckMultiplyDivideOperands( // C99 6.5.5 Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign, bool isDivide); @@ -4204,9 +4207,9 @@ public: Expr *lex, Expr *&rex, SourceLocation OpLoc); QualType CheckConditionalOperands( // C99 6.5.15 Expr *&cond, Expr *&lhs, Expr *&rhs, Expr *&save, - SourceLocation questionLoc); + ExprValueKind &VK, SourceLocation questionLoc); QualType CXXCheckConditionalOperands( // C++ 5.16 - Expr *&cond, Expr *&lhs, Expr *&rhs, Expr *&save, + Expr *&cond, Expr *&lhs, Expr *&rhs, Expr *&save, ExprValueKind &VK, SourceLocation questionLoc); QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool *NonStandardCompositeType = 0); @@ -4268,7 +4271,7 @@ public: /// CheckCastTypes - Check type constraints for casting between types under /// C semantics, or forward to CXXCheckCStyleCast in C++. bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, CXXCastPath &BasePath, + CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath, bool FunctionalStyle = false); // CheckVectorCast - check type constraints for vectors. @@ -4288,9 +4291,9 @@ public: /// CXXCheckCStyleCast - Check constraints of a C-style or function-style /// cast under C++ semantics. - bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, CXXCastPath &BasePath, - bool FunctionalStyle); + bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, + Expr *&CastExpr, CastKind &Kind, + CXXCastPath &BasePath, bool FunctionalStyle); /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. @@ -4299,7 +4302,7 @@ public: bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, SourceLocation lbrac, SourceLocation rbrac, - QualType &ReturnType); + QualType &ReturnType, ExprValueKind &VK); /// CheckBooleanCondition - Diagnose problems involving the use of /// the given expression as a boolean condition (e.g. in an if diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 159a26953489..b4edc5f22bf5 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2813,7 +2813,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { Importer.Import(E->getQualifierRange()), ToD, Importer.Import(E->getLocation()), - T, + T, E->getValueKind(), /*FIXME:TemplateArgs=*/0); } @@ -2858,7 +2858,8 @@ Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { return 0; return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(), - T, + T, E->getValueKind(), + E->getObjectKind(), Importer.Import(E->getOperatorLoc())); } @@ -2900,7 +2901,8 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { return 0; return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(), - T, + T, E->getValueKind(), + E->getObjectKind(), Importer.Import(E->getOperatorLoc())); } @@ -2927,7 +2929,9 @@ Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { return new (Importer.getToContext()) CompoundAssignOperator(LHS, RHS, E->getOpcode(), - T, CompLHSType, CompResultType, + T, E->getValueKind(), + E->getObjectKind(), + CompLHSType, CompResultType, Importer.Import(E->getOperatorLoc())); } @@ -2972,7 +2976,8 @@ Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { if (ImportCastPath(E, BasePath)) return 0; - return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), + return CStyleCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), SubExpr, &BasePath, TInfo, Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc())); diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index cce434364faf..f21c9a3af32f 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -318,6 +318,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { dyn_cast(*Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType().getNonLValueExprType(Context), + Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation()); TemplateArgs.push_back(TemplateArgument(E)); } else { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b03594f8f98b..c92061107535 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -194,8 +194,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T) - : Expr(DeclRefExprClass, T, false, false), + QualType T, ExprValueKind VK) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -216,8 +216,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, - QualType T) - : Expr(DeclRefExprClass, T, false, false), + QualType T, ExprValueKind VK) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -240,10 +240,11 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, ValueDecl *D, SourceLocation NameLoc, QualType T, + ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { return Create(Context, Qualifier, QualifierRange, D, DeclarationNameInfo(D->getDeclName(), NameLoc), - T, TemplateArgs); + T, VK, TemplateArgs); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, @@ -252,6 +253,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, + ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { std::size_t Size = sizeof(DeclRefExpr); if (Qualifier != 0) @@ -262,7 +264,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, void *Mem = Context.Allocate(Size, llvm::alignOf()); return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo, - TemplateArgs, T); + TemplateArgs, T, VK); } DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier, @@ -592,8 +594,9 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) { //===----------------------------------------------------------------------===// CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, - unsigned numargs, QualType t, SourceLocation rparenloc) - : Expr(SC, t, + unsigned numargs, QualType t, ExprValueKind VK, + SourceLocation rparenloc) + : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), NumArgs(numargs) { @@ -607,8 +610,8 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, } CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, - QualType t, SourceLocation rparenloc) - : Expr(CallExprClass, t, + QualType t, ExprValueKind VK, SourceLocation rparenloc) + : Expr(CallExprClass, t, VK, OK_Ordinary, fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), NumArgs(numargs) { @@ -740,7 +743,8 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, OffsetOfNode* compsPtr, unsigned numComps, Expr** exprsPtr, unsigned numExprs, SourceLocation RParenLoc) - : Expr(OffsetOfExprClass, type, /*TypeDependent=*/false, + : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/tsi->getType()->isDependentType() || hasAnyTypeDependentArguments(exprsPtr, numExprs) || hasAnyValueDependentArguments(exprsPtr, numExprs)), @@ -771,7 +775,9 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, DeclAccessPair founddecl, DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs, - QualType ty) { + QualType ty, + ExprValueKind vk, + ExprObjectKind ok) { std::size_t Size = sizeof(MemberExpr); bool hasQualOrFound = (qual != 0 || @@ -784,7 +790,8 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, Size += ExplicitTemplateArgumentList::sizeFor(*targs); void *Mem = C.Allocate(Size, llvm::alignOf()); - MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, ty); + MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, + ty, vk, ok); if (hasQualOrFound) { if (qual && qual->isDependent()) { @@ -964,7 +971,7 @@ ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C, CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T, - CastKind K, Expr *Op, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R) { @@ -972,7 +979,7 @@ CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CStyleCastExpr *E = - new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R); + new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -1089,7 +1096,7 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) { InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, Expr **initExprs, unsigned numInits, SourceLocation rbraceloc) - : Expr(InitListExprClass, QualType(), false, false), + : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false), InitExprs(C, numInits), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), UnionFieldInit(0), HadArrayRangeDesignator(false) @@ -2158,6 +2165,7 @@ void ExtVectorElementExpr::getEncodedElementAccess( } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -2166,8 +2174,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, /*TypeDependent=*/false, - /*ValueDependent=*/false), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/false), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), HasMethod(Method != 0), SuperLoc(SuperLoc), SelectorOrMethod(reinterpret_cast(Method? Method @@ -2180,13 +2188,14 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, T->isDependentType(), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), (T->isDependentType() || hasAnyValueDependentArguments(Args, NumArgs))), NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0), @@ -2200,13 +2209,14 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, Receiver->isTypeDependent(), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), (Receiver->isTypeDependent() || hasAnyValueDependentArguments(Args, NumArgs))), NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0), @@ -2220,6 +2230,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -2231,12 +2242,13 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, SuperLoc, IsInstanceSuper, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, SuperType, Sel, Method, Args, NumArgs, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, @@ -2246,11 +2258,12 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args, NumArgs, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, @@ -2260,7 +2273,7 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args, NumArgs, RBracLoc); } @@ -2343,6 +2356,7 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumIndexExprs, Expr *Init) : Expr(DesignatedInitExprClass, Ty, + Init->getValueKind(), Init->getObjectKind(), Init->isTypeDependent(), Init->isValueDependent()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { @@ -2483,7 +2497,7 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx, ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc) -: Expr(ParenListExprClass, QualType(), +: Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, hasAnyTypeDependentArguments(exprs, nexprs), hasAnyValueDependentArguments(exprs, nexprs)), NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 1820ff77074a..63bf2dd091ce 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -116,7 +116,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, SourceLocation startLoc, SourceLocation endLoc, SourceLocation constructorLParen, SourceLocation constructorRParen) - : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()), + : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, + ty->isDependentType(), ty->isDependentType()), GlobalNew(globalNew), Initializer(initializer), SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete), Constructor(constructor), @@ -247,7 +248,7 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool HasTemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : Expr(K, T, Dependent, Dependent), + : Expr(K, T, VK_LValue, OK_Ordinary, Dependent, Dependent), Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs) { @@ -436,6 +437,7 @@ const char *CXXNamedCastExpr::getCastName() const { } CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, @@ -444,7 +446,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXStaticCastExpr *E = - new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -457,6 +459,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C, } CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, @@ -465,7 +468,7 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXDynamicCastExpr *E = - new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -478,14 +481,15 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C, } CXXReinterpretCastExpr * -CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op, +CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, + CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L) { unsigned PathSize = (BasePath ? BasePath->size() : 0); void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXReinterpretCastExpr *E = - new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -497,10 +501,11 @@ CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize); } -CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op, +CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L) { - return new (C) CXXConstCastExpr(T, Op, WrittenTy, L); + return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L); } CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { @@ -508,7 +513,7 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { } CXXFunctionalCastExpr * -CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, +CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, TypeSourceInfo *Written, SourceLocation L, CastKind K, Expr *Op, const CXXCastPath *BasePath, SourceLocation R) { @@ -516,7 +521,7 @@ CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXFunctionalCastExpr *E = - new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R); + new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -592,7 +597,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, bool ZeroInitialization, ConstructionKind ConstructKind, SourceRange ParenRange) -: Expr(SC, T, +: Expr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), (T->isDependentType() || CallExpr::hasAnyValueDependentArguments(args, numargs))), @@ -615,7 +620,8 @@ CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C, CXXTemporary **temps, unsigned numtemps) : Expr(CXXExprWithTemporariesClass, subexpr->getType(), - subexpr->isTypeDependent(), subexpr->isValueDependent()), + subexpr->getValueKind(), subexpr->getObjectKind(), + subexpr->isTypeDependent(), subexpr->isValueDependent()), SubExpr(subexpr), Temps(0), NumTemps(0) { if (numtemps) { setNumTemporaries(C, numtemps); @@ -671,6 +677,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation RParenLoc) : Expr(CXXUnresolvedConstructExprClass, Type->getType().getNonReferenceType(), + VK_RValue, OK_Ordinary, Type->getType()->isDependentType(), true), Type(Type), LParenLoc(LParenLoc), @@ -722,7 +729,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, + VK_LValue, OK_Ordinary, true, true), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(TemplateArgs != 0), OperatorLoc(OperatorLoc), diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 60fbfd298f19..4677910798f2 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -292,9 +292,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { } case Expr::CXXUuidofExprClass: - // Assume that Microsoft's __uuidof returns an lvalue, like typeid does. - // FIXME: Is this really the case? - return Cl::CL_LValue; + return Cl::CL_PRValue; } llvm_unreachable("unhandled expression kind in classification"); diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index afc9b509e7be..15a8d61c8854 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -105,10 +105,27 @@ namespace { << " " << (void*)Node; DumpSourceRange(Node); } + void DumpValueKind(ExprValueKind K) { + switch (K) { + case VK_RValue: break; + case VK_LValue: OS << " lvalue"; break; + case VK_XValue: OS << " xvalue"; break; + } + } + void DumpObjectKind(ExprObjectKind K) { + switch (K) { + case OK_Ordinary: break; + case OK_BitField: OS << " bitfield"; break; + case OK_ObjCProperty: OS << " objcproperty"; break; + case OK_VectorComponent: OS << " vectorcomponent"; break; + } + } void DumpExpr(const Expr *Node) { DumpStmt(Node); OS << ' '; DumpType(Node->getType()); + DumpValueKind(Node->getValueKind()); + DumpObjectKind(Node->getObjectKind()); } void DumpSourceRange(const Stmt *Node); void DumpLocation(SourceLocation Loc); @@ -122,7 +139,6 @@ namespace { // Exprs void VisitExpr(Expr *Node); void VisitCastExpr(CastExpr *Node); - void VisitImplicitCastExpr(ImplicitCastExpr *Node); void VisitDeclRefExpr(DeclRefExpr *Node); void VisitPredefinedExpr(PredefinedExpr *Node); void VisitCharacterLiteral(CharacterLiteral *Node); @@ -344,20 +360,6 @@ void StmtDumper::VisitCastExpr(CastExpr *Node) { OS << ">"; } -void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) { - VisitCastExpr(Node); - switch (Node->getValueKind()) { - case VK_LValue: - OS << " lvalue"; - break; - case VK_XValue: - OS << " xvalue"; - break; - case VK_RValue: - break; - } -} - void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { DumpExpr(Node); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index c40cfaf6a978..8f3e0a63263e 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -161,7 +161,7 @@ static void AllocateAllBlockDeclRefs(CodeGenFunction &CGF, CGBlockInfo &Info) { if (Info.NeedsObjCSelf) { ValueDecl *Self = cast(CGF.CurFuncDecl)->getSelfDecl(); BlockDeclRefExpr *BDRE = - new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(), + new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(), VK_RValue, SourceLocation(), false); Info.DeclRefs.push_back(BDRE); CGF.AllocateBlockDecl(BDRE); @@ -344,26 +344,26 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (BDRE->getCopyConstructorExpr()) { E = BDRE->getCopyConstructorExpr(); PushDestructorCleanup(E->getType(), Addr); - } - else { - E = new (getContext()) DeclRefExpr(const_cast(VD), - VD->getType().getNonReferenceType(), - SourceLocation()); - if (VD->getType()->isReferenceType()) { - E = new (getContext()) - UnaryOperator(const_cast(E), UO_AddrOf, - getContext().getPointerType(E->getType()), - SourceLocation()); - } + } else { + E = new (getContext()) DeclRefExpr(const_cast(VD), + VD->getType().getNonReferenceType(), + Expr::getValueKindForType(VD->getType()), + SourceLocation()); + if (VD->getType()->isReferenceType()) { + E = new (getContext()) + UnaryOperator(const_cast(E), UO_AddrOf, + getContext().getPointerType(E->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); } } } + } if (BDRE->isByRef()) { E = new (getContext()) UnaryOperator(const_cast(E), UO_AddrOf, getContext().getPointerType(E->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); } RValue r = EmitAnyExpr(E, AggValueSlot::forAddr(Addr, false, true)); @@ -932,7 +932,7 @@ CharUnits BlockFunction::getBlockOffset(CharUnits Size, CharUnits Align) { 0, QualType(PadTy), 0, SC_None, SC_None); Expr *E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(), - SourceLocation()); + VK_LValue, SourceLocation()); BlockLayout.push_back(E); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 7c2dfe8b23b5..13f4d8f7965d 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -393,9 +393,9 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); - DeclRefExpr Base(Self, Self->getType(), Loc); + DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc); ParmVarDecl *ArgDecl = *OMD->param_begin(); - DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); + DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), VK_LValue, Loc); ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true); // The property type can differ from the ivar type in some situations with @@ -406,11 +406,11 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, Ivar->getType(), CK_BitCast, &Arg, VK_RValue); BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign, - Ivar->getType(), Loc); + Ivar->getType(), VK_RValue, OK_Ordinary, Loc); EmitStmt(&Assign); } else { BinaryOperator Assign(&IvarRef, &Arg, BO_Assign, - Ivar->getType(), Loc); + Ivar->getType(), VK_RValue, OK_Ordinary, Loc); EmitStmt(&Assign); } } diff --git a/clang/lib/Rewrite/RewriteObjC.cpp b/clang/lib/Rewrite/RewriteObjC.cpp index a32b434a95c9..7987c65ad211 100644 --- a/clang/lib/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Rewrite/RewriteObjC.cpp @@ -456,7 +456,7 @@ namespace { CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, CastKind Kind, Expr *E) { TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); - return CStyleCastExpr::Create(*Ctx, Ty, Kind, E, 0, TInfo, + return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo, SourceLocation(), SourceLocation()); } } @@ -1265,6 +1265,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME?*/SourceLocation(), SuperLocation, /*IsInstanceSuper=*/true, @@ -1283,6 +1284,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME: */SourceLocation(), cast(Receiver), Sel, OMD, @@ -1344,6 +1346,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME?*/SourceLocation(), SuperLocation, /*IsInstanceSuper=*/true, @@ -1359,6 +1362,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { Receiver = PropGetters[Exp]; MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME:*/SourceLocation(), cast(Receiver), Sel, OMD, @@ -1420,14 +1424,15 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, IV->getBase()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), - IV->getBase()->getLocEnd(), - castExpr); + IV->getBase()->getLocEnd(), + castExpr); replaced = true; if (IV->isFreeIvar() && CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) { MemberExpr *ME = new (Context) MemberExpr(PE, true, D, - IV->getLocation(), - D->getType()); + IV->getLocation(), + D->getType(), + VK_LValue, OK_Ordinary); // delete IV; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. return ME; } @@ -2135,7 +2140,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( QualType msgSendType = FD->getType(); // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, msgSendType, SourceLocation()); + DeclRefExpr *DRE = + new (Context) DeclRefExpr(FD, msgSendType, VK_LValue, SourceLocation()); // Now, we cast the reference to a pointer to the objc_msgSend type. QualType pToFunc = Context->getPointerType(msgSendType); @@ -2147,7 +2153,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( CallExpr *Exp = new (Context) CallExpr(*Context, ICE, args, nargs, - FT->getCallResultType(*Context), EndLoc); + FT->getCallResultType(*Context), + VK_RValue, EndLoc); return Exp; } @@ -2662,10 +2669,12 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), &Context->Idents.get(S), strType, 0, SC_Static, SC_None); - DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue, + SourceLocation()); Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_BitCast, Unop); @@ -2784,8 +2793,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), - Context->getObjCIdType(), - SourceLocation())) + Context->getObjCIdType(), + VK_RValue, + SourceLocation())) ); // set the 'receiver'. // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) @@ -2824,10 +2834,12 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SynthSuperContructorFunctionDecl(); // Simulate a contructor call... DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); // The code for super is a little tricky to prevent collision with // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why @@ -2836,7 +2848,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2849,11 +2862,13 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, TypeSourceInfo *superTInfo = Context->getTrivialTypeSourceInfo(superType); SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, ILE, false); + superType, VK_LValue, + ILE, false); // struct objc_super * SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); } MsgExprs.push_back(SuperRep); break; @@ -2890,8 +2905,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), - Context->getObjCIdType(), - SourceLocation())) + Context->getObjCIdType(), + VK_RValue, SourceLocation())) ); // set the 'receiver'. // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) @@ -2929,10 +2944,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SynthSuperContructorFunctionDecl(); // Simulate a contructor call... DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - superType, SourceLocation()); + superType, VK_LValue, SourceLocation()); // The code for super is a little tricky to prevent collision with // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why @@ -2941,6 +2957,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), @@ -2954,7 +2971,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, TypeSourceInfo *superTInfo = Context->getTrivialTypeSourceInfo(superType); SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, ILE, false); + superType, VK_RValue, ILE, + false); } MsgExprs.push_back(SuperRep); break; @@ -3048,7 +3066,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // Create a reference to the objc_msgSend() declaration. DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType, - SourceLocation()); + VK_LValue, SourceLocation()); // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). // If we don't do this cast, we get the following bizarre warning/note: @@ -3075,7 +3093,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, const FunctionType *FT = msgSendType->getAs(); CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], MsgExprs.size(), - FT->getResultType(), EndLoc); + FT->getResultType(), VK_RValue, + EndLoc); Stmt *ReplacingStmt = CE; if (MsgSendStretFlavor) { // We have the method which returns a struct/union. Must also generate @@ -3085,7 +3104,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // Create a reference to the objc_msgSend_stret() declaration. DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType, - SourceLocation()); + VK_LValue, SourceLocation()); // Need to cast objc_msgSend_stret to "void *" (see above comment). cast = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(Context->VoidTy), @@ -3106,7 +3125,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, FT = msgSendType->getAs(); CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], MsgExprs.size(), - FT->getResultType(), SourceLocation()); + FT->getResultType(), VK_RValue, + SourceLocation()); // Build sizeof(returnType) SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true, @@ -3123,16 +3143,15 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, llvm::APInt(IntSize, 8), Context->IntTy, SourceLocation()); - BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit, - BO_LE, - Context->IntTy, - SourceLocation()); + BinaryOperator *lessThanExpr = + new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, + VK_RValue, OK_Ordinary, SourceLocation()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) ConditionalOperator *CondExpr = new (Context) ConditionalOperator(lessThanExpr, SourceLocation(), CE, SourceLocation(), STCE, (Expr*)0, - returnType); + returnType, VK_RValue); ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), CondExpr); } @@ -3174,10 +3193,11 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), ID, getProtocolType(), 0, SC_Extern, SC_None); - DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue, + SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -4565,7 +4585,7 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { if (HasLocalVariableExternalStorage(DRE->getDecl())) { BlockDeclRefExpr *BDRE = new (Context)BlockDeclRefExpr(DRE->getDecl(), DRE->getType(), - DRE->getLocation(), false); + VK_LValue, DRE->getLocation(), false); BlockDeclRefs.push_back(BDRE); } @@ -4667,7 +4687,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { SourceLocation(), cast(LHSStmt), SourceLocation(), cast(RHSStmt), (Expr*)0, - Exp->getType()); + Exp->getType(), VK_RValue); return CondExpr; } else if (const ObjCIvarRefExpr *IRE = dyn_cast(BlockExp)) { CPT = IRE->getType()->getAs(); @@ -4720,7 +4740,8 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType()); + FD->getType(), VK_LValue, + OK_Ordinary); CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, @@ -4737,7 +4758,8 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { } CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0], BlkExprs.size(), - Exp->getType(), SourceLocation()); + Exp->getType(), VK_RValue, + SourceLocation()); return CE; } @@ -4772,7 +4794,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { /*BitWidth=*/0, /*Mutable=*/true); MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, FD, SourceLocation(), - FD->getType()); + FD->getType(), VK_LValue, + OK_Ordinary); llvm::StringRef Name = VD->getName(); FD = FieldDecl::Create(*Context, 0, SourceLocation(), @@ -4780,7 +4803,7 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), - DeclRefExp->getType()); + DeclRefExp->getType(), VK_LValue, OK_Ordinary); @@ -4799,8 +4822,9 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, - DRE->getType(), DRE->getLocation()); + Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, + DRE->getLocation()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5335,13 +5359,14 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, // Simulate a contructor call... FD = SynthBlockInitFunctionDecl(Tag); - DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue, + SourceLocation()); llvm::SmallVector InitExprs; // Initialize the block function. FD = SynthBlockInitFunctionDecl(Func); - DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), + DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, SourceLocation()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg); @@ -5354,12 +5379,15 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, &Context->Idents.get(DescData.c_str()), Context->VoidPtrTy, 0, SC_Static, SC_None); - UnaryOperator *DescRefExpr = new (Context) UnaryOperator( - new (Context) DeclRefExpr(NewVD, - Context->VoidPtrTy, SourceLocation()), - UO_AddrOf, - Context->getPointerType(Context->VoidPtrTy), - SourceLocation()); + UnaryOperator *DescRefExpr = + new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, + Context->VoidPtrTy, + VK_LValue, + SourceLocation()), + UO_AddrOf, + Context->getPointerType(Context->VoidPtrTy), + VK_RValue, OK_Ordinary, + SourceLocation()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5371,26 +5399,29 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (isObjCType((*I)->getType())) { // FIXME: Conform to ABI ([[obj retain] autorelease]). FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, - SourceLocation()); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); - Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg); } else { FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, - SourceLocation()); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation()); } } @@ -5411,10 +5442,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), - SourceLocation()); + Context->getPointerType(Exp->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5429,10 +5461,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, InitExprs.push_back(FlagExp); } NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - FType, SourceLocation()); + FType, VK_LValue, SourceLocation()); NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index e57e89e4a489..06c2758a9bd7 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -44,17 +44,21 @@ enum CastType { static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange); static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind); static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, CastKind &Kind, CXXCastPath &BasePath); static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind, @@ -156,44 +160,46 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, Diag(Ex->getLocStart(), diag::err_invalid_use_of_bound_member_func) << Ex->getSourceRange(); + ExprValueKind VK = VK_RValue; switch (Kind) { default: llvm_unreachable("Unknown C++ cast!"); case tok::kw_const_cast: if (!TypeDependent) - CheckConstCast(*this, Ex, DestType, OpRange, DestRange); + CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange); return Owned(CXXConstCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Ex, DestTInfo, OpLoc)); + VK, Ex, DestTInfo, OpLoc)); case tok::kw_dynamic_cast: { CastKind Kind = CK_Dependent; CXXCastPath BasePath; if (!TypeDependent) - CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath); + CheckDynamicCast(*this, Ex, DestType, VK, OpRange, DestRange, + Kind, BasePath); return Owned(CXXDynamicCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, &BasePath, DestTInfo, + VK, Kind, Ex, &BasePath, DestTInfo, OpLoc)); } case tok::kw_reinterpret_cast: { CastKind Kind = CK_Dependent; if (!TypeDependent) - CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind); + CheckReinterpretCast(*this, Ex, DestType, VK, OpRange, DestRange, Kind); return Owned(CXXReinterpretCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, 0, + VK, Kind, Ex, 0, DestTInfo, OpLoc)); } case tok::kw_static_cast: { CastKind Kind = CK_Dependent; CXXCastPath BasePath; if (!TypeDependent) - CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath); + CheckStaticCast(*this, Ex, DestType, VK, OpRange, Kind, BasePath); return Owned(CXXStaticCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, &BasePath, + VK, Kind, Ex, &BasePath, DestTInfo, OpLoc)); } } @@ -315,7 +321,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) { /// checked downcasts in class hierarchies. static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind, CXXCastPath &BasePath) { QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType(); @@ -326,11 +332,12 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, QualType DestPointee; const PointerType *DestPointer = DestType->getAs(); - const ReferenceType *DestReference = DestType->getAs(); + const ReferenceType *DestReference = 0; if (DestPointer) { DestPointee = DestPointer->getPointeeType(); - } else if (DestReference) { + } else if ((DestReference = DestType->getAs())) { DestPointee = DestReference->getPointeeType(); + VK = isa(DestReference) ? VK_LValue : VK_RValue; } else { Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr) << OrigDestType << DestRange; @@ -447,9 +454,10 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// const char *str = "literal"; /// legacy_function(const_cast\(str)); void -CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, +CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange) { - if (!DestType->isLValueReferenceType()) + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -466,9 +474,10 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// char *bytes = reinterpret_cast\(int_ptr); void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, const SourceRange &DestRange, - CastKind &Kind) { - if (!DestType->isLValueReferenceType()) + ExprValueKind &VK, const SourceRange &OpRange, + const SourceRange &DestRange, CastKind &Kind) { + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -498,8 +507,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// implicit conversions explicit and getting rid of data loss warnings. void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, CastKind &Kind, - CXXCastPath &BasePath) { + ExprValueKind &VK, const SourceRange &OpRange, + CastKind &Kind, CXXCastPath &BasePath) { // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". @@ -508,7 +517,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, return; } - if (!DestType->isLValueReferenceType() && !DestType->isRecordType()) + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue && !DestType->isRecordType()) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -1345,8 +1355,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, } bool -Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, +Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, + Expr *&CastExpr, CastKind &Kind, CXXCastPath &BasePath, bool FunctionalStyle) { if (CastExpr->isBoundMemberFunction(Context)) @@ -1368,7 +1378,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, return false; } - if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType()) + VK = Expr::getValueKindForType(CastTy); + if (VK == VK_RValue && !CastTy->isRecordType()) DefaultFunctionArrayLvalueConversion(CastExpr); // C++ [expr.cast]p5: The conversions performed by diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index d04addd2103f..ed45de53f264 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -487,8 +487,9 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // GCC does an implicit conversion to the pointer or integer ValType. This // can fail in some cases (1i -> int**), check for this error case now. CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; - if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath)) + if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, VK, BasePath)) return ExprError(); // Okay, we have something that *can* be converted to the right type. Check @@ -497,7 +498,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // pass in 42. The 42 gets converted to char. This is even more strange // for things like 45.123 -> char, etc. // FIXME: Do this check. - ImpCastExprToType(Arg, ValType, Kind, VK_RValue, &BasePath); + ImpCastExprToType(Arg, ValType, Kind, VK, &BasePath); TheCall->setArg(i+1, Arg); } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f7638f80d910..77f604a65361 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1515,7 +1515,8 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, Expr *CopyCtorArg = DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, - Constructor->getLocation(), ParamType, 0); + Constructor->getLocation(), ParamType, + VK_LValue, 0); // Cast to the base class to avoid ambiguities. QualType ArgTy = @@ -1577,7 +1578,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, Expr *MemberExprBase = DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, - Loc, ParamType, 0); + Loc, ParamType, VK_LValue, 0); // Build a reference to this field within the parameter. CXXScopeSpec SS; @@ -1622,7 +1623,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, // Create a reference to the iteration variable. ExprResult IterationVarRef - = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, Loc); + = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_RValue, Loc); assert(!IterationVarRef.isInvalid() && "Reference to invented variable cannot fail!"); @@ -4635,7 +4636,7 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, // Create a reference to the iteration variable; we'll use this several // times throughout. Expr *IterationVarRef - = S.BuildDeclRefExpr(IterationVar, SizeType, Loc).takeAs(); + = S.BuildDeclRefExpr(IterationVar, SizeType, VK_RValue, Loc).take(); assert(IterationVarRef && "Reference to invented variable cannot fail!"); // Create the DeclStmt that holds the iteration variable. @@ -4646,15 +4647,14 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, Upper.zextOrTrunc(S.Context.getTypeSize(SizeType)); Expr *Comparison = new (S.Context) BinaryOperator(IterationVarRef, - IntegerLiteral::Create(S.Context, - Upper, SizeType, Loc), - BO_NE, S.Context.BoolTy, Loc); + IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), + BO_NE, S.Context.BoolTy, + VK_RValue, OK_Ordinary, Loc); // Create the pre-increment of the iteration variable. Expr *Increment - = new (S.Context) UnaryOperator(IterationVarRef, - UO_PreInc, - SizeType, Loc); + = new (S.Context) UnaryOperator(IterationVarRef, UO_PreInc, SizeType, + VK_LValue, OK_Ordinary, Loc); // Subscript the "from" and "to" expressions with the iteration variable. From = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(From, Loc, @@ -4663,10 +4663,9 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, IterationVarRef, Loc)); // Build the copy for an individual element of the array. - StmtResult Copy = BuildSingleCopyAssign(S, Loc, - ArrayTy->getElementType(), - To, From, - CopyingBaseSubobject, Depth+1); + StmtResult Copy = BuildSingleCopyAssign(S, Loc, ArrayTy->getElementType(), + To, From, CopyingBaseSubobject, + Depth + 1); if (Copy.isInvalid()) return StmtError(); @@ -4907,7 +4906,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Construct a reference to the "other" object. We'll be using this // throughout the generated ASTs. - Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, Loc).takeAs(); + Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, VK_RValue, Loc).take(); assert(OtherRef && "Reference to parameter cannot fail!"); // Construct the "this" pointer. We'll be using this throughout the generated @@ -5068,7 +5067,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CollectableMemCpyRef = BuildDeclRefExpr(CollectableMemCpy, CollectableMemCpy->getType(), - Loc, 0).takeAs(); + VK_LValue, Loc, 0).take(); assert(CollectableMemCpyRef && "Builtin reference cannot fail"); } } @@ -5088,7 +5087,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, BuiltinMemCpyRef = BuildDeclRefExpr(BuiltinMemCpy, BuiltinMemCpy->getType(), - Loc, 0).takeAs(); + VK_LValue, Loc, 0).take(); assert(BuiltinMemCpyRef && "Builtin reference cannot fail"); } @@ -6105,7 +6104,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, // it can be destroyed later. InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl); Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl, - Loc, ExDeclType, 0); + Loc, ExDeclType, VK_LValue, 0); InitializationKind Kind = InitializationKind::CreateCopy(Loc, SourceLocation()); InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2cb92b6db68a..25c27fe62856 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -743,15 +743,16 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock, ExprResult -Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, - const CXXScopeSpec *SS) { +Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + SourceLocation Loc, const CXXScopeSpec *SS) { DeclarationNameInfo NameInfo(D->getDeclName(), Loc); - return BuildDeclRefExpr(D, Ty, NameInfo, SS); + return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS); } /// BuildDeclRefExpr - Build a DeclRefExpr. ExprResult Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS) { if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) { @@ -785,7 +786,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, return Owned(DeclRefExpr::Create(Context, SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, SS? SS->getRange() : SourceRange(), - D, NameInfo, Ty)); + D, NameInfo, Ty, VK)); } /// \brief Given a field that represents a member of an anonymous @@ -845,8 +846,9 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, // BaseObject is an anonymous struct/union variable (and is, // therefore, not part of another non-anonymous record). MarkDeclarationReferenced(Loc, BaseObject); - BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(), - Loc); + BaseObjectExpr = + new (Context) DeclRefExpr(BaseObject, BaseObject->getType(), + VK_LValue, Loc); BaseQuals = Context.getCanonicalType(BaseObject->getType()).getQualifiers(); } else if (BaseObjectExpr) { @@ -899,13 +901,14 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, for (llvm::SmallVector::reverse_iterator FI = AnonFields.rbegin(), FIEnd = AnonFields.rend(); FI != FIEnd; ++FI) { - QualType MemberType = (*FI)->getType(); + FieldDecl *Field = *FI; + QualType MemberType = Field->getType(); Qualifiers MemberTypeQuals = Context.getCanonicalType(MemberType).getQualifiers(); // CVR attributes from the base are picked up by members, // except that 'mutable' members don't pick up 'const'. - if ((*FI)->isMutable()) + if (Field->isMutable()) ResultQuals.removeConst(); // GC attributes are never picked up by members. @@ -922,7 +925,9 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI, *FI); // FIXME: Might this end up being a qualified name? Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI, - OpLoc, MemberType); + OpLoc, MemberType, VK_LValue, + Field->isBitField() ? + OK_BitField : OK_Ordinary); BaseObjectIsPointer = false; ResultQuals = NewQuals; } @@ -1526,7 +1531,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (const FunctionProtoType *Proto = T->getAs()) NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType(), Proto->getExtInfo()); - return BuildDeclRefExpr(Func, NoProtoType, NameLoc, &SS); + // Note that functions are r-values in C. + return BuildDeclRefExpr(Func, NoProtoType, VK_RValue, NameLoc, &SS); } } @@ -1916,6 +1922,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = 0) { NestedNameSpecifier *Qualifier = 0; SourceRange QualifierRange; @@ -1926,7 +1933,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange, Member, FoundDecl, MemberNameInfo, - TemplateArgs, Ty); + TemplateArgs, Ty, VK, OK); } /// Builds an implicit member access expression. The current context @@ -2083,6 +2090,18 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, return Owned(ULE); } +static ExprValueKind getValueKindForDecl(ASTContext &Context, + const ValueDecl *D) { + if (isa(D) || isa(D)) return VK_LValue; + if (!Context.getLangOptions().CPlusPlus) return VK_RValue; + if (isa(D)) { + if (isa(D) && cast(D)->isInstance()) + return VK_RValue; + return VK_LValue; + } + return Expr::getValueKindForType(D->getType()); +} + /// \brief Complete semantic analysis for a reference to the given declaration. ExprResult @@ -2126,6 +2145,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, if (VD->isInvalidDecl()) return ExprError(); + ExprValueKind VK = getValueKindForDecl(Context, VD); + // If the identifier reference is inside a block, and it refers to a value // that is outside the block, create a BlockDeclRefExpr instead of a // DeclRefExpr. This ensures the value is treated as a copy-in snapshot when @@ -2150,6 +2171,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, MarkDeclarationReferenced(Loc, VD); QualType ExprTy = VD->getType().getNonReferenceType(); + // The BlocksAttr indicates the variable is bound by-reference. bool byrefVar = (VD->getAttr() != 0); QualType T = VD->getType(); @@ -2160,17 +2182,17 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, bool constAdded = !ExprTy.isConstQualified(); // Variable will be bound by-copy, make it const within the closure. ExprTy.addConst(); - BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false, - constAdded); + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, VK, + Loc, false, constAdded); } else - BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true); + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, VK, Loc, true); if (getLangOptions().CPlusPlus) { if (!T->isDependentType() && !T->isReferenceType()) { Expr *E = new (Context) DeclRefExpr(const_cast(BDRE->getDecl()), T, - SourceLocation()); + VK, SourceLocation()); if (T->getAs()) if (!T->isUnionType()) { ExprResult Res = PerformCopyInitialization( @@ -2191,7 +2213,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. - return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), VK, NameInfo, &SS); } @@ -2624,7 +2646,9 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, if (getLangOptions().CPlusPlus && (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, - Context.DependentTy, RLoc)); + Context.DependentTy, + VK_LValue, OK_Ordinary, + RLoc)); } if (getLangOptions().CPlusPlus && @@ -2651,6 +2675,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, DefaultFunctionArrayLvalueConversion(RHSExp); QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType(); + ExprValueKind VK = VK_LValue; + ExprObjectKind OK = OK_Ordinary; // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent // to the expression *((e1)+(e2)). This means the array "Base" may actually be @@ -2685,6 +2711,9 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, } else if (const VectorType *VTy = LHSTy->getAs()) { BaseExpr = LHSExp; // vectors: V[123] IndexExpr = RHSExp; + VK = LHSExp->getValueKind(); + if (VK != VK_RValue) + OK = OK_VectorComponent; // FIXME: need to deal with const... ResultType = VTy->getElementType(); @@ -2756,7 +2785,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, } return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, - ResultType, RLoc)); + ResultType, VK, OK, RLoc)); } QualType Sema:: @@ -3240,11 +3269,17 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return BuildAnonymousStructUnionMemberReference(MemberLoc, FD, BaseExpr, OpLoc); + // x.a is an l-value if 'a' has a reference type. Otherwise: + // x.a is an l-value/x-value/pr-value if the base is (and note + // that *x is always an l-value). + ExprValueKind VK = IsArrow ? VK_LValue : BaseExpr->getValueKind(); + // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] QualType MemberType = FD->getType(); - if (const ReferenceType *Ref = MemberType->getAs()) + if (const ReferenceType *Ref = MemberType->getAs()) { MemberType = Ref->getPointeeType(); - else { + VK = VK_LValue; + } else { Qualifiers BaseQuals = BaseType.getQualifiers(); BaseQuals.removeObjCGCAttr(); if (FD->isMutable()) BaseQuals.removeConst(); @@ -3262,28 +3297,34 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return ExprError(); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, FD, FoundDecl, MemberNameInfo, - MemberType)); + MemberType, VK, + FD->isBitField() ? OK_BitField : OK_Ordinary)); } if (VarDecl *Var = dyn_cast(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, Var); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, Var, FoundDecl, MemberNameInfo, - Var->getType().getNonReferenceType())); + Var->getType().getNonReferenceType(), + Expr::getValueKindForType(Var->getType()), + OK_Ordinary)); } - if (FunctionDecl *MemberFn = dyn_cast(MemberDecl)) { + if (CXXMethodDecl *MemberFn = dyn_cast(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, MemberFn, FoundDecl, MemberNameInfo, - MemberFn->getType())); + MemberFn->getType(), + MemberFn->isInstance() ? VK_RValue : VK_LValue, + OK_Ordinary)); } + assert(!isa(MemberDecl) && "member function not C++ method?"); if (EnumConstantDecl *Enum = dyn_cast(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, Enum, FoundDecl, MemberNameInfo, - Enum->getType())); + Enum->getType(), VK_RValue, OK_Ordinary)); } Owned(BaseExpr); @@ -3435,7 +3476,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, PType = (*(Setter->param_end() -1))->getType(); // FIXME: we must check that the setter has property type. return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, - PType, + PType, VK_LValue, + OK_ObjCProperty, Setter, MemberLoc, BaseExpr)); } return ExprError(Diag(MemberLoc, diag::err_property_not_found) @@ -3599,6 +3641,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, return ExprError(); return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, OK_ObjCProperty, MemberLoc, BaseExpr)); } @@ -3615,6 +3658,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, SMD = dyn_cast(SDecl); QualType PType = OMD->getSendResultType(); return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(OMD, PType, + VK_LValue, + OK_ObjCProperty, SMD, MemberLoc, BaseExpr)); @@ -3647,7 +3692,9 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc); if (ret.isNull()) return ExprError(); - return Owned(new (Context) ExtVectorElementExpr(ret, BaseExpr, *Member, + return Owned(new (Context) ExtVectorElementExpr(ret, + BaseExpr->getValueKind(), + BaseExpr, *Member, MemberLoc)); } @@ -3959,7 +4006,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, } return Owned(new (Context) CallExpr(Context, Fn, 0, 0, Context.VoidTy, - RParenLoc)); + VK_RValue, RParenLoc)); } // Determine whether this is a dependent call inside a C++ template, @@ -3974,7 +4021,8 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, if (Dependent) return Owned(new (Context) CallExpr(Context, Fn, Args, NumArgs, - Context.DependentTy, RParenLoc)); + Context.DependentTy, VK_RValue, + RParenLoc)); // Determine whether this is a call to an object (C++ [over.call.object]). if (Fn->getType()->isRecordType()) @@ -4014,10 +4062,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, if (const FunctionProtoType *FPT = BO->getType()->getAs()) { QualType ResultTy = FPT->getCallResultType(Context); + ExprValueKind VK = Expr::getValueKindForType(FPT->getResultType()); CXXMemberCallExpr *TheCall = new (Context) CXXMemberCallExpr(Context, BO, Args, - NumArgs, ResultTy, + NumArgs, ResultTy, VK, RParenLoc); if (CheckCallReturnType(FPT->getResultType(), @@ -4081,6 +4130,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, CallExpr *TheCall = new (Context) CallExpr(Context, Fn, Args, NumArgs, Context.BoolTy, + VK_RValue, RParenLoc); const FunctionType *FuncT; @@ -4108,6 +4158,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // We know the result type of the call, set it. TheCall->setType(FuncT->getCallResultType(Context)); + TheCall->setValueKind(Expr::getValueKindForType(FuncT->getResultType())); if (const FunctionProtoType *Proto = dyn_cast(FuncT)) { if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs, @@ -4243,8 +4294,11 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, return ExprError(); } + // In C, compound literals are l-values for some reason. + ExprValueKind VK = getLangOptions().CPlusPlus ? VK_RValue : VK_LValue; + return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - literalExpr, isFileScope)); + VK, literalExpr, isFileScope)); } ExprResult @@ -4388,16 +4442,18 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { } /// CheckCastTypes - Check type constraints for casting between types. -bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, - CastKind& Kind, - CXXCastPath &BasePath, - bool FunctionalStyle) { +bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, + Expr *&castExpr, CastKind& Kind, ExprValueKind &VK, + CXXCastPath &BasePath, bool FunctionalStyle) { if (getLangOptions().CPlusPlus) return CXXCheckCStyleCast(SourceRange(TyR.getBegin(), castExpr->getLocEnd()), - castType, castExpr, Kind, BasePath, + castType, VK, castExpr, Kind, BasePath, FunctionalStyle); + // We only support r-value casts in C. + VK = VK_RValue; + DefaultFunctionArrayLvalueConversion(castExpr); // C99 6.5.4p2: the cast type needs to be void or scalar and the expression @@ -4574,14 +4630,15 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *castExpr) { CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr, - Kind, BasePath)) + Kind, VK, BasePath)) return ExprError(); return Owned(CStyleCastExpr::Create(Context, Ty->getType().getNonLValueExprType(Context), - Kind, castExpr, &BasePath, Ty, + VK, Kind, castExpr, &BasePath, Ty, LParenLoc, RParenLoc)); } @@ -4669,7 +4726,7 @@ ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, /// In that case, lhs = cond. /// C99 6.5.15 QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, - Expr *&SAVE, + Expr *&SAVE, ExprValueKind &VK, SourceLocation QuestionLoc) { // If both LHS and RHS are overloaded functions, try to resolve them. if (Context.hasSameType(LHS->getType(), RHS->getType()) && @@ -4688,7 +4745,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // C++ is sufficiently different to merit its own checker. if (getLangOptions().CPlusPlus) - return CXXCheckConditionalOperands(Cond, LHS, RHS, SAVE, QuestionLoc); + return CXXCheckConditionalOperands(Cond, LHS, RHS, SAVE, VK, QuestionLoc); + + VK = VK_RValue; UsualUnaryConversions(Cond); if (SAVE) { @@ -5053,15 +5112,16 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, LHSExpr = SAVEExpr = CondExpr; } + ExprValueKind VK = VK_RValue; QualType result = CheckConditionalOperands(CondExpr, LHSExpr, RHSExpr, - SAVEExpr, QuestionLoc); + SAVEExpr, VK, QuestionLoc); if (result.isNull()) return ExprError(); return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc, LHSExpr, ColonLoc, RHSExpr, SAVEExpr, - result)); + result, VK)); } // CheckPointerTypesForAssignment - This is a very tricky routine (despite @@ -5499,7 +5559,7 @@ static void ConstructTransparentUnion(ASTContext &C, Expr *&E, // union type from this initializer list. TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType); E = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType, - Initializer, false); + VK_RValue, Initializer, false); } Sema::AssignConvertType @@ -6649,6 +6709,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, LHSType->isObjCObjectPointerType()))) ConvTy = Compatible; + if (ConvTy == Compatible && + getLangOptions().ObjCNonFragileABI && + LHSType->isObjCObjectType()) + Diag(Loc, diag::err_assignment_requires_nonfragile_object) + << LHSType; + // If the RHS is a unary plus or minus, check to see if they = and + are // right next to each other. If so, the user may have typo'd "x =+ 4" // instead of "x += 4". @@ -7148,14 +7214,20 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, // The following two variables are used for compound assignment operators QualType CompLHSTy; // Type of LHS after promotions for computation QualType CompResultTy; // Type of computation result + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType()); + if (getLangOptions().CPlusPlus) { + VK = rhs->getValueKind(); + OK = rhs->getObjectKind(); + } break; case BO_PtrMemD: case BO_PtrMemI: - ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc, + ResultTy = CheckPointerToMemberOperands(lhs, rhs, VK, OpLoc, Opc == BO_PtrMemI); break; case BO_Mul: @@ -7198,7 +7270,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, case BO_MulAssign: case BO_DivAssign: CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true, - Opc == BO_DivAssign); + Opc == BO_DivAssign); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); @@ -7236,21 +7308,25 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, break; case BO_Comma: ResultTy = CheckCommaOperands(lhs, rhs, OpLoc); + if (getLangOptions().CPlusPlus) { + VK = rhs->getValueKind(); + OK = rhs->getObjectKind(); + } break; } if (ResultTy.isNull()) return ExprError(); - if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) { - if (Opc >= BO_Assign && Opc <= BO_OrAssign) - Diag(OpLoc, diag::err_assignment_requires_nonfragile_object) - << ResultTy; - } if (CompResultTy.isNull()) - return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc)); - else - return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy, - CompLHSTy, CompResultTy, - OpLoc)); + return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, + VK, OK, OpLoc)); + + if (getLangOptions().CPlusPlus) { + VK = VK_LValue; + OK = lhs->getObjectKind(); + } + return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy, + VK, OK, CompLHSTy, + CompResultTy, OpLoc)); } /// SuggestParentheses - Emit a diagnostic together with a fixit hint that wraps @@ -7470,10 +7546,15 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, Expr *Input) { UnaryOperatorKind Opc = static_cast(OpcIn); + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; QualType resultType; switch (Opc) { case UO_PreInc: case UO_PreDec: + VK = VK_LValue; + OK = Input->getObjectKind(); + // fallthrough case UO_PostInc: case UO_PostDec: resultType = CheckIncrementDecrementOperand(Input, OpLoc, @@ -7488,6 +7569,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Deref: DefaultFunctionArrayLvalueConversion(Input); resultType = CheckIndirectionOperand(Input, OpLoc); + VK = VK_LValue; break; case UO_Plus: case UO_Minus: @@ -7558,15 +7640,22 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Real: case UO_Imag: resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real); + // _Real and _Imag map ordinary l-values into ordinary l-values. + if (Input->getValueKind() != VK_RValue && + Input->getObjectKind() == OK_Ordinary) + VK = Input->getValueKind(); break; case UO_Extension: resultType = Input->getType(); + VK = Input->getValueKind(); + OK = Input->getObjectKind(); break; } if (resultType.isNull()) return ExprError(); - return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc)); + return Owned(new (Context) UnaryOperator(Input, Opc, resultType, + VK, OK, OpLoc)); } ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, @@ -7884,6 +7973,8 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, SourceLocation RPLoc) { assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)"); + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; QualType resType; bool ValueDependent = false; if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) { @@ -7899,13 +7990,16 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, << CondExpr->getSourceRange()); // If the condition is > zero, then the AST type is the same as the LSHExpr. - resType = condEval.getZExtValue() ? LHSExpr->getType() : RHSExpr->getType(); - ValueDependent = condEval.getZExtValue() ? LHSExpr->isValueDependent() - : RHSExpr->isValueDependent(); + Expr *ActiveExpr = condEval.getZExtValue() ? LHSExpr : RHSExpr; + + resType = ActiveExpr->getType(); + ValueDependent = ActiveExpr->isValueDependent(); + VK = ActiveExpr->getValueKind(); + OK = ActiveExpr->getObjectKind(); } return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, - resType, RPLoc, + resType, VK, OK, RPLoc, resType->isDependentType(), ValueDependent)); } @@ -8154,8 +8248,8 @@ ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, } ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, - Expr *E, TypeSourceInfo *TInfo, - SourceLocation RPLoc) { + Expr *E, TypeSourceInfo *TInfo, + SourceLocation RPLoc) { Expr *OrigExpr = E; // Get the va_list type diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 70e9a97fc673..fbd36fd61d79 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -605,9 +605,10 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // if (NumExprs == 1) { CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0], - Kind, BasePath, + Kind, VK, BasePath, /*FunctionalStyle=*/true)) return ExprError(); @@ -615,7 +616,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return Owned(CXXFunctionalCastExpr::Create(Context, Ty.getNonLValueExprType(Context), - TInfo, TyBeginLoc, Kind, + VK, TInfo, TyBeginLoc, Kind, Exprs[0], &BasePath, RParenLoc)); } @@ -1582,8 +1583,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, /// \brief Check the use of the given variable as a C++ condition in an if, /// while, do-while, or switch statement. ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, - SourceLocation StmtLoc, - bool ConvertToBoolean) { + SourceLocation StmtLoc, + bool ConvertToBoolean) { QualType T = ConditionVar->getType(); // C++ [stmt.select]p2: @@ -1599,7 +1600,8 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType()); + ConditionVar->getType().getNonReferenceType(), + Expr::getValueKindForType(ConditionVar->getType())); if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc)) return ExprError(); @@ -2331,8 +2333,10 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, RParen, Context.BoolTy)); } -QualType Sema::CheckPointerToMemberOperands( - Expr *&lex, Expr *&rex, SourceLocation Loc, bool isIndirect) { +QualType Sema::CheckPointerToMemberOperands(Expr *&lex, Expr *&rex, + ExprValueKind &VK, + SourceLocation Loc, + bool isIndirect) { const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall @@ -2361,7 +2365,7 @@ QualType Sema::CheckPointerToMemberOperands( QualType LType = lex->getType(); if (isIndirect) { if (const PointerType *Ptr = LType->getAs()) - LType = Ptr->getPointeeType().getNonReferenceType(); + LType = Ptr->getPointeeType(); else { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << 1 << LType @@ -2402,6 +2406,7 @@ QualType Sema::CheckPointerToMemberOperands( Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; return QualType(); } + // C++ 5.5p2 // The result is an object or a function of the type specified by the // second operand. @@ -2416,6 +2421,21 @@ QualType Sema::CheckPointerToMemberOperands( // We probably need a "MemberFunctionClosureType" or something like that. QualType Result = MemPtr->getPointeeType(); Result = Context.getCVRQualifiedType(Result, LType.getCVRQualifiers()); + + // C++ [expr.mptr.oper]p6: + // The result of a .* expression whose second operand is a pointer + // to a data member is of the same value category as its + // first operand. The result of a .* expression whose second + // operand is a pointer to a member function is a prvalue. The + // result of an ->* expression is an lvalue if its second operand + // is a pointer to data member and a prvalue otherwise. + if (Result->isFunctionType()) + VK = VK_RValue; + else if (isIndirect) + VK = VK_LValue; + else + VK = lex->getValueKind(); + return Result; } @@ -2573,7 +2593,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) { /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y /// extension. In this case, LHS == Cond. (But they're not aliases.) QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, - Expr *&SAVE, + Expr *&SAVE, ExprValueKind &VK, SourceLocation QuestionLoc) { // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++ // interface pointers. @@ -2591,6 +2611,9 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, return QualType(); } + // Assume r-value. + VK = VK_RValue; + // Either of the arguments dependent? if (LHS->isTypeDependent() || RHS->isTypeDependent()) return Context.DependentTy; @@ -2670,19 +2693,20 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, } // C++0x 5.16p4 - // If the second and third operands are lvalues and have the same type, - // the result is of that type [...] + // If the second and third operands are glvalues of the same value + // category and have the same type, the result is of that type and + // value category and it is a bit-field if the second or the third + // operand is a bit-field, or if both are bit-fields. + // We can't support the bitfield parts of that correctly right now, + // though, so we just require both sides to be ordinary values. bool Same = Context.hasSameType(LTy, RTy); - if (Same && LHS->isLvalue(Context) == Expr::LV_Valid && - RHS->isLvalue(Context) == Expr::LV_Valid) { - // In this context, property reference is really a message call and - // is not considered an l-value. - bool lhsProperty = (isa(LHS) || - isa(LHS)); - bool rhsProperty = (isa(RHS) || - isa(RHS)); - if (!lhsProperty && !rhsProperty) - return LTy; + if (Same && + LHS->getValueKind() != VK_RValue && + LHS->getValueKind() == RHS->getValueKind() && + LHS->getObjectKind() == OK_Ordinary && + RHS->getObjectKind() == OK_Ordinary) { + VK = LHS->getValueKind(); + return LTy; } // C++0x 5.16p5 @@ -3456,11 +3480,15 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, MemberExpr *ME = new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, - SourceLocation(), Method->getType()); - QualType ResultType = Method->getCallResultType(); + SourceLocation(), Method->getType(), + VK_RValue, OK_Ordinary); + QualType ResultType = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultType); + ResultType = ResultType.getNonLValueExprType(Context); + MarkDeclarationReferenced(Exp->getLocStart(), Method); CXXMemberCallExpr *CE = - new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, + new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, VK, Exp->getLocEnd()); return CE; } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index be87a42a3cf7..a99a72f3c853 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -199,7 +199,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, SourceLocation lbrac, SourceLocation rbrac, - QualType &ReturnType) { + QualType &ReturnType, ExprValueKind &VK) { if (!Method) { // Apply default argument promotion as for (C99 6.5.2.2p6). for (unsigned i = 0; i != NumArgs; i++) { @@ -214,10 +214,12 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Diag(lbrac, DiagID) << Sel << isClassMessage << SourceRange(lbrac, rbrac); ReturnType = Context.getObjCIdType(); + VK = VK_RValue; return false; } ReturnType = Method->getSendResultType(); + VK = Expr::getValueKindForType(Method->getResultType()); unsigned NumNamedArgs = Sel.getNumArgs(); // Method might have more arguments than selector indicates. This is due @@ -226,8 +228,8 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, NumNamedArgs = Method->param_size(); // FIXME. This need be cleaned up. if (NumArgs < NumNamedArgs) { - Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2 - << NumNamedArgs << NumArgs; + Diag(lbrac, diag::err_typecheck_call_too_few_args) + << 2 << NumNamedArgs << NumArgs; return false; } @@ -357,13 +359,16 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Selector Sel = PP.getSelectorTable().getNullarySelector(Member); ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc)) - ResTy = Getter->getSendResultType(); + ResTy = Getter->getResultType(); + if (Super) return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, + VK_LValue, OK_ObjCProperty, MemberLoc, SuperLoc, SuperType)); else return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, + VK_LValue, OK_ObjCProperty, MemberLoc, BaseExpr)); } // Check protocols on qualified interfaces. @@ -374,11 +379,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); if (Super) - return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), - MemberLoc, - SuperLoc, SuperType)); + return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, + OK_ObjCProperty, + MemberLoc, + SuperLoc, SuperType)); else return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, + OK_ObjCProperty, MemberLoc, BaseExpr)); } @@ -426,12 +435,12 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, PType = Getter->getSendResultType(); if (Super) return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - Setter, MemberLoc, - SuperLoc, SuperType)); + VK_LValue, OK_ObjCProperty, + Setter, MemberLoc, SuperLoc, SuperType)); else return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - Setter, MemberLoc, - BaseExpr)); + VK_LValue, OK_ObjCProperty, + Setter, MemberLoc, BaseExpr)); } @@ -546,7 +555,8 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, PType = (*PI)->getType(); } return Owned(new (Context) ObjCImplicitSetterGetterRefExpr( - Getter, PType, Setter, + Getter, PType, VK_LValue, OK_ObjCProperty, + Setter, propertyNameLoc, IFace, receiverNameLoc)); } return ExprError(Diag(propertyNameLoc, diag::err_property_not_found) @@ -751,8 +761,9 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast(ArgsIn.release()); assert(SuperLoc.isInvalid() && "Message to super with dependent type"); - return Owned(ObjCMessageExpr::Create(Context, ReceiverType, LBracLoc, - ReceiverTypeInfo, Sel, /*Method=*/0, + return Owned(ObjCMessageExpr::Create(Context, ReceiverType, + VK_RValue, LBracLoc, ReceiverTypeInfo, + Sel, /*Method=*/0, Args, NumArgs, RBracLoc)); } @@ -790,21 +801,23 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, // Check the argument types and determine the result type. QualType ReturnType; + ExprValueKind VK = VK_RValue; + unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast(ArgsIn.release()); if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true, - LBracLoc, RBracLoc, ReturnType)) + LBracLoc, RBracLoc, ReturnType, VK)) return ExprError(); // Construct the appropriate ObjCMessageExpr. Expr *Result; if (SuperLoc.isValid()) - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false, ReceiverType, Sel, Method, Args, NumArgs, RBracLoc); else - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, Method, Args, NumArgs, RBracLoc); return MaybeBindToTemporary(Result); @@ -889,7 +902,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Expr **Args = reinterpret_cast(ArgsIn.release()); assert(SuperLoc.isInvalid() && "Message to super with dependent type"); return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy, - LBracLoc, Receiver, Sel, + VK_RValue, LBracLoc, Receiver, Sel, /*Method=*/0, Args, NumArgs, RBracLoc)); } @@ -1050,8 +1063,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast(ArgsIn.release()); QualType ReturnType; + ExprValueKind VK = VK_RValue; if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, false, - LBracLoc, RBracLoc, ReturnType)) + LBracLoc, RBracLoc, ReturnType, VK)) return ExprError(); if (!ReturnType->isVoidType()) { @@ -1063,12 +1077,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // Construct the appropriate ObjCMessageExpr instance. Expr *Result; if (SuperLoc.isValid()) - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true, ReceiverType, Sel, Method, Args, NumArgs, RBracLoc); else - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, + Receiver, Sel, Method, Args, NumArgs, RBracLoc); return MaybeBindToTemporary(Result); } diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 65002f3ea037..607b7b1782af 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -485,8 +485,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // FIXME. Eventually we want to do this for Objective-C as well. ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = - new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), - SourceLocation()); + new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), + VK_RValue, SourceLocation()); Expr *IvarRefExpr = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, SelfExpr, true, true); @@ -512,15 +512,15 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // FIXME. Eventually we want to do this for Objective-C as well. ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = - new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), - SourceLocation()); + new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), + VK_RValue, SourceLocation()); Expr *lhs = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, SelfExpr, true, true); ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); ParmVarDecl *Param = (*P); - Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(), - SourceLocation()); + Expr *rhs = new (Context) DeclRefExpr(Param, Param->getType(), + VK_LValue, SourceLocation()); ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), BO_Assign, lhs, rhs); PIDecl->setSetterCXXAssignment(Res.takeAs()); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 65d6bc8f7a02..a0e4816683b5 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -33,6 +33,16 @@ namespace clang { using namespace sema; +/// A convenience routine for creating a decayed reference to a +/// function. +static Expr * +CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, + SourceLocation Loc = SourceLocation()) { + Expr *E = new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc); + S.DefaultFunctionArrayConversion(E); + return E; +} + static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS); @@ -3895,7 +3905,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // call on the stack and we don't need its arguments to be // well-formed. DeclRefExpr ConversionRef(Conversion, Conversion->getType(), - From->getLocStart()); + VK_LValue, From->getLocStart()); ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack, Context.getPointerType(Conversion->getType()), CK_FunctionToPointerDecay, @@ -3909,10 +3919,12 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, return; } + ExprValueKind VK = Expr::getValueKindForType(Conversion->getConversionType()); + // Note that it is safe to allocate CallExpr on the stack here because // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). - CallExpr Call(Context, &ConversionFn, 0, 0, CallResultType, + CallExpr Call(Context, &ConversionFn, 0, 0, CallResultType, VK, From->getLocStart()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, &Call, ToType, @@ -7086,6 +7098,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, return Owned(new (Context) UnaryOperator(Input, Opc, Context.DependentTy, + VK_RValue, OK_Ordinary, OpLoc)); CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators @@ -7097,6 +7110,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, &Args[0], NumArgs, Context.DependentTy, + VK_RValue, OpLoc)); } @@ -7151,18 +7165,18 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, DiagnoseUseOfDecl(Best->FoundDecl, OpLoc); - // Determine the result type - QualType ResultTy = FnDecl->getCallResultType(); + // Determine the result type. + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - SourceLocation()); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl); Args[0] = Input; CallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr, - Args, NumArgs, ResultTy, OpLoc); + Args, NumArgs, ResultTy, VK, OpLoc); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -7248,10 +7262,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // BinaryOperator or CompoundAssignment. if (Opc <= BO_Assign || Opc > BO_OrAssign) return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc, - Context.DependentTy, OpLoc)); + Context.DependentTy, + VK_RValue, OK_Ordinary, + OpLoc)); return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc, Context.DependentTy, + VK_LValue, + OK_Ordinary, Context.DependentTy, Context.DependentTy, OpLoc)); @@ -7269,6 +7287,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, 2, Context.DependentTy, + VK_RValue, OpLoc)); } @@ -7362,19 +7381,17 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, DiagnoseUseOfDecl(Best->FoundDecl, OpLoc); - // Determine the result type - QualType ResultTy - = FnDecl->getType()->getAs() - ->getCallResultType(Context); + // Determine the result type. + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - OpLoc); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr, - Args, 2, ResultTy, OpLoc); + Args, 2, ResultTy, VK, OpLoc); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -7474,6 +7491,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args, 2, Context.DependentTy, + VK_RValue, RLoc)); } @@ -7521,19 +7539,17 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, Args[1] = InputInit.takeAs(); // Determine the result type - QualType ResultTy - = FnDecl->getType()->getAs() - ->getCallResultType(Context); + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - LLoc); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Subscript, FnExpr, Args, 2, - ResultTy, RLoc); + ResultTy, VK, RLoc); if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall, FnDecl)) @@ -7704,11 +7720,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, MemExpr = cast(MemExprE->IgnoreParens()); } + QualType ResultType = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultType); + ResultType = ResultType.getNonLValueExprType(Context); + assert(Method && "Member call to something that isn't a method?"); CXXMemberCallExpr *TheCall = new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs, - Method->getCallResultType(), - RParenLoc); + ResultType, VK, RParenLoc); // Check for a valid return type. if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(), @@ -7909,17 +7928,18 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) MethodArgs[ArgIdx + 1] = Args[ArgIdx]; - Expr *NewFn = new (Context) DeclRefExpr(Method, Method->getType(), - SourceLocation()); - UsualUnaryConversions(NewFn); + Expr *NewFn = CreateFunctionRefExpr(*this, Method); // Once we've built TheCall, all of the expressions are properly // owned. - QualType ResultTy = Method->getCallResultType(); + QualType ResultTy = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); + CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn, MethodArgs, NumArgs + 1, - ResultTy, RParenLoc); + ResultTy, VK, RParenLoc); delete [] MethodArgs; if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall, @@ -8064,14 +8084,14 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { return ExprError(); // Build the operator call. - Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(), - SourceLocation()); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, Method); - QualType ResultTy = Method->getCallResultType(); + QualType ResultTy = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, - &Base, 1, ResultTy, OpLoc); + &Base, 1, ResultTy, VK, OpLoc); if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall, Method)) @@ -8140,8 +8160,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, QualType MemPtrType = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); - return new (Context) UnaryOperator(SubExpr, UO_AddrOf, - MemPtrType, UnOp->getOperatorLoc()); + return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, + VK_RValue, OK_Ordinary, + UnOp->getOperatorLoc()); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), @@ -8151,6 +8172,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, return new (Context) UnaryOperator(SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), + VK_RValue, OK_Ordinary, UnOp->getOperatorLoc()); } @@ -8168,6 +8190,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Fn, ULE->getNameLoc(), Fn->getType(), + VK_LValue, TemplateArgs); } @@ -8181,7 +8204,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Expr *Base; - // If we're filling in + // If we're filling in a static method where we used to have an + // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast(Fn)->isStatic()) { return DeclRefExpr::Create(Context, @@ -8190,6 +8214,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Fn, MemExpr->getMemberLoc(), Fn->getType(), + VK_LValue, TemplateArgs); } else { SourceLocation Loc = MemExpr->getMemberLoc(); @@ -8210,7 +8235,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Found, MemExpr->getMemberNameInfo(), TemplateArgs, - Fn->getType()); + Fn->getType(), + cast(Fn)->isStatic() + ? VK_LValue : VK_RValue, + OK_Ordinary); } llvm_unreachable("Invalid reference to overloaded function"); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3f4a1af77278..4c25bc32df5e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3361,9 +3361,10 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, CXXScopeSpec SS; SS.setScopeRep(Qualifier); ExprResult RefExpr = BuildDeclRefExpr(VD, - VD->getType().getNonReferenceType(), - Loc, - &SS); + VD->getType().getNonReferenceType(), + VK_LValue, + Loc, + &SS); if (RefExpr.isInvalid()) return ExprError(); @@ -3390,7 +3391,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, if (ParamType->isPointerType()) { // When the non-type template parameter is a pointer, take the // address of the declaration. - ExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc); + ExprResult RefExpr = BuildDeclRefExpr(VD, T, VK_LValue, Loc); if (RefExpr.isInvalid()) return ExprError(); @@ -3410,13 +3411,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get()); } + ExprValueKind VK = VK_RValue; + // If the non-type template parameter has reference type, qualify the // resulting declaration reference with the extra qualifiers on the // type that the reference refers to. - if (const ReferenceType *TargetRef = ParamType->getAs()) - T = Context.getQualifiedType(T, TargetRef->getPointeeType().getQualifiers()); + if (const ReferenceType *TargetRef = ParamType->getAs()) { + VK = VK_LValue; + T = Context.getQualifiedType(T, + TargetRef->getPointeeType().getQualifiers()); + } - return BuildDeclRefExpr(VD, T, Loc); + return BuildDeclRefExpr(VD, T, VK, Loc); } /// \brief Construct a new expression that refers to the given diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index bae703daa301..807346c4c57a 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1142,26 +1142,32 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, - bool isArrow, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - const DeclarationNameInfo &MemberNameInfo, - ValueDecl *Member, - NamedDecl *FoundDecl, + bool isArrow, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + const DeclarationNameInfo &MemberNameInfo, + ValueDecl *Member, + NamedDecl *FoundDecl, const TemplateArgumentListInfo *ExplicitTemplateArgs, - NamedDecl *FirstQualifierInScope) { + NamedDecl *FirstQualifierInScope) { if (!Member->getDeclName()) { - // We have a reference to an unnamed field. + // We have a reference to an unnamed field. This is always the + // base of an anonymous struct/union member access, i.e. the + // field is always of record type. assert(!Qualifier && "Can't have an unnamed field with a qualifier!"); + assert(Member->getType()->isRecordType() && + "unnamed member not of record type?"); if (getSema().PerformObjectMemberConversion(Base, Qualifier, FoundDecl, Member)) return ExprError(); + ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind(); MemberExpr *ME = new (getSema().Context) MemberExpr(Base, isArrow, Member, MemberNameInfo, - cast(Member)->getType()); + cast(Member)->getType(), + VK, OK_Ordinary); return getSema().Owned(ME); } @@ -1903,18 +1909,21 @@ public: // perform semantic analysis again. if (Super) return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, - Setter, - NameLoc, - SuperLoc, - SuperTy)); + new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, + VK_LValue, + OK_Ordinary, + Setter, + NameLoc, + SuperLoc, + SuperTy)); else return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr( - Getter, T, - Setter, - NameLoc, - Base)); + new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, + VK_LValue, + OK_Ordinary, + Setter, + NameLoc, + Base)); } /// \brief Build a new Objective-C "isa" expression. @@ -1948,8 +1957,8 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, - MultiExprArg SubExprs, - SourceLocation RParenLoc) { + MultiExprArg SubExprs, + SourceLocation RParenLoc) { // Find the declaration for __builtin_shufflevector const IdentifierInfo &Name = SemaRef.Context.Idents.get("__builtin_shufflevector"); @@ -1961,7 +1970,7 @@ public: FunctionDecl *Builtin = cast(*Lookup.first); Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(), - BuiltinLoc); + VK_LValue, BuiltinLoc); SemaRef.UsualUnaryConversions(Callee); // Build the CallExpr @@ -1970,6 +1979,7 @@ public: CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, Subs, NumSubExprs, Builtin->getCallResultType(), + Expr::getValueKindForType(Builtin->getResultType()), RParenLoc); ExprResult OwnedCall(SemaRef.Owned(TheCall)); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 26077c5fb744..6d578f616ed3 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -59,7 +59,7 @@ namespace clang { /// \brief The number of record fields required for the Expr class /// itself. - static const unsigned NumExprFields = NumStmtFields + 3; + static const unsigned NumExprFields = NumStmtFields + 5; /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, @@ -400,6 +400,8 @@ void ASTStmtReader::VisitExpr(Expr *E) { E->setType(Reader.GetType(Record[Idx++])); E->setTypeDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]); + E->setValueKind(static_cast(Record[Idx++])); + E->setObjectKind(static_cast(Record[Idx++])); assert(Idx == NumExprFields && "Incorrect expression field count"); } @@ -625,7 +627,6 @@ void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) { void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - E->setValueKind(static_cast(Record[Idx++])); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { @@ -1284,7 +1285,6 @@ void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); - E->setValueKind(static_cast(Record[Idx++])); } Stmt *ASTReader::ReadStmt(PerFileData &F) { @@ -1523,6 +1523,8 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS); QualType T = GetType(Record[Idx++]); + ExprValueKind VK = static_cast(Record[Idx++]); + ExprObjectKind OK = static_cast(Record[Idx++]); Expr *Base = ReadSubExpr(); ValueDecl *MemberD = cast(GetDecl(Record[Idx++])); SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx); @@ -1531,7 +1533,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange, MemberD, FoundDecl, MemberNameInfo, - NumTemplateArgs ? &ArgInfo : 0, T); + NumTemplateArgs ? &ArgInfo : 0, T, VK, OK); ReadDeclarationNameLoc(F, cast(S)->MemberDNLoc, MemberD->getDeclName(), Record, Idx); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index efbfd944017a..495c3d05ffe0 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -360,6 +360,8 @@ void ASTStmtWriter::VisitExpr(Expr *E) { Writer.AddTypeRef(E->getType(), Record); Record.push_back(E->isTypeDependent()); Record.push_back(E->isValueDependent()); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); } void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) { @@ -555,6 +557,8 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Record.push_back(FoundDecl.getAccess()); Writer.AddTypeRef(E->getType(), Record); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); Writer.AddStmt(E->getBase()); Writer.AddDeclRef(E->getMemberDecl(), Record); Writer.AddSourceLocation(E->getMemberLoc(), Record); @@ -612,7 +616,6 @@ void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) { void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - Record.push_back(E->getValueKind()); Code = serialization::EXPR_IMPLICIT_CAST; } @@ -1297,7 +1300,6 @@ void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); - Record.push_back(E->getValueKind()); Code = serialization::EXPR_OPAQUE_VALUE; } diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp index 5ab1ecd29560..08d963951c1d 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -7,7 +7,7 @@ void example0() { // CHECK-NEXT: DeclRefExpr double &rd = d; // CHECK: const double &rcd = - // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue const double &rcd = d; } @@ -17,11 +17,11 @@ struct B : A { } b; // CHECK: example1 void example1() { // CHECK: A &ra = - // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue A &ra = b; // CHECK: const A &rca = - // CHECK: ImplicitCastExpr{{.*}}'const struct A' - // CHECK: ImplicitCastExpr{{.*}}'struct A' + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue const A& rca = b; } @@ -48,6 +48,6 @@ void example2() { // CHECK: example3 void example3() { // CHECK: const double &rcd2 = - // CHECK: ImplicitCastExpr{{.*}} + // CHECK: ImplicitCastExpr{{.*}} const double& rcd2 = 2; }