[cfe-commits] r120084 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/ASTContext.cpp lib/AST/Expr.cpp lib/AST/ExprClassification.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaStmt.cpp lib/Sema/SemaTemplateDeduction.cpp

John McCall rjmccall at apple.com
Tue Nov 23 21:12:35 PST 2010


Author: rjmccall
Date: Tue Nov 23 23:12:34 2010
New Revision: 120084

URL: http://llvm.org/viewvc/llvm-project?rev=120084&view=rev
Log:
Switch a lot of call-sites over to using the new value-kind calculations.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprClassification.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Nov 23 23:12:34 2010
@@ -127,19 +127,25 @@
   bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
                               SourceRange &R2, ASTContext &Ctx) const;
 
-  /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
-  /// incomplete type other than void. Nonarray expressions that can be lvalues:
-  ///  - name, where name must be a variable
-  ///  - e[i]
-  ///  - (e), where e must be an lvalue
-  ///  - e.name, where e must be an lvalue
-  ///  - e->name
-  ///  - *e, the type of e cannot be a function type
-  ///  - string-constant
-  ///  - reference type [C++ [expr]]
-  ///  - b ? x : y, where x and y are lvalues of suitable types [C++]
+  /// isLValue - True if this expression is an "l-value" according to
+  /// the rules of the current language.  C and C++ give somewhat
+  /// different rules for this concept, but in general, the result of
+  /// an l-value expression identifies a specific object whereas the
+  /// result of an r-value expression is a value detached from any
+  /// specific storage.
   ///
-  enum isLvalueResult {
+  /// C++0x divides the concept of "r-value" into pure r-values
+  /// ("pr-values") and so-called expiring values ("x-values"), which
+  /// identify specific objects that can be safely cannibalized for
+  /// their resources.  This is an unfortunate abuse of terminology on
+  /// the part of the C++ committee.  In Clang, when we say "r-value",
+  /// we generally mean a pr-value.
+  bool isLValue() const { return getValueKind() == VK_LValue; }
+  bool isRValue() const { return getValueKind() == VK_RValue; }
+  bool isXValue() const { return getValueKind() == VK_XValue; }
+  bool isGLValue() const { return getValueKind() != VK_RValue; }
+
+  enum LValueClassification {
     LV_Valid,
     LV_NotObjectType,
     LV_IncompleteVoidType,
@@ -149,7 +155,8 @@
     LV_SubObjCPropertySetting,
     LV_ClassTemporary
   };
-  isLvalueResult isLvalue(ASTContext &Ctx) const;
+  /// Reasons why an expression might not be an l-value.
+  LValueClassification ClassifyLValue(ASTContext &Ctx) const;
 
   /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
   /// does not have an incomplete type, does not have a const-qualified type,

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Nov 23 23:12:34 2010
@@ -2378,7 +2378,7 @@
 
   // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
   // defined as T&, otherwise decltype(e) is defined as T.
-  if (e->isLvalue(Context) == Expr::LV_Valid)
+  if (e->isLValue())
     T = Context.getLValueReferenceType(T);
 
   return T;

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Nov 23 23:12:34 2010
@@ -1460,7 +1460,7 @@
 bool Expr::isBoundMemberFunction(ASTContext &Ctx) const {
   if (isTypeDependent())
     return false;
-  return isLvalue(Ctx) == Expr::LV_MemberFunction;
+  return ClassifyLValue(Ctx) == Expr::LV_MemberFunction;
 }
 
 static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1,

Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Tue Nov 23 23:12:34 2010
@@ -529,7 +529,7 @@
   return Cl::CM_Modifiable;
 }
 
-Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
+Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
   Classification VC = Classify(Ctx);
   switch (VC.getKind()) {
   case Cl::CL_LValue: return LV_Valid;

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Nov 23 23:12:34 2010
@@ -192,7 +192,7 @@
   }
 
   RValue RV;
