From b3d5a323a5ca92ea73443499cee2f15db1ff0fb3 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Wed, 18 Nov 2009 14:59:57 +0000 Subject: Update clang to r89205. --- lib/CodeGen/CGExpr.cpp | 205 ++++++++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 89 deletions(-) (limited to 'lib/CodeGen/CGExpr.cpp') diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index d9dd70ac9e49..2a544c560931 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -267,6 +267,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitCXXBindTemporaryLValue(cast(E)); case Expr::CXXExprWithTemporariesClass: return EmitCXXExprWithTemporariesLValue(cast(E)); + case Expr::CXXZeroInitValueExprClass: + return EmitNullInitializationLValue(cast(E)); + case Expr::CXXDefaultArgExprClass: + return EmitLValue(cast(E)->getExpr()); + case Expr::CXXTypeidExprClass: + return EmitCXXTypeidLValue(cast(E)); case Expr::ObjCMessageExprClass: return EmitObjCMessageExprLValue(cast(E)); @@ -303,8 +309,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::CXXReinterpretCastExprClass: case Expr::CXXConstCastExprClass: return EmitCastLValue(cast(E)); - case Expr::CXXZeroInitValueExprClass: - return EmitNullInitializationLValue(cast(E)); } } @@ -813,53 +817,53 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, } } +static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, + const Expr *E, const VarDecl *VD) { + assert((VD->hasExternalStorage() || VD->isFileVarDecl()) && + "Var decl must have external storage or be a file var decl!"); + + llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD); + if (VD->getType()->isReferenceType()) + V = CGF.Builder.CreateLoad(V, "tmp"); + LValue LV = LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType())); + setObjCGCLValueClass(CGF.getContext(), E, LV); + return LV; +} + LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { - const VarDecl *VD = dyn_cast(E->getDecl()); - - if (VD && (VD->isBlockVarDecl() || isa(VD) || - isa(VD))) { - LValue LV; - bool NonGCable = VD->hasLocalStorage() && - !VD->hasAttr(); - if (VD->hasExternalStorage()) { - llvm::Value *V = CGM.GetAddrOfGlobalVar(VD); - if (VD->getType()->isReferenceType()) - V = Builder.CreateLoad(V, "tmp"); - LV = LValue::MakeAddr(V, MakeQualifiers(E->getType())); - } else { - llvm::Value *V = LocalDeclMap[VD]; - assert(V && "DeclRefExpr not entered in LocalDeclMap?"); - - Qualifiers Quals = MakeQualifiers(E->getType()); - // local variables do not get their gc attribute set. - // local static? - if (NonGCable) Quals.removeObjCGCAttr(); - - if (VD->hasAttr()) { - V = Builder.CreateStructGEP(V, 1, "forwarding"); - V = Builder.CreateLoad(V, false); - V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), - VD->getNameAsString()); - } - if (VD->getType()->isReferenceType()) - V = Builder.CreateLoad(V, "tmp"); - LV = LValue::MakeAddr(V, Quals); + const NamedDecl *ND = E->getDecl(); + + if (const VarDecl *VD = dyn_cast(ND)) { + + // Check if this is a global variable. + if (VD->hasExternalStorage() || VD->isFileVarDecl()) + return EmitGlobalVarDeclLValue(*this, E, VD); + + bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr(); + + llvm::Value *V = LocalDeclMap[VD]; + assert(V && "DeclRefExpr not entered in LocalDeclMap?"); + + Qualifiers Quals = MakeQualifiers(E->getType()); + // local variables do not get their gc attribute set. + // local static? + if (NonGCable) Quals.removeObjCGCAttr(); + + if (VD->hasAttr()) { + V = Builder.CreateStructGEP(V, 1, "forwarding"); + V = Builder.CreateLoad(V, false); + V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), + VD->getNameAsString()); } - LValue::SetObjCNonGC(LV, NonGCable); - setObjCGCLValueClass(getContext(), E, LV); - return LV; - } - - if (VD && VD->isFileVarDecl()) { - llvm::Value *V = CGM.GetAddrOfGlobalVar(VD); if (VD->getType()->isReferenceType()) V = Builder.CreateLoad(V, "tmp"); - LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType())); + LValue LV = LValue::MakeAddr(V, Quals); + LValue::SetObjCNonGC(LV, NonGCable); setObjCGCLValueClass(getContext(), E, LV); return LV; } - if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { + if (const FunctionDecl *FD = dyn_cast(ND)) { llvm::Value* V = CGM.GetAddrOfFunction(FD); if (!FD->hasPrototype()) { if (const FunctionProtoType *Proto = @@ -876,20 +880,15 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LValue::MakeAddr(V, MakeQualifiers(E->getType())); } - if (const ImplicitParamDecl *IPD = dyn_cast(E->getDecl())){ - llvm::Value *V = LocalDeclMap[IPD]; - assert(V && "BlockVarDecl not entered in LocalDeclMap?"); - return LValue::MakeAddr(V, MakeQualifiers(E->getType())); - } - if (E->getQualifier()) { // FIXME: the qualifier check does not seem sufficient here - return EmitPointerToDataMemberLValue(E); + return EmitPointerToDataMemberLValue(cast(ND)); } - assert(0 && "Unimp declref"); - //an invalid LValue, but the assert will - //ensure that this point is never reached. + assert(false && "Unhandled DeclRefExpr"); + + // an invalid LValue, but the assert will + // ensure that this point is never reached. return LValue(); } @@ -924,13 +923,17 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) { return LV; } case UnaryOperator::Real: - case UnaryOperator::Imag: + case UnaryOperator::Imag: { LValue LV = EmitLValue(E->getSubExpr()); unsigned Idx = E->getOpcode() == UnaryOperator::Imag; return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(), Idx, "idx"), MakeQualifiers(ExprTy)); } + case UnaryOperator::PreInc: + case UnaryOperator::PreDec: + return EmitUnsupportedLValue(E, "pre-inc/dec expression"); + } } LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { @@ -1151,18 +1154,24 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { BaseQuals = BaseTy.getQualifiers(); } - FieldDecl *Field = dyn_cast(E->getMemberDecl()); - // FIXME: Handle non-field member expressions - assert(Field && "No code generation for non-field member references"); - LValue MemExpLV = EmitLValueForField(BaseValue, Field, isUnion, - BaseQuals.getCVRQualifiers()); - LValue::SetObjCNonGC(MemExpLV, isNonGC); - setObjCGCLValueClass(getContext(), E, MemExpLV); - return MemExpLV; + NamedDecl *ND = E->getMemberDecl(); + if (FieldDecl *Field = dyn_cast(ND)) { + LValue LV = EmitLValueForField(BaseValue, Field, isUnion, + BaseQuals.getCVRQualifiers()); + LValue::SetObjCNonGC(LV, isNonGC); + setObjCGCLValueClass(getContext(), E, LV); + return LV; + } + + if (VarDecl *VD = dyn_cast(ND)) + return EmitGlobalVarDeclLValue(*this, E, VD); + + assert(false && "Unhandled member declaration!"); + return LValue(); } LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, - FieldDecl* Field, + const FieldDecl* Field, unsigned CVRQualifiers) { CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); @@ -1187,7 +1196,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, } LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, - FieldDecl* Field, + const FieldDecl* Field, bool isUnion, unsigned CVRQualifiers) { if (Field->isBitField()) @@ -1281,22 +1290,26 @@ CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) { return LValue::MakeAddr(Temp, MakeQualifiers(E->getType())); } -/// EmitCastLValue - Casts are never lvalues. If a cast is needed by the code -/// generator in an lvalue context, then it must mean that we need the address -/// of an aggregate in order to access one of its fields. This can happen for -/// all the reasons that casts are permitted with aggregate result, including -/// noop aggregate casts, and cast from scalar to union. +/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast. +/// If the cast is a dynamic_cast, we can have the usual lvalue result, +/// otherwise if a cast is needed by the code generator in an lvalue context, +/// then it must mean that we need the address of an aggregate in order to +/// access one of its fields. This can happen for all the reasons that casts +/// are permitted with aggregate result, including noop aggregate casts, and +/// cast from scalar to union. LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { switch (E->getCastKind()) { default: - // If this is an lvalue cast, treat it as a no-op. - // FIXME: We shouldn't need to check for this explicitly! - if (const ImplicitCastExpr *ICE = dyn_cast(E)) - if (ICE->isLvalueCast()) - return EmitLValue(E->getSubExpr()); - - assert(0 && "Unhandled cast!"); - + return EmitUnsupportedLValue(E, "unexpected cast lvalue"); + + case CastExpr::CK_Dynamic: { + LValue LV = EmitLValue(E->getSubExpr()); + llvm::Value *V = LV.getAddress(); + const CXXDynamicCastExpr *DCE = cast(E); + return LValue::MakeAddr(EmitDynamicCast(V, DCE), + MakeQualifiers(E->getType())); + } + case CastExpr::CK_NoOp: case CastExpr::CK_ConstructorConversion: case CastExpr::CK_UserDefinedConversion: @@ -1320,13 +1333,24 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { return LValue::MakeAddr(Base, MakeQualifiers(E->getType())); } - case CastExpr::CK_ToUnion: { llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType())); EmitAnyExpr(E->getSubExpr(), Temp, false); return LValue::MakeAddr(Temp, MakeQualifiers(E->getType())); - } + } + case CastExpr::CK_BaseToDerived: { + return EmitUnsupportedLValue(E, "base-to-derived cast lvalue"); + } + case CastExpr::CK_BitCast: { + // This must be a reinterpret_cast (or c-style equivalent). + const ExplicitCastExpr *CE = cast(E); + + LValue LV = EmitLValue(E->getSubExpr()); + llvm::Value *V = Builder.CreateBitCast(LV.getAddress(), + ConvertType(CE->getTypeAsWritten())); + return LValue::MakeAddr(V, MakeQualifiers(E->getType())); + } } } @@ -1448,6 +1472,12 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) { return LValue::MakeAddr(Temp, MakeQualifiers(E->getType())); } +LValue +CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) { + llvm::Value *Temp = EmitCXXTypeidExpr(E); + return LValue::MakeAddr(Temp, MakeQualifiers(E->getType())); +} + LValue CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) { LValue LV = EmitLValue(E->getSubExpr()); @@ -1526,19 +1556,18 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) { } -LValue CodeGenFunction::EmitPointerToDataMemberLValue(const DeclRefExpr *E) { - const FieldDecl *Field = cast(E->getDecl()); +LValue CodeGenFunction::EmitPointerToDataMemberLValue(const FieldDecl *Field) { const CXXRecordDecl *ClassDecl = cast(Field->getDeclContext()); QualType NNSpecTy = getContext().getCanonicalType( getContext().getTypeDeclType(const_cast(ClassDecl))); NNSpecTy = getContext().getPointerType(NNSpecTy); llvm::Value *V = llvm::Constant::getNullValue(ConvertType(NNSpecTy)); - LValue MemExpLV = EmitLValueForField(V, const_cast(Field), - /*isUnion*/false, /*Qualifiers*/0); + LValue MemExpLV = EmitLValueForField(V, Field, /*isUnion=*/false, + /*Qualifiers=*/0); const llvm::Type *ResultType = ConvertType(getContext().getPointerDiffType()); V = Builder.CreatePtrToInt(MemExpLV.getAddress(), ResultType, "datamember"); - return LValue::MakeAddr(V, MakeQualifiers(E->getType())); + return LValue::MakeAddr(V, MakeQualifiers(Field->getType())); } RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType, @@ -1571,16 +1600,14 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType, LValue CodeGenFunction:: EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) { - llvm::Value *BaseV = EmitLValue(E->getLHS()).getAddress(); + llvm::Value *BaseV; if (E->getOpcode() == BinaryOperator::PtrMemI) - BaseV = Builder.CreateLoad(BaseV, "indir.ptr"); + BaseV = EmitScalarExpr(E->getLHS()); + else + BaseV = EmitLValue(E->getLHS()).getAddress(); const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext()); BaseV = Builder.CreateBitCast(BaseV, i8Ty); - LValue RHSLV = EmitLValue(E->getRHS()); - llvm::Value *OffsetV = - EmitLoadOfLValue(RHSLV, E->getRHS()->getType()).getScalarVal(); - const llvm::Type* ResultType = ConvertType(getContext().getPointerDiffType()); - OffsetV = Builder.CreateBitCast(OffsetV, ResultType); + llvm::Value *OffsetV = EmitScalarExpr(E->getRHS()); llvm::Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr"); QualType Ty = E->getRHS()->getType(); -- cgit v1.2.3