[cfe-commits] r120896 - in /cfe/trunk: include/clang/AST/Expr.h lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGExprComplex.cpp lib/Sema/SemaOverload.cpp

John McCall rjmccall at apple.com
Sat Dec 4 00:14:53 PST 2010


Author: rjmccall
Date: Sat Dec  4 02:14:53 2010
New Revision: 120896

URL: http://llvm.org/viewvc/llvm-project?rev=120896&view=rev
Log:
Remove some defensive calls to EmitLoadOfPropertyRefLValue that shouldn't
be required, and then fix up some missing loads on overloaded-operator
paths which that exposed.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=120896&r1=120895&r2=120896&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Dec  4 02:14:53 2010
@@ -2395,13 +2395,24 @@
   static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
   bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
 
-  bool isAssignmentOp() const { return Opc >= BO_Assign && Opc <= BO_OrAssign; }
-  bool isCompoundAssignmentOp() const {
+  static bool isAssignmentOp(Opcode Opc) {
+    return Opc >= BO_Assign && Opc <= BO_OrAssign;
+  }
+  bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); }
+
+  static bool isCompoundAssignmentOp(Opcode Opc) {
     return Opc > BO_Assign && Opc <= BO_OrAssign;
   }
-  bool isShiftAssignOp() const {
+  bool isCompoundAssignmentOp() const {
+    return isCompoundAssignmentOp(getOpcode());
+  }
+
+  static bool isShiftAssignOp(Opcode Opc) {
     return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
   }
+  bool isShiftAssignOp() const {
+    return isShiftAssignOp(getOpcode());
+  }
 
   static bool classof(const Stmt *S) {
     return S->getStmtClass() >= firstBinaryOperatorConstant &&

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=120896&r1=120895&r2=120896&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Dec  4 02:14:53 2010
@@ -195,13 +195,6 @@
   if (E->isLValue()) {
     // Emit the expression as an lvalue.
     LValue LV = CGF.EmitLValue(E);
-    if (LV.isPropertyRef()) {
-      QualType QT = E->getType();
-      RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV);
-      assert(RV.isScalar() && "EmitExprForReferenceBinding");
-      return RV.getScalarVal();
-    }
-    
     if (LV.isSimple())
       return LV.getAddress();
     
@@ -1537,11 +1530,6 @@
     const PointerType *PTy =
       BaseExpr->getType()->getAs<PointerType>();
     BaseQuals = PTy->getPointeeType().getQualifiers();
-  } else if (ObjCPropertyRefExpr *PRE
-               = dyn_cast<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens())) {
-    RValue RV = EmitLoadOfPropertyRefLValue(EmitObjCPropertyRefLValue(PRE));
-    BaseValue = RV.getAggregateAddr();
-    BaseQuals = BaseExpr->getType().getQualifiers();
   } else {
     LValue BaseLV = EmitLValue(BaseExpr);
     if (BaseLV.isNonGC())
@@ -1771,17 +1759,8 @@
   }
 
   case CK_NoOp:
-    if (!E->getSubExpr()->isRValue() || E->getType()->isRecordType()) {
-      LValue LV = EmitLValue(E->getSubExpr());
-      if (LV.isPropertyRef()) {
-        QualType QT = E->getSubExpr()->getType();
-        RValue RV = EmitLoadOfPropertyRefLValue(LV);
-        assert(RV.isAggregate());
-        llvm::Value *V = RV.getAggregateAddr();
-        return MakeAddrLValue(V, QT);
-      }
-      return LV;
-    }
+    if (!E->getSubExpr()->isRValue() || E->getType()->isRecordType())
+      return EmitLValue(E->getSubExpr());
     // Fall through to synthesize a temporary.
 
   case CK_LValueToRValue:
@@ -1843,15 +1822,7 @@
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
     
     LValue LV = EmitLValue(E->getSubExpr());
-    llvm::Value *This;
-    if (LV.isPropertyRef()) {
-      QualType QT = E->getSubExpr()->getType();
-      RValue RV = EmitLoadOfPropertyRefLValue(LV);
-      assert (!RV.isScalar() && "EmitCastLValue");
-      This = RV.getAggregateAddr();
-    }
-    else
-      This = LV.getAddress();
+    llvm::Value *This = LV.getAddress();
     
     // Perform the derived-to-base conversion
     llvm::Value *Base = 

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=120896&r1=120895&r2=120896&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Sat Dec  4 02:14:53 2010
@@ -122,16 +122,8 @@
   llvm::Value *This;
   if (ME->isArrow())
     This = EmitScalarExpr(ME->getBase());
