Ejemplo n.º 1
0
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
  // For an assignment to work, the value on the right has
  // to be compatible with the value on the left.
  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
                                                 E->getRHS()->getType())
         && "Invalid assignment");
  LValue LHS = CGF.EmitLValue(E->getLHS());

  // We have to special case property setters, otherwise we must have
  // a simple lvalue (no aggregates inside vectors, bitfields).
  if (LHS.isPropertyRef()) {
    llvm::Value *AggLoc = DestPtr;
    if (!AggLoc)
      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
                            RValue::getAggregate(AggLoc, VolatileDest));
  } else if (LHS.isKVCRef()) {
    llvm::Value *AggLoc = DestPtr;
    if (!AggLoc)
      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
                            RValue::getAggregate(AggLoc, VolatileDest));
  } else {
    bool RequiresGCollection = false;
    if (CGF.getContext().getLangOptions().getGCMode())
      RequiresGCollection = TypeRequiresGCollection(E->getLHS()->getType());

    // Codegen the RHS so that it stores directly into the LHS.
    CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
                    false, false, RequiresGCollection);
    EmitFinalDestCopy(E, LHS, true);
  }
}
Ejemplo n.º 2
0
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
  // For an assignment to work, the value on the right has
  // to be compatible with the value on the left.
  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
                                                 E->getRHS()->getType())
         && "Invalid assignment");

  // FIXME:  __block variables need the RHS evaluated first!
  LValue LHS = CGF.EmitLValue(E->getLHS());

  // We have to special case property setters, otherwise we must have
  // a simple lvalue (no aggregates inside vectors, bitfields).
  if (LHS.isPropertyRef()) {
    AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
    CGF.EmitAggExpr(E->getRHS(), Slot);
    CGF.EmitStoreThroughPropertyRefLValue(Slot.asRValue(), LHS);
  } else {
    bool GCollection = false;
    if (CGF.getContext().getLangOptions().getGCMode())
      GCollection = TypeRequiresGCollection(E->getLHS()->getType());

    // Codegen the RHS so that it stores directly into the LHS.
    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 
                                                   GCollection);
    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
    EmitFinalDestCopy(E, LHS, true);
  }
}
Ejemplo n.º 3
0
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
  // For an assignment to work, the value on the right has
  // to be compatible with the value on the left.
  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
                                                 E->getRHS()->getType())
         && "Invalid assignment");

  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS()))
    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
      if (VD->hasAttr<BlocksAttr>() &&
          E->getRHS()->HasSideEffects(CGF.getContext())) {
        // When __block variable on LHS, the RHS must be evaluated first 
        // as it may change the 'forwarding' field via call to Block_copy.
        LValue RHS = CGF.EmitLValue(E->getRHS());
        LValue LHS = CGF.EmitLValue(E->getLHS());
        bool GCollection = false;
        if (CGF.getContext().getLangOptions().getGCMode())
          GCollection = TypeRequiresGCollection(E->getLHS()->getType());
        Dest = AggValueSlot::forLValue(LHS, true, GCollection);
        EmitFinalDestCopy(E, RHS, true);
        return;
      }
  
  LValue LHS = CGF.EmitLValue(E->getLHS());

  // We have to special case property setters, otherwise we must have
  // a simple lvalue (no aggregates inside vectors, bitfields).
  if (LHS.isPropertyRef()) {
    const ObjCPropertyRefExpr *RE = LHS.getPropertyRefExpr();
    QualType ArgType = RE->getSetterArgType();
    RValue Src;
    if (ArgType->isReferenceType())
      Src = CGF.EmitReferenceBindingToExpr(E->getRHS(), 0);
    else {
      AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
      CGF.EmitAggExpr(E->getRHS(), Slot);
      Src = Slot.asRValue();
    }
    CGF.EmitStoreThroughPropertyRefLValue(Src, LHS);
  } else {
    bool GCollection = false;
    if (CGF.getContext().getLangOptions().getGCMode())
      GCollection = TypeRequiresGCollection(E->getLHS()->getType());

    // Codegen the RHS so that it stores directly into the LHS.
    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 
                                                   GCollection);
    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
    EmitFinalDestCopy(E, LHS, true);
  }
}
Ejemplo n.º 4
0
ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
    ComplexPairTy Val;
    LValue LV = EmitBinAssignLValue(E, Val);

    // The result of an assignment in C is the assigned r-value.
    if (!CGF.getContext().getLangOptions().CPlusPlus)
        return Val;

    // Objective-C property assignment never reloads the value following a store.
    if (LV.isPropertyRef())
        return Val;

    // If the lvalue is non-volatile, return the computed value of the assignment.
    if (!LV.isVolatileQualified())
        return Val;

    return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
}
Ejemplo n.º 5
0
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
  switch (E->getCastKind()) {
  case CK_Dynamic: {
    assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
    LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
    // FIXME: Do we also need to handle property references here?
    if (LV.isSimple())
      CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
    else
      CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
    
    if (!Dest.isIgnored())
      CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
    break;
  }
      
  case CK_ToUnion: {
    if (Dest.isIgnored()) break;

    // GCC union extension
    QualType Ty = E->getSubExpr()->getType();
    QualType PtrTy = CGF.getContext().getPointerType(Ty);
    llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
                                                 CGF.ConvertType(PtrTy));
    EmitInitializationToLValue(E->getSubExpr(),
                               CGF.MakeAddrLValue(CastPtr, Ty));
    break;
  }

  case CK_DerivedToBase:
  case CK_BaseToDerived:
  case CK_UncheckedDerivedToBase: {
    assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: "
                "should have been unpacked before we got here");
    break;
  }

  case CK_GetObjCProperty: {
    LValue LV = CGF.EmitLValue(E->getSubExpr());
    assert(LV.isPropertyRef());
    RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot());
    EmitGCMove(E, RV);
    break;
  }

  case CK_LValueToRValue: // hope for downstream optimization
  case CK_NoOp:
  case CK_UserDefinedConversion:
  case CK_ConstructorConversion:
    assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
                                                   E->getType()) &&
           "Implicit cast types must be compatible");
    Visit(E->getSubExpr());
    break;
      
  case CK_LValueBitCast:
    llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
    break;

  case CK_Dependent:
  case CK_BitCast:
  case CK_ArrayToPointerDecay:
  case CK_FunctionToPointerDecay:
  case CK_NullToPointer:
  case CK_NullToMemberPointer:
  case CK_BaseToDerivedMemberPointer:
  case CK_DerivedToBaseMemberPointer:
  case CK_MemberPointerToBoolean:
  case CK_IntegralToPointer:
  case CK_PointerToIntegral:
  case CK_PointerToBoolean:
  case CK_ToVoid:
  case CK_VectorSplat:
  case CK_IntegralCast:
  case CK_IntegralToBoolean:
  case CK_IntegralToFloating:
  case CK_FloatingToIntegral:
  case CK_FloatingToBoolean:
  case CK_FloatingCast:
  case CK_AnyPointerToObjCPointerCast:
  case CK_AnyPointerToBlockPointerCast:
  case CK_ObjCObjectLValueCast:
  case CK_FloatingRealToComplex:
  case CK_FloatingComplexToReal:
  case CK_FloatingComplexToBoolean:
  case CK_FloatingComplexCast:
  case CK_FloatingComplexToIntegralComplex:
  case CK_IntegralRealToComplex:
  case CK_IntegralComplexToReal:
  case CK_IntegralComplexToBoolean:
  case CK_IntegralComplexCast:
  case CK_IntegralComplexToFloatingComplex:
  case CK_ObjCProduceObject:
  case CK_ObjCConsumeObject:
  case CK_ObjCReclaimReturnedObject:
    llvm_unreachable("cast kind invalid for aggregate types");
  }
}
Ejemplo n.º 6
0
ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
        QualType DestTy) {
    switch (CK) {
    case CK_Dependent:
        llvm_unreachable("dependent cast kind in IR gen!");

    case CK_GetObjCProperty: {
        LValue LV = CGF.EmitLValue(Op);
        assert(LV.isPropertyRef() && "Unknown LValue type!");
        return CGF.EmitLoadOfPropertyRefLValue(LV).getComplexVal();
    }

    case CK_NoOp:
    case CK_LValueToRValue:
    case CK_UserDefinedConversion:
        return Visit(Op);

    case CK_LValueBitCast: {
        llvm::Value *V = CGF.EmitLValue(Op).getAddress();
        V = Builder.CreateBitCast(V,
                                  CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
        // FIXME: Are the qualifiers correct here?
        return EmitLoadOfComplex(V, DestTy.isVolatileQualified());
    }

    case CK_BitCast:
    case CK_BaseToDerived:
    case CK_DerivedToBase:
    case CK_UncheckedDerivedToBase:
    case CK_Dynamic:
    case CK_ToUnion:
    case CK_ArrayToPointerDecay:
    case CK_FunctionToPointerDecay:
    case CK_NullToPointer:
    case CK_NullToMemberPointer:
    case CK_BaseToDerivedMemberPointer:
    case CK_DerivedToBaseMemberPointer:
    case CK_MemberPointerToBoolean:
    case CK_ConstructorConversion:
    case CK_IntegralToPointer:
    case CK_PointerToIntegral:
    case CK_PointerToBoolean:
    case CK_ToVoid:
    case CK_VectorSplat:
    case CK_IntegralCast:
    case CK_IntegralToBoolean:
    case CK_IntegralToFloating:
    case CK_FloatingToIntegral:
    case CK_FloatingToBoolean:
    case CK_FloatingCast:
    case CK_AnyPointerToObjCPointerCast:
    case CK_AnyPointerToBlockPointerCast:
    case CK_ObjCObjectLValueCast:
    case CK_FloatingComplexToReal:
    case CK_FloatingComplexToBoolean:
    case CK_IntegralComplexToReal:
    case CK_IntegralComplexToBoolean:
    case CK_ObjCProduceObject:
    case CK_ObjCConsumeObject:
    case CK_ObjCReclaimReturnedObject:
        llvm_unreachable("invalid cast kind for complex value");

    case CK_FloatingRealToComplex:
    case CK_IntegralRealToComplex: {
        llvm::Value *Elt = CGF.EmitScalarExpr(Op);

        // Convert the input element to the element type of the complex.
        DestTy = DestTy->getAs<ComplexType>()->getElementType();
        Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);

        // Return (realval, 0).
        return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
    }

    case CK_FloatingComplexCast:
    case CK_FloatingComplexToIntegralComplex:
    case CK_IntegralComplexCast:
    case CK_IntegralComplexToFloatingComplex:
        return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
    }

    llvm_unreachable("unknown cast resulting in complex value");
}