[cfe-commits] r142915 - in /cfe/trunk/lib/Sema: CMakeLists.txt SemaExpr.cpp

John McCall rjmccall at apple.com
Tue Oct 25 01:42:34 PDT 2011


Author: rjmccall
Date: Tue Oct 25 03:42:34 2011
New Revision: 142915

URL: http://llvm.org/viewvc/llvm-project?rev=142915&view=rev
Log:
Pull the pseudo-object stuff into its own file.
Tidy up some marginally related code just to annoy
single-purpose-commit lovers.  No functionality change.


Modified:
    cfe/trunk/lib/Sema/CMakeLists.txt
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CMakeLists.txt?rev=142915&r1=142914&r2=142915&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CMakeLists.txt (original)
+++ cfe/trunk/lib/Sema/CMakeLists.txt Tue Oct 25 03:42:34 2011
@@ -31,6 +31,7 @@
   SemaLookup.cpp
   SemaObjCProperty.cpp
   SemaOverload.cpp
+  SemaPseudoObject.cpp
   SemaStmt.cpp
   SemaTemplate.cpp
   SemaTemplateDeduction.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=142915&r1=142914&r2=142915&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 25 03:42:34 2011
@@ -6960,51 +6960,41 @@
 /// depends on various declarations and thus must be treated specially.
 ///
 static bool IsReadonlyProperty(Expr *E, Sema &S) {
-  if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
-    const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E);
-    if (PropExpr->isImplicitProperty()) return false;
+  const ObjCPropertyRefExpr *PropExpr = dyn_cast<ObjCPropertyRefExpr>(E);
+  if (!PropExpr) return false;
+  if (PropExpr->isImplicitProperty()) return false;
 
-    ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty();
-    QualType BaseType = PropExpr->isSuperReceiver() ? 
+  ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty();
+  QualType BaseType = PropExpr->isSuperReceiver() ? 
                             PropExpr->getSuperReceiverType() :  
                             PropExpr->getBase()->getType();
       
-    if (const ObjCObjectPointerType *OPT =
-          BaseType->getAsObjCInterfacePointerType())
-      if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl())
-        if (S.isPropertyReadonly(PDecl, IFace))
-          return true;
-  }
+  if (const ObjCObjectPointerType *OPT =
+      BaseType->getAsObjCInterfacePointerType())
+    if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl())
+      if (S.isPropertyReadonly(PDecl, IFace))
+        return true;
   return false;
 }
 
 static bool IsConstProperty(Expr *E, Sema &S) {
-  if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) {
-    const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E);
-    if (PropExpr->isImplicitProperty()) return false;
+  const ObjCPropertyRefExpr *PropExpr = dyn_cast<ObjCPropertyRefExpr>(E);
+  if (!PropExpr) return false;
+  if (PropExpr->isImplicitProperty()) return false;
     
-    ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty();
-    QualType T = PDecl->getType();
-    if (T->isReferenceType())
-      T = T->getAs<ReferenceType>()->getPointeeType();
-    CanQualType CT = S.Context.getCanonicalType(T);
-    return CT.isConstQualified();
-  }
-  return false;
+  ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty();
+  QualType T = PDecl->getType().getNonReferenceType();
+  return T.isConstQualified();
 }
 
 static bool IsReadonlyMessage(Expr *E, Sema &S) {
-  if (E->getStmtClass() != Expr::MemberExprClass) 
-    return false;
-  const MemberExpr *ME = cast<MemberExpr>(E);
-  NamedDecl *Member = ME->getMemberDecl();
-  if (isa<FieldDecl>(Member)) {
-    Expr *Base = ME->getBase()->IgnoreParenImpCasts();
-    if (Base->getStmtClass() != Expr::ObjCMessageExprClass)
-      return false;
-    return cast<ObjCMessageExpr>(Base)->getMethodDecl() != 0;
-  }
-  return false;
+  const MemberExpr *ME = dyn_cast<MemberExpr>(E);
+  if (!ME) return false;
+  if (!isa<FieldDecl>(ME->getMemberDecl())) return false;
+  ObjCMessageExpr *Base =
+    dyn_cast<ObjCMessageExpr>(ME->getBase()->IgnoreParenImpCasts());
+  if (!Base) return false;
+  return Base->getMethodDecl() != 0;
 }
 
 /// CheckForModifiableLvalue - Verify that E is a modifiable lvalue.  If not,