-  else {
-    LValue BaseLV = EmitLValue(ME->getBase());
-    if (BaseLV.isPropertyRef()) {
-      QualType QT = ME->getBase()->getType();
-      RValue RV = EmitLoadOfPropertyRefLValue(BaseLV);
-      This = RV.isScalar() ? RV.getScalarVal() : RV.getAggregateAddr();
-    }
-    else
-      This = BaseLV.getAddress();
-  }
+  else
+    This = EmitLValue(ME->getBase()).getAddress();
 
   if (MD->isTrivial()) {
     if (isa<CXXDestructorDecl>(MD)) return RValue::get(0);
@@ -233,22 +225,14 @@
                                                ReturnValueSlot ReturnValue) {
   assert(MD->isInstance() &&
          "Trying to emit a member call expr on a static method!");
+  LValue LV = EmitLValue(E->getArg(0));
+  llvm::Value *This = LV.getAddress();
+
   if (MD->isCopyAssignmentOperator()) {
     const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
     if (ClassDecl->hasTrivialCopyAssignment()) {
       assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
              "EmitCXXOperatorMemberCallExpr - user declared copy assignment");
-      LValue LV = EmitLValue(E->getArg(0));
-      llvm::Value *This;
-      if (LV.isPropertyRef()) {
-        AggValueSlot Slot = CreateAggTemp(E->getArg(1)->getType());
-        EmitAggExpr(E->getArg(1), Slot);
-        EmitStoreThroughPropertyRefLValue(Slot.asRValue(), LV);
-        return RValue::getAggregate(0, false);
-      }
-      else
-        This = LV.getAddress();
-      
       llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
       QualType Ty = E->getType();
       EmitAggregateCopy(This, Src, Ty);
@@ -260,17 +244,6 @@
   const llvm::Type *Ty =
     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
                                    FPT->isVariadic());
-  LValue LV = EmitLValue(E->getArg(0));
-  llvm::Value *This;
-  if (LV.isPropertyRef()) {
-    QualType QT = E->getArg(0)->getType();
-    RValue RV = EmitLoadOfPropertyRefLValue(LV);
-    assert (!RV.isScalar() && "EmitCXXOperatorMemberCallExpr");
-    This = RV.getAggregateAddr();
-  }
-  else
-    This = LV.getAddress();
-
   llvm::Value *Callee;
   if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0), MD))
     Callee = BuildVirtualCall(MD, This, Ty);

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=120896&r1=120895&r2=120896&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Sat Dec  4 02:14:53 2010
@@ -60,7 +60,10 @@
   /// value l-value, this method emits the address of the l-value, then loads
   /// and returns the result.
   ComplexPairTy EmitLoadOfLValue(const Expr *E) {
-    LValue LV = CGF.EmitLValue(E);
+    return EmitLoadOfLValue(CGF.EmitLValue(E));
+  }
+
+  ComplexPairTy EmitLoadOfLValue(LValue LV) {
     if (LV.isSimple())
       return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
 
@@ -72,6 +75,16 @@
   /// the real and imaginary pieces.
   ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
 
+  /// EmitStoreThroughLValue - Given an l-value of complex type, store
+  /// a complex number into it.
+  void EmitStoreThroughLValue(ComplexPairTy Val, LValue LV) {
+    if (LV.isSimple())
+      return EmitStoreOfComplex(Val, LV.getAddress(), LV.isVolatileQualified());
+
+    assert(LV.isPropertyRef() && "Unknown LValue type!");
+    CGF.EmitStoreThroughPropertyRefLValue(RValue::getComplex(Val), LV);
+  }
+
   /// EmitStoreOfComplex - Store the specified real/imag parts into the
   /// specified value pointer.
   void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
@@ -540,13 +553,9 @@
   OpInfo.RHS = Visit(E->getRHS());
   
   LValue LHS = CGF.EmitLValue(E->getLHS());
-  // We know the LHS is a complex lvalue.
-  ComplexPairTy LHSComplexPair;
-  if (LHS.isPropertyRef())
-    LHSComplexPair = CGF.EmitLoadOfPropertyRefLValue(LHS).getComplexVal();
-  else
-    LHSComplexPair = EmitLoadOfComplex(LHS.getAddress(),
-                                       LHS.isVolatileQualified());
+
+  // Load from the l-value.
+  ComplexPairTy LHSComplexPair = EmitLoadOfLValue(LHS);
   
   OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
 
@@ -558,10 +567,7 @@
   Val = Result;
 
   // Store the result value into the LHS lvalue.
-  if (LHS.isPropertyRef())
-    CGF.EmitStoreThroughPropertyRefLValue(RValue::getComplex(Result), LHS);
-  else
-    EmitStoreOfComplex(Result, LHS.getAddress(), LHS.isVolatileQualified());
+  EmitStoreThroughLValue(Result, LHS);
 
   return LHS;
 }
