]> granicus.if.org Git - clang/commitdiff
Switch a lot of call-sites over to using the new value-kind calculations.
authorJohn McCall <rjmccall@apple.com>
Wed, 24 Nov 2010 05:12:34 +0000 (05:12 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 24 Nov 2010 05:12:34 +0000 (05:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120084 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
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

index 3050bf9a2e9a5bb06211748cfd25ffb18804db52..041446d6895da8de874889bccc3c6fee470be2ab 100644 (file)
@@ -127,19 +127,25 @@ public:
   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 @@ public:
     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,
index 12a92f8ac6ff40d426815184f42c264863369b67..7b247701021f5d5c4f4145c8d6e0424501dbfd32 100644 (file)
@@ -2378,7 +2378,7 @@ static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
 
   // 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;
index c92061107535f3f47cc35cde99a2ca07c4774a46..3e3792e21fe727119ebc07558c0ea911bb75f767 100644 (file)
@@ -1460,7 +1460,7 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
 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,
index f24ddcbb73255fe8a5f38de3a9a4ff6d018e8501..4025f18a3b44670abbaae8cc7e3599550a2e9a02 100644 (file)
@@ -529,7 +529,7 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
   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;
index 7682baa8e5938428de43be0d7aa60573d005d592..f802b3981c7a83d5bad9a883a56cc59ed51407c6 100644 (file)
@@ -192,7 +192,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
   }
 
   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 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
           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 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
     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::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
 
 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)
index a5f9890c12a061922dc728153624d125bcfd0afd..e5ea26c24b61918be797a49091703e45da399547 100644 (file)
@@ -1474,7 +1474,7 @@ Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
     // 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 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
     // 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 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
   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);
index 06c2758a9bd7276ce3efa3aca85295a452afdf8d..5997d98fa58e1927f856f4c8243d772c61be1361 100644 (file)
@@ -375,7 +375,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
       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 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
   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 @@ TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
     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 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
   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 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
 
   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;
index fa7069628b988f460e146868d0f0e2adfef9cc7e..2daeed1257ac53794770835edbdb68a8c00cab20 100644 (file)
@@ -238,8 +238,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
     // 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 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
   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 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
 
   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 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp,
     // 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 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp,
         << 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.
index fde207ed38da7bf0f819594f7aa6f923ff27fe07..f5d7170e5cda5fa45da817496f9f1d20d7b3279d 100644 (file)
@@ -2460,7 +2460,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
   //   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
index 1b47332c53f1a70bc2adbed783157b404afac32d..455f7bbba74057e352d71e32ab177152747bfdde 100644 (file)
@@ -4173,7 +4173,7 @@ bool InitializationSequence::Diagnose(Sema &S,
   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 @@ bool InitializationSequence::Diagnose(Sema &S,
     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;
index 5ea7414026cf74156a0c76ba5fcfd7660be1ce72..5da655907cf8d68e58ae09bd62b487798a6e95f2 100644 (file)
@@ -1003,8 +1003,8 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
   // 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 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
       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;
 
index 68b7a8c163b2bd03e0841f39c984d93b0d4ff0aa..48d2b47c8a6c3f0fa510f0757b7b5a81d4d98dd9 100644 (file)
@@ -977,8 +977,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
                               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 @@ static bool CheckAsmLValue(const Expr *E, Sema &S) {
   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();
index 39996e315dbc44888495f2a19dbd40b050c436f4..070c334f872163ac32bde83609d8c7258eca53f2 100644 (file)
@@ -1757,7 +1757,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
       //   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: