[cfe-commits] r108807 - in /cfe/trunk: include/clang/AST/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Rewrite/ lib/Sema/
Sebastian Redl
sebastian.redl at getdesigned.at
Mon Jul 19 21:20:21 PDT 2010
Author: cornedbee
Date: Mon Jul 19 23:20:21 2010
New Revision: 108807
URL: http://llvm.org/viewvc/llvm-project?rev=108807&view=rev
Log:
Update ImplicitCastExpr to be able to represent an XValue.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprClassification.cpp
cfe/trunk/lib/AST/StmtDumper.cpp
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
cfe/trunk/lib/Rewrite/RewriteObjC.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaInit.h
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Jul 19 23:20:21 2010
@@ -258,7 +258,6 @@
/// function returning an rvalue reference.
/// lvalues and xvalues are collectively referred to as glvalues, while
/// prvalues and xvalues together form rvalues.
- /// If a
Classification Classify(ASTContext &Ctx) const {
return ClassifyImpl(Ctx, 0);
}
@@ -2045,24 +2044,33 @@
///
/// In C, implicit casts always produce rvalues. However, in C++, an
/// implicit cast whose result is being bound to a reference will be
-/// an lvalue. For example:
+/// an lvalue or xvalue. For example:
///
/// @code
/// class Base { };
/// class Derived : public Base { };
+/// Derived &&ref();
/// void f(Derived d) {
-/// Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base
+/// Base& b = d; // initializer is an ImplicitCastExpr
+/// // to an lvalue of type Base
+/// Base&& r = ref(); // initializer is an ImplicitCastExpr
+/// // to an xvalue of type Base
/// }
/// @endcode
class ImplicitCastExpr : public CastExpr {
- /// LvalueCast - Whether this cast produces an lvalue.
- bool LvalueCast;
+public:
+ enum ResultCategory {
+ RValue, LValue, XValue
+ };
+
+private:
+ /// Category - The category this cast produces.
+ ResultCategory Category;
public:
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
- CXXBaseSpecifierArray BasePath, bool Lvalue)
- : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath),
- LvalueCast(Lvalue) { }
+ CXXBaseSpecifierArray BasePath, ResultCategory Cat)
+ : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath), Category(Cat) { }
/// \brief Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell)
@@ -2072,11 +2080,11 @@
return getSubExpr()->getSourceRange();
}
- /// isLvalueCast - Whether this cast produces an lvalue.
- bool isLvalueCast() const { return LvalueCast; }
+ /// getCategory - The value category this cast produces.
+ ResultCategory getCategory() const { return Category; }
- /// setLvalueCast - Set whether this cast produces an lvalue.
- void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; }
+ /// setCategory - Set the value category this cast produces.
+ void setCategory(ResultCategory Cat) { Category = Cat; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
@@ -2098,8 +2106,8 @@
/// actual type of the expression as determined by semantic
/// analysis. These types may differ slightly. For example, in C++ one
/// can cast to a reference type, which indicates that the resulting
-/// expression will be an lvalue. The reference type, however, will
-/// not be used as the type of the expression.
+/// expression will be an lvalue or xvalue. The reference type, however,
+/// will not be used as the type of the expression.
class ExplicitCastExpr : public CastExpr {
/// TInfo - Source type info for the (written) type
/// this expression is casting to.
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jul 19 23:20:21 2010
@@ -2900,7 +2900,7 @@
CXXBaseSpecifierArray BasePath;
return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
SubExpr, BasePath,
- E->isLvalueCast());
+ E->getCategory());
}
Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Jul 19 23:20:21 2010
@@ -1508,7 +1508,8 @@
Expr *E = this->IgnoreParens();
while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+ if (ICE->getCategory() != ImplicitCastExpr::RValue &&
+ ICE->getCastKind() == CastExpr::CK_NoOp)
E = ICE->getSubExpr()->IgnoreParens();
else
break;
@@ -1530,7 +1531,8 @@
const Expr *E = this->IgnoreParens();
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+ if (ICE->getCategory() != ImplicitCastExpr::RValue &&
+ ICE->getCastKind() == CastExpr::CK_NoOp)
E = ICE->getSubExpr()->IgnoreParens();
else
break;
Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Mon Jul 19 23:20:21 2010
@@ -134,10 +134,16 @@
// Implicit casts are lvalues if they're lvalue casts. Other than that, we
// only specifically record class temporaries.
case Expr::ImplicitCastExprClass:
- if (cast<ImplicitCastExpr>(E)->isLvalueCast())
+ switch (cast<ImplicitCastExpr>(E)->getCategory()) {
+ case ImplicitCastExpr::RValue:
+ return Lang.CPlusPlus && E->getType()->isRecordType() ?
+ Cl::CL_ClassTemporary : Cl::CL_PRValue;
+ case ImplicitCastExpr::LValue:
return Cl::CL_LValue;
- return Lang.CPlusPlus && E->getType()->isRecordType() ?
- Cl::CL_ClassTemporary : Cl::CL_PRValue;
+ case ImplicitCastExpr::XValue:
+ return Cl::CL_XValue;
+ }
+ llvm_unreachable("Invalid value category of implicit cast.");
// C++ [expr.prim.general]p4: The presence of parentheses does not affect
// whether the expression is an lvalue.
Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Mon Jul 19 23:20:21 2010
@@ -340,8 +340,16 @@
void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
VisitCastExpr(Node);
- if (Node->isLvalueCast())
+ switch (Node->getCategory()) {
+ case ImplicitCastExpr::LValue:
OS << " lvalue";
+ break;
+ case ImplicitCastExpr::XValue:
+ OS << " xvalue";
+ break;
+ default:
+ break;
+ }
}
void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jul 19 23:20:21 2010
@@ -325,7 +325,7 @@
void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
VisitCastExpr(S);
- ID.AddBoolean(S->isLvalueCast());
+ ID.AddInteger(S->getCategory());
}
void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Jul 19 23:20:21 2010
@@ -897,8 +897,8 @@
}
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
- // And that lvalue casts are never null.
- if (ICE->isLvalueCast())
+ // And that glvalue casts are never null.
+ if (ICE->getCategory() != ImplicitCastExpr::RValue)
return false;
}
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Jul 19 23:20:21 2010
@@ -404,7 +404,8 @@
if (getContext().getCanonicalType(Ivar->getType()) !=
getContext().getCanonicalType(ArgDecl->getType())) {
ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg,
- CXXBaseSpecifierArray(), false);
+ CXXBaseSpecifierArray(),
+ ImplicitCastExpr::RValue);
BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign,
Ivar->getType(), Loc);
EmitStmt(&Assign);
Modified: cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderStmt.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderStmt.cpp Mon Jul 19 23:20:21 2010
@@ -588,7 +588,7 @@
void PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- E->setLvalueCast(Record[Idx++]);
+ E->setCategory(static_cast<ImplicitCastExpr::ResultCategory>(Record[Idx++]));
}
void PCHStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
Modified: cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterStmt.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterStmt.cpp Mon Jul 19 23:20:21 2010
@@ -602,7 +602,7 @@
void PCHStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- Record.push_back(E->isLvalueCast());
+ Record.push_back(E->getCategory());
Code = pch::EXPR_IMPLICIT_CAST;
}
Modified: cfe/trunk/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteObjC.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteObjC.cpp Mon Jul 19 23:20:21 2010
@@ -2108,7 +2108,7 @@
ImplicitCastExpr *ICE =
new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown,
DRE, CXXBaseSpecifierArray(),
- /*isLvalue=*/false);
+ ImplicitCastExpr::RValue);
const FunctionType *FT = msgSendType->getAs<FunctionType>();
@@ -5609,7 +5609,9 @@
}
#if 0
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
- CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
+ CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
+ ICE->getSubExpr(),
+ SourceLocation());
// Get the new text.
std::string SStr;
llvm::raw_string_ostream Buf(SStr);
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Jul 19 23:20:21 2010
@@ -152,10 +152,11 @@
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
-/// If isLvalue, the result of the cast is an lvalue.
+/// The result is of the given category.
void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
CastExpr::CastKind Kind,
- bool isLvalue, CXXBaseSpecifierArray BasePath) {
+ ImplicitCastExpr::ResultCategory Category,
+ CXXBaseSpecifierArray BasePath) {
QualType ExprTy = Context.getCanonicalType(Expr->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
@@ -186,12 +187,21 @@
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
ImpCast->setType(Ty);
- ImpCast->setLvalueCast(isLvalue);
+ ImpCast->setCategory(Category);
return;
}
}
- Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, isLvalue);
+ Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, Category);
+}
+
+ImplicitCastExpr::ResultCategory Sema::CastCategory(Expr *E) {
+ Expr::Classification Classification = E->Classify(Context);
+ return Classification.isRValue() ?
+ ImplicitCastExpr::RValue :
+ (Classification.isLValue() ?
+ ImplicitCastExpr::LValue :
+ ImplicitCastExpr::XValue);
}
void Sema::DeleteExpr(ExprTy *E) {
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jul 19 23:20:21 2010
@@ -4153,11 +4153,16 @@
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
+ /// CastCategory - Get the correct forwarded implicit cast result category
+ /// from the inner expression.
+ ImplicitCastExpr::ResultCategory CastCategory(Expr *E);
+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// cast. If there is already an implicit cast, merge into the existing one.
/// If isLvalue, the result of the cast is an lvalue.
void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind,
- bool isLvalue = false,
+ ImplicitCastExpr::ResultCategory Category =
+ ImplicitCastExpr::RValue,
CXXBaseSpecifierArray BasePath =
CXXBaseSpecifierArray());
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jul 19 23:20:21 2010
@@ -6782,7 +6782,7 @@
CastExpr::CK_IntegralCast,
ECD->getInitExpr(),
CXXBaseSpecifierArray(),
- /*isLvalue=*/false));
+ ImplicitCastExpr::RValue));
if (getLangOptions().CPlusPlus)
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jul 19 23:20:21 2010
@@ -1536,9 +1536,9 @@
QualType ArgTy =
SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(),
ParamType.getQualifiers());
- SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
+ SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/true,
+ ImplicitCastExpr::LValue,
CXXBaseSpecifierArray(BaseSpec));
InitializationKind InitKind
@@ -4858,8 +4858,8 @@
// appropriately-qualified base type.
Expr *From = OtherRef->Retain();
ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
- CastExpr::CK_UncheckedDerivedToBase, /*isLvalue=*/true,
- CXXBaseSpecifierArray(Base));
+ CastExpr::CK_UncheckedDerivedToBase,
+ ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base));
// Dereference "this".
OwningExprResult To = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
@@ -4871,7 +4871,7 @@
Context.getCVRQualifiedType(BaseType,
CopyAssignOperator->getTypeQualifiers()),
CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/true, CXXBaseSpecifierArray(Base));
+ ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base));
To = Owned(ToE);
// Build the copy.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul 19 23:20:21 2010
@@ -1441,9 +1441,8 @@
SourceRange FromRange = From->getSourceRange();
SourceLocation FromLoc = FromRange.getBegin();
- bool isLvalue
- = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions;
-
+ ImplicitCastExpr::ResultCategory Category = CastCategory(From);
+
// C++ [class.member.lookup]p8:
// [...] Ambiguities can often be resolved by qualifying a name with its
// class name.
@@ -1481,7 +1480,7 @@
if (PointerConversions)
QType = Context.getPointerType(QType);
ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ Category, BasePath);
FromType = QType;
FromRecordType = QRecordType;
@@ -1518,7 +1517,7 @@
if (PointerConversions)
UType = Context.getPointerType(UType);
ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ Category, BasePath);
FromType = UType;
FromRecordType = URecordType;
}
@@ -1535,7 +1534,7 @@
return true;
ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ Category, BasePath);
return false;
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jul 19 23:20:21 2010
@@ -296,10 +296,10 @@
return ExprError();
// C++ [expr.typeid]p3:
- // When typeid is applied to an expression other than an lvalue of a
+ // When typeid is applied to an expression other than an glvalue of a
// polymorphic class type [...] [the] expression is an unevaluated
// operand. [...]
- if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) {
+ if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) {
isUnevaluatedOperand = false;
// We require a vtable to query the type at run time.
@@ -316,7 +316,7 @@
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
if (!Context.hasSameType(T, UnqualT)) {
T = UnqualT;
- ImpCastExprToType(E, UnqualT, CastExpr::CK_NoOp, E->isLvalue(Context));
+ ImpCastExprToType(E, UnqualT, CastExpr::CK_NoOp, CastCategory(E));
Operand.release();
Operand = Owned(E);
}
@@ -401,7 +401,7 @@
// or "pointer to function returning T", [...]
if (E->getType().hasQualifiers())
ImpCastExprToType(E, E->getType().getUnqualifiedType(), CastExpr::CK_NoOp,
- E->isLvalue(Context) == Expr::LV_Valid);
+ CastCategory(E));
DefaultFunctionArrayConversion(E);
@@ -1809,7 +1809,7 @@
CXXBaseSpecifierArray BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath);
break;
}
@@ -1821,7 +1821,7 @@
return true;
if (CheckExceptionSpecCompatibility(From, ToType))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath);
break;
}
case ICK_Boolean_Conversion: {
@@ -1843,11 +1843,8 @@
IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType.getNonReferenceType(),
- CastExpr::CK_DerivedToBase,
- /*isLvalue=*/(From->getType()->isRecordType() &&
- From->isLvalue(Context) == Expr::LV_Valid),
- BasePath);
+ ImpCastExprToType(From, ToType.getNonReferenceType(),
+ CastExpr::CK_DerivedToBase, CastCategory(From), BasePath);
break;
}
@@ -1877,18 +1874,21 @@
// Nothing to do.
break;
- case ICK_Qualification:
- // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
- // references.
+ case ICK_Qualification: {
+ // The qualification keeps the category of the inner expression, unless the
+ // target type isn't a reference.
+ ImplicitCastExpr::ResultCategory Category = ToType->isReferenceType() ?
+ CastCategory(From) : ImplicitCastExpr::RValue;
ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
- CastExpr::CK_NoOp, ToType->isLValueReferenceType());
+ CastExpr::CK_NoOp, Category);
if (SCS.DeprecatedStringLiteralToCharPtr)
Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
<< ToType.getNonReferenceType();
break;
-
+ }
+
default:
assert(false && "Improper third standard conversion");
break;
@@ -1974,11 +1974,12 @@
}
// Cast LHS to type of use.
QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
- bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
-
+ ImplicitCastExpr::ResultCategory Category =
+ isIndirect ? ImplicitCastExpr::RValue : CastCategory(lex);
+
CXXBaseSpecifierArray BasePath;
BuildBasePathArray(Paths, BasePath);
- ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
+ ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, Category,
BasePath);
}
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jul 19 23:20:21 2010
@@ -2021,12 +2021,14 @@
switch (Kind) {
case SK_ResolveAddressOfOverloadedFunction:
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue:
case SK_BindReference:
case SK_BindReferenceToTemporary:
case SK_ExtraneousCopyToTemporary:
case SK_UserConversion:
case SK_QualificationConversionRValue:
+ case SK_QualificationConversionXValue:
case SK_QualificationConversionLValue:
case SK_ListInitialization:
case SK_ConstructorInitialization:
@@ -2091,9 +2093,14 @@
}
void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType,
- bool IsLValue) {
+ ImplicitCastExpr::ResultCategory Category) {
Step S;
- S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+ switch (Category) {
+ case ImplicitCastExpr::RValue: S.Kind = SK_CastDerivedToBaseRValue; break;
+ case ImplicitCastExpr::XValue: S.Kind = SK_CastDerivedToBaseXValue; break;
+ case ImplicitCastExpr::LValue: S.Kind = SK_CastDerivedToBaseLValue; break;
+ default: llvm_unreachable("No such category");
+ }
S.Type = BaseType;
Steps.push_back(S);
}
@@ -2125,10 +2132,20 @@
}
void InitializationSequence::AddQualificationConversionStep(QualType Ty,
- bool IsLValue) {
+ ImplicitCastExpr::ResultCategory Category) {
Step S;
- S.Kind = IsLValue? SK_QualificationConversionLValue
- : SK_QualificationConversionRValue;
+ switch (Category) {
+ case ImplicitCastExpr::RValue:
+ S.Kind = SK_QualificationConversionRValue;
+ break;
+ case ImplicitCastExpr::XValue:
+ S.Kind = SK_QualificationConversionXValue;
+ break;
+ case ImplicitCastExpr::LValue:
+ S.Kind = SK_QualificationConversionLValue;
+ break;
+ default: llvm_unreachable("No such category");
+ }
S.Type = Ty;
Steps.push_back(S);
}
@@ -2375,6 +2392,13 @@
// Determine whether we need to perform derived-to-base or
// cv-qualification adjustments.
+ ImplicitCastExpr::ResultCategory Category = ImplicitCastExpr::RValue;
+ if (T2->isLValueReferenceType())
+ Category = ImplicitCastExpr::LValue;
+ else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>())
+ Category = RRef->getPointeeType()->isFunctionType() ?
+ ImplicitCastExpr::LValue : ImplicitCastExpr::RValue;
+
bool NewDerivedToBase = false;
Sema::ReferenceCompareResult NewRefRelationship
= S.CompareReferenceRelationship(DeclLoc, T1,
@@ -2394,10 +2418,10 @@
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1,
T2.getNonReferenceType().getQualifiers()),
- /*isLValue=*/true);
+ Category);
if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
- Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+ Sequence.AddQualificationConversionStep(cv1T1, Category);
Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
return OR_Success;
@@ -2472,9 +2496,9 @@
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1, T2Quals),
- /*isLValue=*/true);
+ ImplicitCastExpr::LValue);
if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+ Sequence.AddQualificationConversionStep(cv1T1,ImplicitCastExpr::LValue);
bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
(Initializer->getBitField() || Initializer->refersToVectorElement());
Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
@@ -2550,9 +2574,9 @@
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1, T2Quals),
- /*isLValue=*/false);
+ ImplicitCastExpr::RValue);
if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
+ Sequence.AddQualificationConversionStep(cv1T1,ImplicitCastExpr::RValue);
Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
return;
}
@@ -3505,12 +3529,14 @@
switch (Steps.front().Kind) {
case SK_ResolveAddressOfOverloadedFunction:
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue:
case SK_BindReference:
case SK_BindReferenceToTemporary:
case SK_ExtraneousCopyToTemporary:
case SK_UserConversion:
case SK_QualificationConversionLValue:
+ case SK_QualificationConversionXValue:
case SK_QualificationConversionRValue:
case SK_ConversionSequence:
case SK_ListInitialization:
@@ -3550,6 +3576,7 @@
break;
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue: {
// We have a derived-to-base cast that produces either an rvalue or an
// lvalue. Perform that cast.
@@ -3573,11 +3600,16 @@
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
+ ImplicitCastExpr::ResultCategory Category =
+ Step->Kind == SK_CastDerivedToBaseLValue ?
+ ImplicitCastExpr::LValue :
+ (Step->Kind == SK_CastDerivedToBaseXValue ?
+ ImplicitCastExpr::XValue :
+ ImplicitCastExpr::RValue);
CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
CastExpr::CK_DerivedToBase,
(Expr*)CurInit.release(),
- BasePath,
- Step->Kind == SK_CastDerivedToBaseLValue));
+ BasePath, Category));
break;
}
@@ -3711,29 +3743,36 @@
}
CurInitExpr = CurInit.takeAs<Expr>();
+ // FIXME: xvalues
CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
CastKind,
CurInitExpr,
CXXBaseSpecifierArray(),
- IsLvalue));
+ IsLvalue ? ImplicitCastExpr::LValue : ImplicitCastExpr::RValue));
if (RequiresCopy)
CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
move(CurInit), /*IsExtraneousCopy=*/false);
-
+
break;
}
-
+
case SK_QualificationConversionLValue:
- case SK_QualificationConversionRValue:
+ case SK_QualificationConversionXValue:
+ case SK_QualificationConversionRValue: {
// Perform a qualification conversion; these can never go wrong.
- S.ImpCastExprToType(CurInitExpr, Step->Type,
- CastExpr::CK_NoOp,
- Step->Kind == SK_QualificationConversionLValue);
+ ImplicitCastExpr::ResultCategory Category =
+ Step->Kind == SK_QualificationConversionLValue ?
+ ImplicitCastExpr::LValue :
+ (Step->Kind == SK_QualificationConversionXValue ?
+ ImplicitCastExpr::XValue :
+ ImplicitCastExpr::RValue);
+ S.ImpCastExprToType(CurInitExpr, Step->Type, CastExpr::CK_NoOp, Category);
CurInit.release();
CurInit = S.Owned(CurInitExpr);
break;
-
+ }
+
case SK_ConversionSequence: {
bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
@@ -4288,6 +4327,10 @@
OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
break;
+ case SK_CastDerivedToBaseXValue:
+ OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
+ break;
+
case SK_CastDerivedToBaseLValue:
OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
break;
@@ -4307,10 +4350,13 @@
case SK_UserConversion:
OS << "user-defined conversion via " << S->Function.Function;
break;
-
+
case SK_QualificationConversionRValue:
OS << "qualification conversion (rvalue)";
+ case SK_QualificationConversionXValue:
+ OS << "qualification conversion (xvalue)";
+
case SK_QualificationConversionLValue:
OS << "qualification conversion (lvalue)";
break;
Modified: cfe/trunk/lib/Sema/SemaInit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.h?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.h (original)
+++ cfe/trunk/lib/Sema/SemaInit.h Mon Jul 19 23:20:21 2010
@@ -445,6 +445,8 @@
SK_ResolveAddressOfOverloadedFunction,
/// \brief Perform a derived-to-base cast, producing an rvalue.
SK_CastDerivedToBaseRValue,
+ /// \brief Perform a derived-to-base cast, producing an xvalue.
+ SK_CastDerivedToBaseXValue,
/// \brief Perform a derived-to-base cast, producing an lvalue.
SK_CastDerivedToBaseLValue,
/// \brief Reference binding to an lvalue.
@@ -460,6 +462,8 @@
SK_UserConversion,
/// \brief Perform a qualification conversion, producing an rvalue.
SK_QualificationConversionRValue,
+ /// \brief Perform a qualification conversion, producing an xvalue.
+ SK_QualificationConversionXValue,
/// \brief Perform a qualification conversion, producing an lvalue.
SK_QualificationConversionLValue,
/// \brief Perform an implicit conversion sequence.
@@ -670,7 +674,8 @@
///
/// \param IsLValue true if the result of this cast will be treated as
/// an lvalue.
- void AddDerivedToBaseCastStep(QualType BaseType, bool IsLValue);
+ void AddDerivedToBaseCastStep(QualType BaseType,
+ ImplicitCastExpr::ResultCategory Category);
/// \brief Add a new step binding a reference to an object.
///
@@ -702,7 +707,8 @@
/// \brief Add a new step that performs a qualification conversion to the
/// given type.
- void AddQualificationConversionStep(QualType Ty, bool IsLValue);
+ void AddQualificationConversionStep(QualType Ty,
+ ImplicitCastExpr::ResultCategory Category);
/// \brief Add a new step that applies an implicit conversion sequence.
void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jul 19 23:20:21 2010
@@ -3042,7 +3042,8 @@
if (!Context.hasSameType(From->getType(), DestType))
ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
- /*isLvalue=*/!From->getType()->isPointerType());
+ From->getType()->isPointerType() ?
+ ImplicitCastExpr::RValue : ImplicitCastExpr::LValue);
return false;
}
@@ -3721,7 +3722,8 @@
From->getLocStart());
ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
CastExpr::CK_FunctionToPointerDecay,
- &ConversionRef, CXXBaseSpecifierArray(), false);
+ &ConversionRef, CXXBaseSpecifierArray(),
+ ImplicitCastExpr::RValue);
// 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
@@ -7632,7 +7634,7 @@
return new (Context) ImplicitCastExpr(ICE->getType(),
ICE->getCastKind(),
SubExpr, CXXBaseSpecifierArray(),
- ICE->isLvalueCast());
+ ICE->getCategory());
}
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=108807&r1=108806&r2=108807&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jul 19 23:20:21 2010
@@ -2909,8 +2909,7 @@
Arg, Converted);
if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType())) {
- ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
- Arg->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp, CastCategory(Arg));
} else if (!Context.hasSameUnqualifiedType(ArgType,
ParamType.getNonReferenceType())) {
// We can't perform this conversion.
@@ -2973,8 +2972,7 @@
if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
// Types match exactly: nothing more to do here.
} else if (IsQualificationConversion(ArgType, ParamType)) {
- ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
- Arg->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp, CastCategory(Arg));
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
More information about the cfe-commits
mailing list