@@ -7291,307 +7281,6 @@
     return ResType.getUnqualifiedType();
   }
 }
-
-static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
-                                            const ObjCPropertyRefExpr *PRE) {
-  bool instanceProperty;
-  QualType searchType;
-  if (PRE->isObjectReceiver()) {
-    searchType = PRE->getBase()->getType()
-      ->castAs<ObjCObjectPointerType>()->getPointeeType();
-    instanceProperty = true;
-  } else if (PRE->isSuperReceiver()) {
-    searchType = PRE->getSuperReceiverType();
-    instanceProperty = false;
-    if (const ObjCObjectPointerType *PT
-        = searchType->getAs<ObjCObjectPointerType>()) {
-      searchType = PT->getPointeeType();
-      instanceProperty = true;
-    }
-  } else if (PRE->isClassReceiver()) {
-    searchType = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
-    instanceProperty = false;
-  }
-
-  return S.LookupMethodInObjectType(sel, searchType, instanceProperty);
-}
-
-ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
-  assert(E->getValueKind() == VK_LValue &&
-         E->getObjectKind() == OK_ObjCProperty);
-  const ObjCPropertyRefExpr *PRE = E->getObjCProperty();
-
-  QualType ReceiverType;
-  if (PRE->isObjectReceiver())
-    ReceiverType = PRE->getBase()->getType();
-  else if (PRE->isSuperReceiver())
-    ReceiverType = PRE->getSuperReceiverType();
-  else
-    ReceiverType = Context.getObjCInterfaceType(PRE->getClassReceiver());
-    
-  ExprValueKind VK = VK_RValue;
-  QualType T;
-  if (PRE->isImplicitProperty()) {
-    if (ObjCMethodDecl *GetterMethod = 
-          PRE->getImplicitPropertyGetter()) {
-      T = getMessageSendResultType(ReceiverType, GetterMethod,
-                                   PRE->isClassReceiver(), 
-                                   PRE->isSuperReceiver());
-      VK = Expr::getValueKindForType(GetterMethod->getResultType());
-    } else {
-      Diag(PRE->getLocation(), diag::err_getter_not_found)
-            << PRE->getBase()->getType();
-      return ExprError();
-    }
-  } else {
-    ObjCPropertyDecl *prop = PRE->getExplicitProperty();
-
-    ObjCMethodDecl *getter =
-      LookupMethodInReceiverType(*this, prop->getGetterName(), PRE);
-    if (getter && !getter->hasRelatedResultType())
-      DiagnosePropertyAccessorMismatch(prop, getter, PRE->getLocation());
-    if (!getter) getter = prop->getGetterMethodDecl();
-
-    // Figure out the type of the expression.  Mostly this is the
-    // result type of the getter, if possible.
-    if (getter) {
-      T = getMessageSendResultType(ReceiverType, getter, 
-                                   PRE->isClassReceiver(), 
-                                   PRE->isSuperReceiver());
-      VK = Expr::getValueKindForType(getter->getResultType());
-
-      // As a special case, if the method returns 'id', try to get a
-      // better type from the property.
-      if (VK == VK_RValue && T->isObjCIdType() &&
-          prop->getType()->isObjCRetainableType())
-        T = prop->getType();
-    } else {
-      T = prop->getType();
-      VK = Expr::getValueKindForType(T);
-      T = T.getNonLValueExprType(Context);
-    }
-  }
-
-  E->setType(T);
-  E = ImplicitCastExpr::Create(Context, T, CK_GetObjCProperty, E, 0, VK);
-  
-  ExprResult Result = MaybeBindToTemporary(E);
-  if (!Result.isInvalid())
-    E = Result.take();
-
-  return Owned(E);
-}
-
-namespace {
-  struct PseudoObjectInfo {
-    const ObjCPropertyRefExpr *RefExpr;
-    bool HasSetter;
-    Selector SetterSelector;
-    ParmVarDecl *SetterParam;
-    QualType SetterParamType;
-
-    void setSetter(ObjCMethodDecl *setter) {
-      HasSetter = true;
-      SetterParam = *setter->param_begin();
-      SetterParamType = SetterParam->getType().getUnqualifiedType();
-    }
-
-    PseudoObjectInfo(Sema &S, Expr *E)
-      : RefExpr(E->getObjCProperty()), HasSetter(false), SetterParam(0) {
-
-      assert(E->getValueKind() == VK_LValue &&
-             E->getObjectKind() == OK_ObjCProperty);
-
-      // Try to find a setter.
-
-      // For implicit properties, just trust the lookup we already did.
-      if (RefExpr->isImplicitProperty()) {
-        if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
-          setSetter(setter);
-          SetterSelector = setter->getSelector();
-        } else {
-          IdentifierInfo *getterName =
-            RefExpr->getImplicitPropertyGetter()->getSelector()
-              .getIdentifierInfoForSlot(0);
-          SetterSelector = 
-            SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
-                                               S.PP.getSelectorTable(),
-                                               getterName);
-        }
-        return;
-      }
-
-      // For explicit properties, this is more involved.
-      ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
-      SetterSelector = prop->getSetterName();
-
-      // Do a normal method lookup first.
-      if (ObjCMethodDecl *setter =
-            LookupMethodInReceiverType(S, SetterSelector, RefExpr))
-        return setSetter(setter);
-
-      // If that failed, trust the type on the @property declaration.
-      if (!prop->isReadOnly()) {
-        HasSetter = true;
-        SetterParamType = prop->getType().getUnqualifiedType();
-      }
-    }
-  };
-}
-
-/// Check an increment or decrement of a pseudo-object expression.
-ExprResult Sema::checkPseudoObjectIncDec(Scope *S, SourceLocation opcLoc,
-                                         UnaryOperatorKind opcode, Expr *op) {
-  assert(UnaryOperator::isIncrementDecrementOp(opcode));
-  PseudoObjectInfo info(*this, op);
-
-  // If there's no setter, we have no choice but to try to assign to
-  // the result of the getter.
-  if (!info.HasSetter) {
-    QualType resultType = info.RefExpr->getGetterResultType();
-    assert(!resultType.isNull() && "property has no setter and no getter!");
-
-    // Only do this if the getter returns an l-value reference type.
-    if (const LValueReferenceType *refType
-          = resultType->getAs<LValueReferenceType>()) {
-      op = ImplicitCastExpr::Create(Context, refType->getPointeeType(),
-                                    CK_GetObjCProperty, op, 0, VK_LValue);
-      return BuildUnaryOp(S, opcLoc, opcode, op);
-    }
-
-    // Otherwise, it's an error.
-    Diag(opcLoc, diag::err_nosetter_property_incdec)
-      << unsigned(info.RefExpr->isImplicitProperty())
-      << unsigned(UnaryOperator::isDecrementOp(opcode))
-      << info.SetterSelector
-      << op->getSourceRange();
-    return ExprError();
-  }
-
-  // ++/-- behave like compound assignments, i.e. they need a getter.
-  QualType getterResultType = info.RefExpr->getGetterResultType();
-  if (getterResultType.isNull()) {
-    assert(info.RefExpr->isImplicitProperty());
-    Diag(opcLoc, diag::err_nogetter_property_incdec)
-      << unsigned(UnaryOperator::isDecrementOp(opcode))
-      << info.RefExpr->getImplicitPropertyGetter()->getSelector()
-      << op->getSourceRange();
-    return ExprError();
-  }
-
-  // HACK: change the type of the operand to prevent further placeholder
-  // transformation.
-  op->setType(getterResultType.getNonLValueExprType(Context));
-  op->setObjectKind(OK_Ordinary);
-  
-  ExprResult result = CreateBuiltinUnaryOp(opcLoc, opcode, op);
-  if (result.isInvalid()) return ExprError();
-
-  // Change the object kind back.
-  op->setObjectKind(OK_ObjCProperty);
-  return result;
-}
-
-ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
-                                             BinaryOperatorKind opcode,
-                                             Expr *LHS, Expr *RHS) {
-  assert(BinaryOperator::isAssignmentOp(opcode));
-  PseudoObjectInfo info(*this, LHS);
-
-  // If there's no setter, we have no choice but to try to assign to
-  // the result of the getter.
-  if (!info.HasSetter) {
-    QualType resultType = info.RefExpr->getGetterResultType();
-    assert(!resultType.isNull() && "property has no setter and no getter!");
-
-    // Only do this if the getter returns an l-value reference type.
-    if (const LValueReferenceType *refType
-          = resultType->getAs<LValueReferenceType>()) {
-      LHS = ImplicitCastExpr::Create(Context, refType->getPointeeType(),
-                                     CK_GetObjCProperty, LHS, 0, VK_LValue);
-      return BuildBinOp(S, opcLoc, opcode, LHS, RHS);
-    }
-
-    // Otherwise, it's an error.
-    Diag(opcLoc, diag::err_nosetter_property_assignment)
-      << unsigned(info.RefExpr->isImplicitProperty())
-      << info.SetterSelector
-      << LHS->getSourceRange() << RHS->getSourceRange();
-    return ExprError();
-  }
-
-  // If there is a setter, we definitely want to use it.
-
-  // If this is a simple assignment, just initialize the parameter
-  // with the RHS.
-  if (opcode == BO_Assign) {
-    LHS->setType(info.SetterParamType.getNonLValueExprType(Context));
-
-    // Under certain circumstances, we need to type-check the RHS as a
-    // straight-up parameter initialization.  This gives somewhat
-    // inferior diagnostics, so we try to avoid it.
-
-    if (RHS->isTypeDependent()) {
-      // Just build the expression.
-
-    } else if ((getLangOptions().CPlusPlus && LHS->getType()->isRecordType()) ||
-               (getLangOptions().ObjCAutoRefCount &&
-                info.SetterParam &&
-                info.SetterParam->hasAttr<NSConsumedAttr>())) {
-      InitializedEntity param = (info.SetterParam
-        ? InitializedEntity::InitializeParameter(Context, info.SetterParam)
-        : InitializedEntity::InitializeParameter(Context, info.SetterParamType,
-                                                 /*consumed*/ false));
-      ExprResult arg = PerformCopyInitialization(param, opcLoc, RHS);
-      if (arg.isInvalid()) return ExprError();
-      RHS = arg.take();
-
-      // Warn about assignments of +1 objects to unsafe pointers in ARC.
-      // CheckAssignmentOperands does this on the other path.
-      if (getLangOptions().ObjCAutoRefCount)
-        checkUnsafeExprAssigns(opcLoc, LHS, RHS);
-    } else {
-      ExprResult RHSResult = Owned(RHS);
-
-      LHS->setObjectKind(OK_Ordinary);
-      QualType resultType = CheckAssignmentOperands(LHS, RHSResult, opcLoc,
-                                                    /*compound*/ QualType());
-      LHS->setObjectKind(OK_ObjCProperty);
-
-      if (!RHSResult.isInvalid()) RHS = RHSResult.take();
-      if (resultType.isNull()) return ExprError();
-    }
-
-    // Warn about property sets in ARC that might cause retain cycles.
-    if (getLangOptions().ObjCAutoRefCount && !info.RefExpr->isSuperReceiver())
-      checkRetainCycles(const_cast<Expr*>(info.RefExpr->getBase()), RHS);
-
-    return new (Context) BinaryOperator(LHS, RHS, opcode, RHS->getType(),
-                                        RHS->getValueKind(),
-                                        RHS->getObjectKind(),
-                                        opcLoc);
-  }
-
-  // If this is a compound assignment, we need to use the getter, too.
-  QualType getterResultType = info.RefExpr->getGetterResultType();
-  if (getterResultType.isNull()) {
-    Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
-      << LHS->getSourceRange() << RHS->getSourceRange();
-    return ExprError();
-  }
-
-  // HACK: change the type of the LHS to prevent further placeholder
-  // transformation.
-  LHS->setType(getterResultType.getNonLValueExprType(Context));
-  LHS->setObjectKind(OK_Ordinary);
-  
-  ExprResult result = CreateBuiltinBinOp(opcLoc, opcode, LHS, RHS);
-  if (result.isInvalid()) return ExprError();
-
-  // Change the object kind back.
-  LHS->setObjectKind(OK_ObjCProperty);
-  return result;
-}
   
 
 /// getPrimaryDecl - Helper function for CheckAddressOfOperand().





More information about the cfe-commits mailing list