-  if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) {
+  if (E->isLValue()) {
     // Emit the expression as an lvalue.
     LValue LV = CGF.EmitLValue(E);
     if (LV.isPropertyRef() || LV.isKVCRef()) {
@@ -235,8 +235,8 @@
           continue;
         }
       } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-        if (ME->getBase()->isLvalue(CGF.getContext()) != Expr::LV_Valid &&
-            ME->getBase()->getType()->isRecordType()) {
+        if (!ME->isArrow() && ME->getBase()->isRValue()) {
+          assert(ME->getBase()->getType()->isRecordType());
           if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
             E = ME->getBase();
             Adjustments.push_back(SubobjectAdjustment(Field));
@@ -1515,7 +1515,7 @@
     const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
     Base = MakeAddrLValue(Ptr, PT->getPointeeType());
     Base.getQuals().removeObjCGCAttr();
-  } else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) {
+  } else if (E->getBase()->isGLValue()) {
     // Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
     // emit the base as an lvalue.
     assert(E->getBase()->getType()->isVectorType());
@@ -1711,7 +1711,7 @@
 
 LValue 
 CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator *E) {
-  if (E->isLvalue(getContext()) == Expr::LV_Valid) {
+  if (E->isGLValue()) {
     if (int Cond = ConstantFoldsToSimpleInteger(E->getCond())) {
       Expr *Live = Cond == 1 ? E->getLHS() : E->getRHS();
       if (Live)

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Nov 23 23:12:34 2010
@@ -1474,7 +1474,7 @@
     // If it's an l-value, load through the appropriate subobject l-value.
     // Note that we have to ask E because Op might be an l-value that
     // this won't work for, e.g. an Obj-C property.
-    if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid)
+    if (E->isGLValue())
       return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
                 .getScalarVal();
 
@@ -1491,7 +1491,7 @@
     // If it's an l-value, load through the appropriate subobject l-value.
     // Note that we have to ask E because Op might be an l-value that
     // this won't work for, e.g. an Obj-C property.
-    if (Op->isLvalue(CGF.getContext()) == Expr::LV_Valid)
+    if (Op->isGLValue())
       return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
                 .getScalarVal();
 
@@ -2548,7 +2548,7 @@
   const llvm::Type *ClassPtrTy = ConvertType(E->getType());
 
   Expr *BaseExpr = E->getBase();
-  if (BaseExpr->isLvalue(getContext()) != Expr::LV_Valid) {
+  if (BaseExpr->isRValue()) {
     V = CreateTempAlloca(ClassPtrTy, "resval");
     llvm::Value *Src = EmitScalarExpr(BaseExpr);
     Builder.CreateStore(Src, V);

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Tue Nov 23 23:12:34 2010
@@ -375,7 +375,7 @@
       return;
     }
   } else if (DestReference->isLValueReferenceType()) {
-    if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+    if (!SrcExpr->isLValue()) {
       Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
         << CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
     }
@@ -698,7 +698,7 @@
   if (!R)
     return TC_NotApplicable;
 
-  if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid)
+  if (!SrcExpr->isLValue())
     return TC_NotApplicable;
 
   // Because we try the reference downcast before this function, from now on
@@ -739,7 +739,7 @@
     return TC_NotApplicable;
   }
   bool RValueRef = DestReference->isRValueReferenceType();
-  if (!RValueRef && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+  if (!RValueRef && !SrcExpr->isLValue()) {
     // We know the left side is an lvalue reference, so we can suggest a reason.
     msg = diag::err_bad_cxx_cast_rvalue;
     return TC_NotApplicable;
@@ -1049,7 +1049,7 @@
   QualType SrcType = SrcExpr->getType();
   if (const LValueReferenceType *DestTypeTmp =
         DestType->getAs<LValueReferenceType>()) {
-    if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+    if (!SrcExpr->isLValue()) {
       // Cannot const_cast non-lvalue to lvalue reference type. But if this
       // is C-style, static_cast might find a way, so we simply suggest a
       // message and tell the parent to keep searching.
@@ -1152,7 +1152,7 @@
 
   if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
     bool LValue = DestTypeTmp->isLValueReferenceType();
-    if (LValue && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
+    if (LValue && !SrcExpr->isLValue()) {
       // Cannot cast non-lvalue to reference type. See the similar comment in
       // const_cast.
       msg = diag::err_bad_cxx_cast_rvalue;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 23 23:12:34 2010
@@ -238,8 +238,7 @@
     // An lvalue or rvalue of type "array of N T" or "array of unknown bound of
     // T" can be converted to an rvalue of type "pointer to T".
     //
-    if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
-        E->isLvalue(Context) == Expr::LV_Valid)
+    if (getLangOptions().C99 || getLangOptions().CPlusPlus || E->isLValue())
       ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
                         CK_ArrayToPointerDecay);
   }
@@ -252,7 +251,7 @@
   assert(!Ty.isNull() && "DefaultFunctionArrayLvalueConversion - missing type");
   if (!Ty->isDependentType() && Ty.hasQualifiers() &&
       (!getLangOptions().CPlusPlus || !Ty->isRecordType()) &&
-      E->isLvalue(Context) == Expr::LV_Valid) {
+      E->isLValue()) {
     // C++ [conv.lval]p1:
     //   [...] If T is a non-class type, the type of the rvalue is the
     //   cv-unqualified version of T. Otherwise, the type of the
@@ -789,10 +788,16 @@
 
   MarkDeclarationReferenced(NameInfo.getLoc(), D);
 
-  return Owned(DeclRefExpr::Create(Context,
+  Expr *E = DeclRefExpr::Create(Context,
                               SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
-                                   SS? SS->getRange() : SourceRange(),
-                                   D, NameInfo, Ty, VK));
+                                SS? SS->getRange() : SourceRange(),
+                                D, NameInfo, Ty, VK);
+
+  // Just in case we're building an illegal pointer-to-member.
+  if (isa<FieldDecl>(D) && cast<FieldDecl>(D)->getBitWidth())
+    E->setObjectKind(OK_BitField);
+
+  return Owned(E);
 }
 
 static ExprResult
@@ -7045,7 +7050,7 @@
     // expressions here, but the result of one is always an lvalue anyway.
   }
   NamedDecl *dcl = getPrimaryDecl(op);
-  Expr::isLvalueResult lval = op->isLvalue(S.Context);
+  Expr::LValueClassification lval = op->ClassifyLValue(S.Context);
 
   if (lval == Expr::LV_ClassTemporary) {
     bool sfinae = S.isSFINAEContext();
@@ -7091,25 +7096,21 @@
         << op->getSourceRange();
       return QualType();
     }
-  } else if (op->getBitField()) { // C99 6.5.3.2p1
+  } else if (op->getObjectKind() == OK_BitField) { // C99 6.5.3.2p1
     // The operand cannot be a bit-field
     S.Diag(OpLoc, diag::err_typecheck_address_of)
       << "bit-field" << op->getSourceRange();
         return QualType();
-  } else if (op->refersToVectorElement()) {
+  } else if (op->getObjectKind() == OK_VectorComponent) {
     // The operand cannot be an element of a vector
     S.Diag(OpLoc, diag::err_typecheck_address_of)
       << "vector element" << op->getSourceRange();
     return QualType();
-  } else if (isa<ObjCPropertyRefExpr>(op)) {
+  } else if (op->getObjectKind() == OK_ObjCProperty) {
     // cannot take address of a property expression.
     S.Diag(OpLoc, diag::err_typecheck_address_of)
       << "property expression" << op->getSourceRange();
     return QualType();
-  } else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(op)) {
-    // FIXME: Can LHS ever be null here?
-    if (!CheckAddressOfOperand(S, CO->getTrueExpr(), OpLoc).isNull())
-      return CheckAddressOfOperand(S, CO->getFalseExpr(), OpLoc);
   } else if (dcl) { // C99 6.5.3.2p1
     // We have an lvalue with a decl. Make sure the decl is not declared
     // with the register storage-class specifier.

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 23 23:12:34 2010
@@ -2460,7 +2460,7 @@
   //   can be converted to match an operand expression E2 of type T2 is defined
   //   as follows:
   //   -- If E2 is an lvalue:
-  bool ToIsLvalue = (To->isLvalue(Self.Context) == Expr::LV_Valid);
+  bool ToIsLvalue = To->isLValue();
   if (ToIsLvalue) {
     //   E1 can be converted to match E2 if E1 can be implicitly converted to
     //   type "lvalue reference to T2", subject to the constraint that in the

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Nov 23 23:12:34 2010
@@ -4173,7 +4173,7 @@
   case FK_ReferenceInitFailed:
     S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
       << DestType.getNonReferenceType()
-      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->isLValue()
       << Args[0]->getType()
       << Args[0]->getSourceRange();
     break;
@@ -4182,7 +4182,7 @@
     S.Diag(Kind.getLocation(), diag::err_init_conversion_failed)
       << (int)Entity.getKind()
       << DestType
-      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->isLValue()
       << Args[0]->getType()
       << Args[0]->getSourceRange();
     break;

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Nov 23 23:12:34 2010
@@ -1003,8 +1003,8 @@
   // Lvalue-to-rvalue conversion (C++ 4.1):
   //   An lvalue (3.10) of a non-function, non-array type T can be
   //   converted to an rvalue.
-  Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
-  if (argIsLvalue == Expr::LV_Valid &&
+  bool argIsLValue = From->isLValue();
+  if (argIsLValue &&
       !FromType->isFunctionType() && !FromType->isArrayType() &&
       S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
     SCS.First = ICK_Lvalue_To_Rvalue;
@@ -1036,7 +1036,7 @@
       SCS.setAllToTypes(FromType);
       return true;
     }
-  } else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
+  } else if (FromType->isFunctionType() && argIsLValue) {
     // Function-to-pointer conversion (C++ 4.3).
     SCS.First = ICK_Function_To_Pointer;
 

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Nov 23 23:12:34 2010
@@ -977,8 +977,7 @@
                               diag::err_non_variable_decl_in_for));
     } else {
       Expr *FirstE = cast<Expr>(First);
-      if (!FirstE->isTypeDependent() &&
-          FirstE->isLvalue(Context) != Expr::LV_Valid)
+      if (!FirstE->isTypeDependent() && !FirstE->isLValue())
         return StmtError(Diag(First->getLocStart(),
                    diag::err_selector_element_not_lvalue)
           << First->getSourceRange());
@@ -1312,13 +1311,13 @@
   if (E->isTypeDependent())
     return false;
   
-  if (E->isLvalue(S.Context) == Expr::LV_Valid)
+  if (E->isLValue())
     return false;  // Cool, this is an lvalue.
 
   // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
   // are supposed to allow.
   const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
-  if (E != E2 && E2->isLvalue(S.Context) == Expr::LV_Valid) {
+  if (E != E2 && E2->isLValue()) {
     if (!S.getLangOptions().HeinousExtensions)
       S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
         << E->getSourceRange();

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=120084&r1=120083&r2=120084&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Nov 23 23:12:34 2010
@@ -1757,7 +1757,7 @@
       //   type deduction.
       if (ParamRefType->isRValueReferenceType() &&
           ParamRefType->getAs<TemplateTypeParmType>() &&
-          Args[I]->isLvalue(Context) == Expr::LV_Valid)
+          Args[I]->isLValue())
         ArgType = Context.getLValueReferenceType(ArgType);
     } else {
       // C++ [temp.deduct.call]p2:





More information about the cfe-commits mailing list