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<ExprValueKind>(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) {
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<ReferenceType>())
+ return isa<LValueReferenceType>(RT) ? VK_LValue : VK_XValue;
+ return VK_RValue;
+ }
+
+ /// getValueKind - The value kind that this expression produces.
+ ExprValueKind getValueKind() const {
+ return static_cast<ExprValueKind>(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<ExprObjectKind>(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;
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)
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();
}
SourceRange QualifierRange,
ValueDecl *D,
SourceLocation NameLoc,
- QualType T,
+ QualType T, ExprValueKind VK,
const TemplateArgumentListInfo *TemplateArgs = 0);
static DeclRefExpr *Create(ASTContext &Context,
SourceRange QualifierRange,
ValueDecl *D,
const DeclarationNameInfo &NameInfo,
- QualType T,
+ QualType T, ExprValueKind VK,
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
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)
// 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);
}
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.
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);
}
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)
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
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) {}
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) {}
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()),
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()),
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) {
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);
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),
// (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),
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<Expr>(Base); }
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) {}
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(),
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.
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,
return getSubExpr()->getSourceRange();
}
- using Expr::getValueKind;
- using Expr::setValueKind;
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
}
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)
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.
: 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);
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) {
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) {
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() &&
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!
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.
/// 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;
// 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.
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.
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];
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;
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) { }
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) { }
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)
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.
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.
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) {}
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();
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) { }
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) { }
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) { }
/// This expression node represents a C++ static cast, e.g.,
/// @c static_cast<int>(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)
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,
/// This expression node represents a dynamic cast, e.g.,
/// @c dynamic_cast<Derived*>(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)
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);
/// This expression node represents a reinterpret cast, e.g.,
/// @c reinterpret_cast<int>(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);
/// This expression node represents a const cast, e.g.,
/// @c const_cast<char*>(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);
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) { }
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) { }
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
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
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) { }
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()),
// 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<Expr>(Op); }
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<Expr **>(this + 1) = SubExpr;
}
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:
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)
public:
static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
+ ExprValueKind VK,
TypeSourceInfo *Written,
SourceLocation TyBeginLoc,
CastKind Kind, Expr *Op,
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)
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)
false, 0, false,
false, 0, 0,
FunctionType::ExtInfo())),
+ VK_RValue, OK_Ordinary,
/*isTypeDependent=*/(Base->isTypeDependent() ||
(DestroyedType.getTypeSourceInfo() &&
DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
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)
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)
{}
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)
{}
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),
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)
{ }
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) {}
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) {}
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) {}
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) {}
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) {}
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()) {
}
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)
: 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,
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,
///
/// \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.
/// \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,
///
/// \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
///
/// \param RBracLoc The location of the closing square bracket ']'.
static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ ExprValueKind VK,
SourceLocation LBracLoc,
TypeSourceInfo *Receiver,
Selector Sel,
///
/// \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
///
/// \param RBracLoc The location of the closing square bracket ']'.
static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ ExprValueKind VK,
SourceLocation LBracLoc,
Expr *Receiver,
Selector Sel,
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.
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;
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 {
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,
/// 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);
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);
/// 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.
/// 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.
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
Importer.Import(E->getQualifierRange()),
ToD,
Importer.Import(E->getLocation()),
- T,
+ T, E->getValueKind(),
/*FIXME:TemplateArgs=*/0);
}
return 0;
return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
- T,
+ T, E->getValueKind(),
+ E->getObjectKind(),
Importer.Import(E->getOperatorLoc()));
}
return 0;
return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
- T,
+ T, E->getValueKind(),
+ E->getObjectKind(),
Importer.Import(E->getOperatorLoc()));
}
return new (Importer.getToContext())
CompoundAssignOperator(LHS, RHS, E->getOpcode(),
- T, CompLHSType, CompResultType,
+ T, E->getValueKind(),
+ E->getObjectKind(),
+ CompLHSType, CompResultType,
Importer.Import(E->getOperatorLoc()));
}
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()));
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Expr *E = new (Context) DeclRefExpr(NTTP,
NTTP->getType().getNonLValueExprType(Context),
+ Expr::getValueKindForType(NTTP->getType()),
NTTP->getLocation());
TemplateArgs.push_back(TemplateArgument(E));
} else {
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)),
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)),
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,
ValueDecl *D,
const DeclarationNameInfo &NameInfo,
QualType T,
+ ExprValueKind VK,
const TemplateArgumentListInfo *TemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (Qualifier != 0)
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo,
- TemplateArgs, T);
+ TemplateArgs, T, VK);
}
DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier,
//===----------------------------------------------------------------------===//
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) {
}
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) {
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)),
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 ||
Size += ExplicitTemplateArgumentList::sizeFor(*targs);
void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
- 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()) {
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) {
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;
}
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)
}
ObjCMessageExpr::ObjCMessageExpr(QualType T,
+ ExprValueKind VK,
SourceLocation LBracLoc,
SourceLocation SuperLoc,
bool IsInstanceSuper,
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<uintptr_t>(Method? Method
}
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),
}
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),
}
ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+ ExprValueKind VK,
SourceLocation LBracLoc,
SourceLocation SuperLoc,
bool IsInstanceSuper,
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
NumArgs * sizeof(Expr *);
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::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,
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
NumArgs * sizeof(Expr *);
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::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,
unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
NumArgs * sizeof(Expr *);
void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
- return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args,
+ return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args,
NumArgs, RBracLoc);
}
unsigned NumIndexExprs,
Expr *Init)
: Expr(DesignatedInitExprClass, Ty,
+ Init->getValueKind(), Init->getObjectKind(),
Init->isTypeDependent(), Init->isValueDependent()),
EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
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) {
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),
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)
{
}
CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
+ ExprValueKind VK,
CastKind K, Expr *Op,
const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy,
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;
}
}
CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
+ ExprValueKind VK,
CastKind K, Expr *Op,
const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy,
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;
}
}
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;
}
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) {
}
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) {
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;
}
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenRange)
-: Expr(SC, T,
+: Expr(SC, T, VK_RValue, OK_Ordinary,
T->isDependentType(),
(T->isDependentType() ||
CallExpr::hasAnyValueDependentArguments(args, numargs))),
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);
SourceLocation RParenLoc)
: Expr(CXXUnresolvedConstructExprClass,
Type->getType().getNonReferenceType(),
+ VK_RValue, OK_Ordinary,
Type->getType()->isDependentType(), true),
Type(Type),
LParenLoc(LParenLoc),
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),
}
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");
<< " " << (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);
// 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);
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);
if (Info.NeedsObjCSelf) {
ValueDecl *Self = cast<ObjCMethodDecl>(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);
if (BDRE->getCopyConstructorExpr()) {
E = BDRE->getCopyConstructorExpr();
PushDestructorCleanup(E->getType(), Addr);
- }
- else {
- E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
- VD->getType().getNonReferenceType(),
- SourceLocation());
- if (VD->getType()->isReferenceType()) {
- E = new (getContext())
- UnaryOperator(const_cast<Expr*>(E), UO_AddrOf,
- getContext().getPointerType(E->getType()),
- SourceLocation());
- }
+ } else {
+ E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
+ VD->getType().getNonReferenceType(),
+ Expr::getValueKindForType(VD->getType()),
+ SourceLocation());
+ if (VD->getType()->isReferenceType()) {
+ E = new (getContext())
+ UnaryOperator(const_cast<Expr*>(E), UO_AddrOf,
+ getContext().getPointerType(E->getType()),
+ VK_RValue, OK_Ordinary, SourceLocation());
}
}
}
+ }
if (BDRE->isByRef()) {
E = new (getContext())
UnaryOperator(const_cast<Expr*>(E), UO_AddrOf,
getContext().getPointerType(E->getType()),
- SourceLocation());
+ VK_RValue, OK_Ordinary, SourceLocation());
}
RValue r = EmitAnyExpr(E, AggValueSlot::forAddr(Addr, false, true));
0, QualType(PadTy), 0,
SC_None, SC_None);
Expr *E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
- SourceLocation());
+ VK_LValue, SourceLocation());
BlockLayout.push_back(E);
}
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
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);
}
}
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());
}
}
if (Super)
MsgExpr = ObjCMessageExpr::Create(*Context,
Ty.getNonReferenceType(),
+ Expr::getValueKindForType(Ty),
/*FIXME?*/SourceLocation(),
SuperLocation,
/*IsInstanceSuper=*/true,
MsgExpr = ObjCMessageExpr::Create(*Context,
Ty.getNonReferenceType(),
+ Expr::getValueKindForType(Ty),
/*FIXME: */SourceLocation(),
cast<Expr>(Receiver),
Sel, OMD,
if (Super)
MsgExpr = ObjCMessageExpr::Create(*Context,
Ty.getNonReferenceType(),
+ Expr::getValueKindForType(Ty),
/*FIXME?*/SourceLocation(),
SuperLocation,
/*IsInstanceSuper=*/true,
Receiver = PropGetters[Exp];
MsgExpr = ObjCMessageExpr::Create(*Context,
Ty.getNonReferenceType(),
+ Expr::getValueKindForType(Ty),
/*FIXME:*/SourceLocation(),
cast<Expr>(Receiver),
Sel, OMD,
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;
}
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);
CallExpr *Exp =
new (Context) CallExpr(*Context, ICE, args, nargs,
- FT->getCallResultType(*Context), EndLoc);
+ FT->getCallResultType(*Context),
+ VK_RValue, EndLoc);
return 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);
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"))
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
//
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);
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;
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"))
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
//
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
+ VK_RValue, OK_Ordinary,
SourceLocation());
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
- superType, ILE, false);
+ superType, VK_RValue, ILE,
+ false);
}
MsgExprs.push_back(SuperRep);
break;
// 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:
const FunctionType *FT = msgSendType->getAs<FunctionType>();
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
// 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),
FT = msgSendType->getAs<FunctionType>();
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,
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);
}
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);
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);
}
SourceLocation(), cast<Expr>(LHSStmt),
SourceLocation(), cast<Expr>(RHSStmt),
(Expr*)0,
- Exp->getType());
+ Exp->getType(), VK_RValue);
return CondExpr;
} else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
CPT = IRE->getType()->getAs<BlockPointerType>();
&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,
}
CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0],
BlkExprs.size(),
- Exp->getType(), SourceLocation());
+ Exp->getType(), VK_RValue,
+ SourceLocation());
return CE;
}
/*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(),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true);
ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
- DeclRefExp->getType());
+ DeclRefExp->getType(), VK_LValue, OK_Ordinary);
if (VarDecl *Var = dyn_cast<VarDecl>(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);
// 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<Expr*, 4> 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);
&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.
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());
}
}
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);
}
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();
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,
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));
}
}
/// 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();
QualType DestPointee;
const PointerType *DestPointer = DestType->getAs<PointerType>();
- const ReferenceType *DestReference = DestType->getAs<ReferenceType>();
+ const ReferenceType *DestReference = 0;
if (DestPointer) {
DestPointee = DestPointer->getPointeeType();
- } else if (DestReference) {
+ } else if ((DestReference = DestType->getAs<ReferenceType>())) {
DestPointee = DestReference->getPointeeType();
+ VK = isa<LValueReferenceType>(DestReference) ? VK_LValue : VK_RValue;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
<< OrigDestType << DestRange;
/// const char *str = "literal";
/// legacy_function(const_cast\<char*\>(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;
/// char *bytes = reinterpret_cast\<char*\>(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;
/// 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".
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;
}
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))
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
// 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
// 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);
}
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 =
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;
// 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!");
// Create a reference to the iteration variable; we'll use this several
// times throughout.
Expr *IterationVarRef
- = S.BuildDeclRefExpr(IterationVar, SizeType, Loc).takeAs<Expr>();
+ = S.BuildDeclRefExpr(IterationVar, SizeType, VK_RValue, Loc).take();
assert(IterationVarRef && "Reference to invented variable cannot fail!");
// Create the DeclStmt that holds the iteration variable.
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,
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();
// Construct a reference to the "other" object. We'll be using this
// throughout the generated ASTs.
- Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, Loc).takeAs<Expr>();
+ 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
CollectableMemCpyRef = BuildDeclRefExpr(CollectableMemCpy,
CollectableMemCpy->getType(),
- Loc, 0).takeAs<Expr>();
+ VK_LValue, Loc, 0).take();
assert(CollectableMemCpyRef && "Builtin reference cannot fail");
}
}
BuiltinMemCpyRef = BuildDeclRefExpr(BuiltinMemCpy,
BuiltinMemCpy->getType(),
- Loc, 0).takeAs<Expr>();
+ VK_LValue, Loc, 0).take();
assert(BuiltinMemCpyRef && "Builtin reference cannot fail");
}
// 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);
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) {
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
// 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) {
for (llvm::SmallVector<FieldDecl *, 4>::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.
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;
}
if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
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);
}
}
DeclAccessPair FoundDecl,
const DeclarationNameInfo &MemberNameInfo,
QualType Ty,
+ ExprValueKind VK, ExprObjectKind OK,
const TemplateArgumentListInfo *TemplateArgs = 0) {
NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange;
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
return Owned(ULE);
}
+static ExprValueKind getValueKindForDecl(ASTContext &Context,
+ const ValueDecl *D) {
+ if (isa<VarDecl>(D) || isa<FieldDecl>(D)) return VK_LValue;
+ if (!Context.getLangOptions().CPlusPlus) return VK_RValue;
+ if (isa<FunctionDecl>(D)) {
+ if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(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
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
MarkDeclarationReferenced(Loc, VD);
QualType ExprTy = VD->getType().getNonReferenceType();
+
// The BlocksAttr indicates the variable is bound by-reference.
bool byrefVar = (VD->getAttr<BlocksAttr>() != 0);
QualType T = VD->getType();
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<ValueDecl*>(BDRE->getDecl()), T,
- SourceLocation());
+ VK, SourceLocation());
if (T->getAs<RecordType>())
if (!T->isUnionType()) {
ExprResult Res = PerformCopyInitialization(
// 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);
}
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 &&
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
} else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) {
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();
}
return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
- ResultType, RLoc));
+ ResultType, VK, OK, RLoc));
}
QualType Sema::
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<ReferenceType>())
+ if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
MemberType = Ref->getPointeeType();
- else {
+ VK = VK_LValue;
+ } else {
Qualifiers BaseQuals = BaseType.getQualifiers();
BaseQuals.removeObjCGCAttr();
if (FD->isMutable()) BaseQuals.removeConst();
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<VarDecl>(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<FunctionDecl>(MemberDecl)) {
+ if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(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<FunctionDecl>(MemberDecl) && "member function not C++ method?");
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
Enum, FoundDecl, MemberNameInfo,
- Enum->getType()));
+ Enum->getType(), VK_RValue, OK_Ordinary));
}
Owned(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)
return ExprError();
return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+ VK_LValue, OK_ObjCProperty,
MemberLoc,
BaseExpr));
}
SMD = dyn_cast<ObjCMethodDecl>(SDecl);
QualType PType = OMD->getSendResultType();
return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(OMD, PType,
+ VK_LValue,
+ OK_ObjCProperty,
SMD,
MemberLoc,
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));
}
}
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,
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())
if (const FunctionProtoType *FPT
= BO->getType()->getAs<FunctionProtoType>()) {
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(),
CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
Args, NumArgs,
Context.BoolTy,
+ VK_RValue,
RParenLoc);
const FunctionType *FuncT;
// 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<FunctionProtoType>(FuncT)) {
if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs,
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
}
/// 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
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));
}
/// 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()) &&
// 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) {
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
// 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
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".
// 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:
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);
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
Expr *Input) {
UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(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,
case UO_Deref:
DefaultFunctionArrayLvalueConversion(Input);
resultType = CheckIndirectionOperand(Input, OpLoc);
+ VK = VK_LValue;
break;
case UO_Plus:
case UO_Minus:
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,
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()) {
<< 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));
}
}
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
//
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();
return Owned(CXXFunctionalCastExpr::Create(Context,
Ty.getNonLValueExprType(Context),
- TInfo, TyBeginLoc, Kind,
+ VK, TInfo, TyBeginLoc, Kind,
Exprs[0], &BasePath,
RParenLoc));
}
/// \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:
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();
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
QualType LType = lex->getType();
if (isIndirect) {
if (const PointerType *Ptr = LType->getAs<PointerType>())
- LType = Ptr->getPointeeType().getNonReferenceType();
+ LType = Ptr->getPointeeType();
else {
Diag(Loc, diag::err_bad_memptr_lhs)
<< OpSpelling << 1 << LType
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.
// 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;
}
/// 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.
return QualType();
}
+ // Assume r-value.
+ VK = VK_RValue;
+
// Either of the arguments dependent?
if (LHS->isTypeDependent() || RHS->isTypeDependent())
return Context.DependentTy;
}
// 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<ObjCPropertyRefExpr>(LHS) ||
- isa<ObjCImplicitSetterGetterRefExpr>(LHS));
- bool rhsProperty = (isa<ObjCPropertyRefExpr>(RHS) ||
- isa<ObjCImplicitSetterGetterRefExpr>(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
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;
}
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++) {
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
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;
}
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.
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));
}
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));
}
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)
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(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));
}
// Check the argument types and determine the result type.
QualType ReturnType;
+ ExprValueKind VK = VK_RValue;
+
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(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);
Expr **Args = reinterpret_cast<Expr **>(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));
}
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(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()) {
// 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);
}
// 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);
// 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<Expr>());
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);
// 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,
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,
return Owned(new (Context) UnaryOperator(Input,
Opc,
Context.DependentTy,
+ VK_RValue, OK_Ordinary,
OpLoc));
CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
&Args[0], NumArgs,
Context.DependentTy,
+ VK_RValue,
OpLoc));
}
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))
// 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));
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
Args, 2,
Context.DependentTy,
+ VK_RValue,
OpLoc));
}
DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
- // Determine the result type
- QualType ResultTy
- = FnDecl->getType()->getAs<FunctionType>()
- ->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))
return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
Args, 2,
Context.DependentTy,
+ VK_RValue,
RLoc));
}
Args[1] = InputInit.takeAs<Expr>();
// Determine the result type
- QualType ResultTy
- = FnDecl->getType()->getAs<FunctionType>()
- ->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))
MemExpr = cast<MemberExpr>(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(),
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,
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))
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(),
return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
Context.getPointerType(SubExpr->getType()),
+ VK_RValue, OK_Ordinary,
UnOp->getOperatorLoc());
}
Fn,
ULE->getNameLoc(),
Fn->getType(),
+ VK_LValue,
TemplateArgs);
}
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<CXXMethodDecl>(Fn)->isStatic()) {
return DeclRefExpr::Create(Context,
Fn,
MemExpr->getMemberLoc(),
Fn->getType(),
+ VK_LValue,
TemplateArgs);
} else {
SourceLocation Loc = MemExpr->getMemberLoc();
Found,
MemExpr->getMemberNameInfo(),
TemplateArgs,
- Fn->getType());
+ Fn->getType(),
+ cast<CXXMethodDecl>(Fn)->isStatic()
+ ? VK_LValue : VK_RValue,
+ OK_Ordinary);
}
llvm_unreachable("Invalid reference to overloaded function");
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();
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();
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<ReferenceType>())
- T = Context.getQualifiedType(T, TargetRef->getPointeeType().getQualifiers());
+ if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>()) {
+ 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
/// 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<FieldDecl>(Member)->getType());
+ cast<FieldDecl>(Member)->getType(),
+ VK, OK_Ordinary);
return getSema().Owned(ME);
}
// 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.
/// 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");
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Expr *Callee
= new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
- BuiltinLoc);
+ VK_LValue, BuiltinLoc);
SemaRef.UsualUnaryConversions(Callee);
// Build the CallExpr
CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
Subs, NumSubExprs,
Builtin->getCallResultType(),
+ Expr::getValueKindForType(Builtin->getResultType()),
RParenLoc);
ExprResult OwnedCall(SemaRef.Owned(TheCall));
/// \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,
E->setType(Reader.GetType(Record[Idx++]));
E->setTypeDependent(Record[Idx++]);
E->setValueDependent(Record[Idx++]);
+ E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
+ E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++]));
assert(Idx == NumExprFields && "Incorrect expression field count");
}
void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
}
void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
- E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
}
Stmt *ASTReader::ReadStmt(PerFileData &F) {
DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
QualType T = GetType(Record[Idx++]);
+ ExprValueKind VK = static_cast<ExprValueKind>(Record[Idx++]);
+ ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]);
Expr *Base = ReadSubExpr();
ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++]));
SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx);
S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange,
MemberD, FoundDecl, MemberNameInfo,
- NumTemplateArgs ? &ArgInfo : 0, T);
+ NumTemplateArgs ? &ArgInfo : 0, T, VK, OK);
ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
MemberD->getDeclName(), Record, Idx);
break;
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) {
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);
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- Record.push_back(E->getValueKind());
Code = serialization::EXPR_IMPLICIT_CAST;
}
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
- Record.push_back(E->getValueKind());
Code = serialization::EXPR_OPAQUE_VALUE;
}
// CHECK-NEXT: DeclRefExpr
double &rd = d;
// CHECK: const double &rcd =
- // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' <NoOp>
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp>
const double &rcd = d;
}
// CHECK: example1
void example1() {
// CHECK: A &ra =
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> lvalue
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
A &ra = b;
// CHECK: const A &rca =
- // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
const A& rca = b;
}
// CHECK: example3
void example3() {
// CHECK: const double &rcd2 =
- // CHECK: ImplicitCastExpr{{.*}}<IntegralToFloating>
+ // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
const double& rcd2 = 2;
}