[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