@@ -603,10 +609,7 @@
   LValue LHS = CGF.EmitLValue(E->getLHS());
 
   // Store the result value into the LHS lvalue.
-  if (LHS.isPropertyRef())
-    CGF.EmitStoreThroughPropertyRefLValue(RValue::getComplex(Val), LHS);
-  else
-    EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
+  EmitStoreThroughLValue(Val, LHS);
 
   return LHS;
 }

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=120896&r1=120895&r2=120896&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Dec  4 02:14:53 2010
@@ -23,6 +23,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "llvm/ADT/DenseSet.h"
@@ -7081,6 +7082,9 @@
   // TODO: provide better source location info.
   DeclarationNameInfo OpNameInfo(OpName, OpLoc);
 
+  if (Input->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Input);
+
   Expr *Args[2] = { Input, 0 };
   unsigned NumArgs = 1;
 
@@ -7292,10 +7296,38 @@
                                                    OpLoc));
   }
 
-  // If this is the .* operator, which is not overloadable, just
-  // create a built-in binary operator.
-  if (Opc == BO_PtrMemD)
-    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+  // Always do property rvalue conversions on the RHS.
+  if (Args[1]->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Args[1]);
+
+  // The LHS is more complicated.
+  if (Args[0]->getObjectKind() == OK_ObjCProperty) {
+
+    // There's a tension for assignment operators between primitive
+    // property assignment and the overloaded operators.
+    if (BinaryOperator::isAssignmentOp(Opc)) {
+      const ObjCPropertyRefExpr *PRE = LHS->getObjCProperty();
+
+      // Is the property "logically" settable?
+      bool Settable = (PRE->isExplicitProperty() ||
+                       PRE->getImplicitPropertySetter());
+
+      // To avoid gratuitously inventing semantics, use the primitive
+      // unless it isn't.  Thoughts in case we ever really care:
+      // - If the property isn't logically settable, we have to
+      //   load and hope.
+      // - If the property is settable and this is simple assignment,
+      //   we really should use the primitive.
+      // - If the property is settable, then we could try overloading
+      //   on a generic lvalue of the appropriate type;  if it works
+      //   out to a builtin candidate, we would do that same operation
+      //   on the property, and otherwise just error.
+      if (Settable)
+        return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+    }
+
+    ConvertPropertyForRValue(Args[0]);
+  }
 
   // If this is the assignment operator, we only perform overload resolution
   // if the left-hand side is a class or enumeration type. This is actually
@@ -7306,6 +7338,11 @@
   if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
+  // If this is the .* operator, which is not overloadable, just
+  // create a built-in binary operator.
+  if (Opc == BO_PtrMemD)
+    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+
   // Build an empty overload set.
   OverloadCandidateSet CandidateSet(OpLoc);
 
@@ -7496,6 +7533,11 @@
                                                    RLoc));
   }
 
+  if (Args[0]->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Args[0]);
+  if (Args[1]->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Args[1]);
+
   // Build an empty overload set.
   OverloadCandidateSet CandidateSet(LLoc);
 
@@ -7766,6 +7808,9 @@
                                    SourceLocation LParenLoc,
                                    Expr **Args, unsigned NumArgs,
                                    SourceLocation RParenLoc) {
+  if (Object->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Object);
+
   assert(Object->getType()->isRecordType() && "Requires object type argument");
   const RecordType *Record = Object->getType()->getAs<RecordType>();
 
@@ -8017,6 +8062,9 @@
 Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
   assert(Base->getType()->isRecordType() && "left-hand side must have class type");
 
+  if (Base->getObjectKind() == OK_ObjCProperty)
+    ConvertPropertyForRValue(Base);
+
   SourceLocation Loc = Base->getExprLoc();
 
   // C++ [over.ref]p1:





More information about the cfe-commits mailing list