CGExprAgg.cpp revision 195337d2e5d4625ae9dc1328c7cdbc7115b0261b
1c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===// 2bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah// 3c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// The LLVM Compiler Infrastructure 4c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// 5c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// This file is distributed under the University of Illinois Open Source 6c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// License. See LICENSE.TXT for details. 7c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// 8c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 9c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// 10c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// This contains code to emit Aggregate Expr nodes as LLVM code. 11c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// 12c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 13c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 14c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "CodeGenFunction.h" 15c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "CodeGenModule.h" 16c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "CGObjCRuntime.h" 17c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "clang/AST/ASTContext.h" 18c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "clang/AST/DeclCXX.h" 19c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "clang/AST/StmtVisitor.h" 2016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed#include "llvm/Constants.h" 21bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah#include "llvm/Function.h" 22c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "llvm/GlobalVariable.h" 23c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "llvm/Intrinsics.h" 24c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedusing namespace clang; 2516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedusing namespace CodeGen; 26c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 27c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 2816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed// Aggregate Expression Emitter 2916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed//===----------------------------------------------------------------------===// 30c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 31c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmednamespace { 32c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedclass AggExprEmitter : public StmtVisitor<AggExprEmitter> { 3316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CodeGenFunction &CGF; 3416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGBuilderTy &Builder; 3516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *DestPtr; 36c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed bool VolatileDest; 37c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed bool IgnoreResult; 38c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed bool IsInitializer; 39c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed bool RequiresGCollection; 40c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedpublic: 4116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v, 4216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed bool ignore, bool isinit, bool requiresGCollection) 4316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed : CGF(cgf), Builder(CGF.Builder), 4416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore), 4516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed IsInitializer(isinit), RequiresGCollection(requiresGCollection) { 4616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 4716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 48c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed //===--------------------------------------------------------------------===// 49c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Utilities 50c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed //===--------------------------------------------------------------------===// 51c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 52c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed /// EmitAggLoadOfLValue - Given an expression with aggregate type that 53c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed /// represents a value lvalue, this method emits the address of the lvalue, 54c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed /// then loads the result into DestPtr. 55c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void EmitAggLoadOfLValue(const Expr *E); 56c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 57359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 58c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false); 59c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false); 60c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 61c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed //===--------------------------------------------------------------------===// 62c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Visitor Methods 63359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall //===--------------------------------------------------------------------===// 64c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 65c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitStmt(Stmt *S) { 661409b3ce70e0f46806c431eff4db4d9881598e05Naseer Ahmed CGF.ErrorUnsupported(S, "aggregate expression"); 671409b3ce70e0f46806c431eff4db4d9881598e05Naseer Ahmed } 681409b3ce70e0f46806c431eff4db4d9881598e05Naseer Ahmed void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); } 69c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); } 7016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 7116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // l-values. 7216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); } 73b2fa7edbf5150e6bdc25b1d37dfd5e14ad571ae9Naseer Ahmed void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } 74c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); } 75c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); } 76660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 77c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitAggLoadOfLValue(E); 78c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 79c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitArraySubscriptExpr(ArraySubscriptExpr *E) { 80c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitAggLoadOfLValue(E); 81c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 82c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) { 83c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitAggLoadOfLValue(E); 84c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 85c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitPredefinedExpr(const PredefinedExpr *E) { 86c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitAggLoadOfLValue(E); 87c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 88c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 89c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Operators. 90c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCastExpr(CastExpr *E); 91c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCallExpr(const CallExpr *E); 92c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitStmtExpr(const StmtExpr *E); 93c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitBinaryOperator(const BinaryOperator *BO); 94c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO); 95c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitBinAssign(const BinaryOperator *E); 9616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitBinComma(const BinaryOperator *E); 9716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitUnaryAddrOf(const UnaryOperator *E); 9816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 9916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitObjCMessageExpr(ObjCMessageExpr *E); 10016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 10116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitAggLoadOfLValue(E); 10216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 10316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); 10416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E); 10516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 106c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitConditionalOperator(const ConditionalOperator *CO); 107c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitChooseExpr(const ChooseExpr *CE); 108c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitInitListExpr(InitListExpr *E); 109660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); 11016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 111c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Visit(DAE->getExpr()); 112c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 113c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); 114c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXConstructExpr(const CXXConstructExpr *E); 115c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); 116c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); 117c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } 11816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 119c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitVAArgExpr(VAArgExpr *E); 120c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 121c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void EmitInitializationToLValue(Expr *E, LValue Address, QualType T); 122c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void EmitNullInitializationToLValue(LValue Address, QualType T); 123c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // case Expr::ChooseExprClass: 124c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); } 12516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed}; 12616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} // end anonymous namespace. 127c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 128c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 129c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// Utilities 130c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 131c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 132c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed/// EmitAggLoadOfLValue - Given an expression with aggregate type that 133c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed/// represents a value lvalue, this method emits the address of the lvalue, 134c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed/// then loads the result into DestPtr. 135c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) { 136c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed LValue LV = CGF.EmitLValue(E); 137c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitFinalDestCopy(E, LV); 138c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 139c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 140c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 141c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) { 142c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed assert(Src.isAggregate() && "value must be aggregate value!"); 143c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 144c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // If the result is ignored, don't copy from the value. 145c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (DestPtr == 0) { 1469a678455a788dc76a43ad93459ae6a792f0fd114Saurabh Shah if (!Src.isVolatileQualified() || (IgnoreResult && Ignore)) 147c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 148c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // If the source is volatile, we must read from it; to do that, we need 149c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // some place to put it. 150c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp"); 151c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 152c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 153c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (RequiresGCollection) { 154c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, 155c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed DestPtr, Src.getAggregateAddr(), 156c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed E->getType()); 157c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 158c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 159c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // If the result of the assignment is used, copy the LHS there also. 160c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // FIXME: Pass VolatileDest as well. I think we also need to merge volatile 161c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // from the source as well, as we can't eliminate it if either operand 162c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // is volatile, unless copy has volatile for both source and destination.. 163c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(), 16416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed VolatileDest|Src.isVolatileQualified()); 165c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 166c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 167c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. 16816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { 169c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc"); 17016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 171c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(), 17216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Src.isVolatileQualified()), 173c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Ignore); 17416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 17516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 176c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 177c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed// Visitor Methods 178c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed//===----------------------------------------------------------------------===// 179c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 180c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitCastExpr(CastExpr *E) { 181c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed switch (E->getCastKind()) { 182c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed default: assert(0 && "Unhandled cast kind!"); 183c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 184c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed case CastExpr::CK_ToUnion: { 185c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // GCC union extension 186c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed QualType PtrTy = 18716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.getContext().getPointerType(E->getSubExpr()->getType()); 18816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr, 18916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.ConvertType(PtrTy)); 19016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitInitializationToLValue(E->getSubExpr(), 19116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed LValue::MakeAddr(CastPtr, Qualifiers()), 19216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed E->getType()); 193a79e534d42353d8e75b668f5e77b6f6357a08e07Saurabh Shah break; 194b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah } 195b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah 196b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah // FIXME: Remove the CK_Unknown check here. 197b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah case CastExpr::CK_Unknown: 198b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah case CastExpr::CK_NoOp: 199b5e3a690995208ad018a083456d6a05628300e92Saurabh Shah case CastExpr::CK_UserDefinedConversion: 20016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed case CastExpr::CK_ConstructorConversion: 201d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shah assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(), 20216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed E->getType()) && 20316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed "Implicit cast types must be compatible"); 20416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Visit(E->getSubExpr()); 20516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed break; 206d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shah 20716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed case CastExpr::CK_NullToMemberPointer: { 20816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed const llvm::Type *PtrDiffTy = 20916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.ConvertType(CGF.getContext().getPointerDiffType()); 21016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 21116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy); 21216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr"); 213d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shah Builder.CreateStore(NullValue, Ptr, VolatileDest); 214c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 215c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj"); 216c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Builder.CreateStore(NullValue, Adj, VolatileDest); 21716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 218c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed break; 219c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 22016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 22116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed case CastExpr::CK_BitCast: { 22216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // This must be a member function pointer cast. 223c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Visit(E->getSubExpr()); 224c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed break; 22516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 226c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 227c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed case CastExpr::CK_DerivedToBaseMemberPointer: 22816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed case CastExpr::CK_BaseToDerivedMemberPointer: { 229c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed QualType SrcType = E->getSubExpr()->getType(); 230c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 23116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp"); 232c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified()); 23316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 234c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr"); 235c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed SrcPtr = Builder.CreateLoad(SrcPtr); 236c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 237c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj"); 238c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed SrcAdj = Builder.CreateLoad(SrcAdj); 239c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 240c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr"); 241c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Builder.CreateStore(SrcPtr, DstPtr, VolatileDest); 242c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 243c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj"); 244c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 245c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Now See if we need to update the adjustment. 246c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const CXXRecordDecl *BaseDecl = 247c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()-> 248c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed getClass()->getAs<RecordType>()->getDecl()); 249c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const CXXRecordDecl *DerivedDecl = 250c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()-> 251c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed getClass()->getAs<RecordType>()->getDecl()); 252c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) 25316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed std::swap(DerivedDecl, BaseDecl); 254c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 2552e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah if (llvm::Constant *Adj = 25616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, BaseDecl)) { 25716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) 258c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj"); 259c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed else 260c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj"); 261c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 26216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 26316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Builder.CreateStore(SrcAdj, DstAdj, VolatileDest); 26416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed break; 26516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 26616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 2670114e85754fb37f4f0eb042fb682b41fd74aa4b5Naseer Ahmed} 2680114e85754fb37f4f0eb042fb682b41fd74aa4b5Naseer Ahmed 2690114e85754fb37f4f0eb042fb682b41fd74aa4b5Naseer Ahmedvoid AggExprEmitter::VisitCallExpr(const CallExpr *E) { 27016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (E->getCallReturnType()->isReferenceType()) { 27116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitAggLoadOfLValue(E); 27216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed return; 2736d41cb36a5f965bb6e5d6e0a6391f97ded56d39dSaurabh Shah } 274c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 275c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // If the struct doesn't require GC, we can just pass the destination 276c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // directly to EmitCall. 277c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (!RequiresGCollection) { 27816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest)); 279c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 280c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 281c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 282c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed RValue RV = CGF.EmitCallExpr(E); 283d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shah EmitFinalDestCopy(E, RV); 2842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah} 285d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shah 286d7dd5e35374e461d250dd8cc430a47624d6485c7Saurabh Shahvoid AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { 28716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RValue RV = CGF.EmitObjCMessageExpr(E); 28816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitFinalDestCopy(E, RV); 28916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 29016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 29116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 292c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed RValue RV = CGF.EmitObjCPropertyGet(E); 293c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitFinalDestCopy(E, RV); 294c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 295c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 296c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr( 29716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed ObjCImplicitSetterGetterRefExpr *E) { 29816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RValue RV = CGF.EmitObjCPropertyGet(E); 29916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitFinalDestCopy(E, RV); 300c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 30116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 30216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitBinComma(const BinaryOperator *E) { 30316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitAnyExpr(E->getLHS(), 0, false, true); 30416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest, 30516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed /*IgnoreResult=*/false, IsInitializer); 306c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 307c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 308c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) { 30916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // We have a member function pointer. 31016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); 31116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed (void) MPT; 312c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed assert(MPT->getPointeeType()->isFunctionProtoType() && 31316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed "Unexpected member pointer type!"); 31416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 31516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr()); 31616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed const CXXMethodDecl *MD = 31716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed cast<CXXMethodDecl>(DRE->getDecl())->getCanonicalDecl(); 31816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 319c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const llvm::Type *PtrDiffTy = 320c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.ConvertType(CGF.getContext().getPointerDiffType()); 32116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 32216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr"); 32316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *FuncPtr; 324c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 32516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (MD->isVirtual()) { 32616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed int64_t Index = 32716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.CGM.getVtableInfo().getMethodVtableIndex(MD); 32816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 329c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Itanium C++ ABI 2.3: 33016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // For a non-virtual function, this field is a simple function pointer. 33116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // For a virtual function, it is 1 plus the virtual table offset 33216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // (in bytes) of the function, represented as a ptrdiff_t. 33316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed FuncPtr = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1); 33416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } else { 335c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 336c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const llvm::Type *Ty = 33716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD), 3382e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah FPT->isVariadic()); 33916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty); 34016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy); 34116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 342c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Builder.CreateStore(FuncPtr, DstPtr, VolatileDest); 3432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah 344c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj"); 34516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 346c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // The adjustment will always be 0. 34716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr, 34816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed VolatileDest); 349c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 35016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 35116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitStmtExpr(const StmtExpr *E) { 35216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest); 35316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 35416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 35516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) { 35616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (E->getOpcode() == BinaryOperator::PtrMemD || 35716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed E->getOpcode() == BinaryOperator::PtrMemI) 35816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed VisitPointerToDataMemberBinaryOperator(E); 35916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed else 360c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.ErrorUnsupported(E, "aggregate binary expression"); 36116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 362c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 363c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitPointerToDataMemberBinaryOperator( 36416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed const BinaryOperator *E) { 36516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E); 36616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitFinalDestCopy(E, LV); 367c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 36816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 36916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { 37016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // For an assignment to work, the value on the right has 37116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // to be compatible with the value on the left. 37216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 37316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed E->getRHS()->getType()) 37416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed && "Invalid assignment"); 37516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed LValue LHS = CGF.EmitLValue(E->getLHS()); 37616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 377c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // We have to special case property setters, otherwise we must have 378c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // a simple lvalue (no aggregates inside vectors, bitfields). 379c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (LHS.isPropertyRef()) { 380c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *AggLoc = DestPtr; 381660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed if (!AggLoc) 382c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed AggLoc = CGF.CreateMemTemp(E->getRHS()->getType()); 3832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest); 384c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), 38516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RValue::getAggregate(AggLoc, VolatileDest)); 38616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } else if (LHS.isKVCRef()) { 387c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *AggLoc = DestPtr; 38816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!AggLoc) 38916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed AggLoc = CGF.CreateMemTemp(E->getRHS()->getType()); 39016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest); 391b2fa7edbf5150e6bdc25b1d37dfd5e14ad571ae9Naseer Ahmed CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), 392b2fa7edbf5150e6bdc25b1d37dfd5e14ad571ae9Naseer Ahmed RValue::getAggregate(AggLoc, VolatileDest)); 393c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } else { 394c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed bool RequiresGCollection = false; 395c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (CGF.getContext().getLangOptions().NeXTRuntime) { 396c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed QualType LHSTy = E->getLHS()->getType(); 397c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>()) 39816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RequiresGCollection = FDTTy->getDecl()->hasObjectMember(); 39916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 40016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // Codegen the RHS so that it stores directly into the LHS. 401c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(), 40216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed false, false, RequiresGCollection); 40316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitFinalDestCopy(E, LHS, true); 40416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 40516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 406c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 40716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) { 40816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!E->getLHS()) { 40916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.ErrorUnsupported(E, "conditional operator with missing LHS"); 410c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 41116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 41216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 41316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 414c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 415c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 416c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 417c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); 418c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 419c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.BeginConditionalBranch(); 420c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitBlock(LHSBlock); 421c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 422c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Handle the GNU extension for missing LHS. 423c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed assert(E->getLHS() && "Must have LHS for aggregate value"); 424c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 42516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Visit(E->getLHS()); 42616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EndConditionalBranch(); 427c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitBranch(ContBlock); 42816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 42916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.BeginConditionalBranch(); 430c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitBlock(RHSBlock); 43116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 43216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Visit(E->getRHS()); 433c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EndConditionalBranch(); 4341409b3ce70e0f46806c431eff4db4d9881598e05Naseer Ahmed CGF.EmitBranch(ContBlock); 43516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 43616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitBlock(ContBlock); 4371409b3ce70e0f46806c431eff4db4d9881598e05Naseer Ahmed} 438c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 439c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { 440c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Visit(CE->getChosenSubExpr(CGF.getContext())); 44116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 442c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 44316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { 44416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr()); 44516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType()); 446c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 447c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (!ArgPtr) { 448c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.ErrorUnsupported(VE, "aggregate va_arg expression"); 449c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 45016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 451c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 452c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers())); 45316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 45416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 45516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { 45616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *Val = DestPtr; 45716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 45816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!Val) { 459c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Create a temporary variable. 4602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah Val = CGF.CreateMemTemp(E->getType(), "tmp"); 4612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah 462c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // FIXME: volatile 463660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed CGF.EmitAggExpr(E->getSubExpr(), Val, false); 464c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } else 46516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Visit(E->getSubExpr()); 466c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 467c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Don't make this a live temporary if we're emitting an initializer expr. 468c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (!IsInitializer) 46916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.PushCXXTemporary(E->getTemporary(), Val); 47016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 471c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 472c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid 473c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer AhmedAggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) { 474c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *Val = DestPtr; 47516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 476c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (!Val) { 477c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Create a temporary variable. 47816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Val = CGF.CreateMemTemp(E->getType(), "tmp"); 479c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 480c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 481c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->requiresZeroInitialization()) 482c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitNullInitializationToLValue(LValue::MakeAddr(Val, 483c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // FIXME: Qualifiers()? 48416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed E->getType().getQualifiers()), 485c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed E->getType()); 486c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 487c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitCXXConstructExpr(Val, E); 488c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 489c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 490c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { 491c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *Val = DestPtr; 492c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 49316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!Val) { 494c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Create a temporary variable. 495c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Val = CGF.CreateMemTemp(E->getType(), "tmp"); 49616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 49716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer); 498c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 49916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 500c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmedvoid AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { 501c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *Val = DestPtr; 50216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 50316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!Val) { 50416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // Create a temporary variable. 50516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Val = CGF.CreateMemTemp(E->getType(), "tmp"); 506c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 50716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed LValue LV = LValue::MakeAddr(Val, Qualifiers()); 50816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitNullInitializationToLValue(LV, E->getType()); 50916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 51016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 51116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 51216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *Val = DestPtr; 51316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 51416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!Val) { 51516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // Create a temporary variable. 51616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed Val = CGF.CreateMemTemp(E->getType(), "tmp"); 51716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 51816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed LValue LV = LValue::MakeAddr(Val, Qualifiers()); 51916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitNullInitializationToLValue(LV, E->getType()); 52016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 52116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 52216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid 52316791f95b2570b9d48fa360875676e9c8559c0a1Naseer AhmedAggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) { 52416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // FIXME: Ignore result? 52516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // FIXME: Are initializers affected by volatile? 52616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (isa<ImplicitValueInitExpr>(E)) { 52716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitNullInitializationToLValue(LV, T); 52816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } else if (T->isReferenceType()) { 52916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false); 53016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitStoreThroughLValue(RV, LV, T); 531c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } else if (T->isAnyComplexType()) { 532c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); 533c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } else if (CGF.hasAggregateLLVMType(T)) { 53416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitAnyExpr(E, LV.getAddress(), false); 53516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } else { 53616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T); 53716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 53816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed} 53916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 54016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) { 54116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (!CGF.hasAggregateLLVMType(T)) { 542c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // For non-aggregates, we can store zero 54316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T)); 544c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T); 54516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } else { 54616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // Otherwise, just memset the whole thing to zero. This is legal 54716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // because in LLVM, all default initializers are guaranteed to have a 548c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // bit pattern of all zeros. 54916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // FIXME: That isn't true for member pointers! 55016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // There's a potential optimization opportunity in combining 55116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // memsets; that would be easy for arrays, but relatively 55216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // difficult for structures with the current code. 55316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed CGF.EmitMemSetToZero(LV.getAddress(), T); 55416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 555c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed} 556c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 55716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedvoid AggExprEmitter::VisitInitListExpr(InitListExpr *E) { 55816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed#if 0 55916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // FIXME: Assess perf here? Figure out what cases are worth optimizing here 56016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // (Length of globals? Chunks of zeroed-out space?). 56116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // 562c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // If we can, prefer a copy from a global; this is a lot less code for long 563c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // globals, and it's easier for the current optimizers to analyze. 564c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) { 565c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::GlobalVariable* GV = 566c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true, 567c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::GlobalValue::InternalLinkage, C, ""); 568c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers())); 569c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 570c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 571c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#endif 572c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->hadArrayRangeDesignator()) { 573c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed CGF.ErrorUnsupported(E, "GNU array range designator extension"); 574c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 575c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 576c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Handle initialization of an array. 577c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->getType()->isArrayType()) { 578c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const llvm::PointerType *APType = 579c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed cast<llvm::PointerType>(DestPtr->getType()); 580c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed const llvm::ArrayType *AType = 581c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed cast<llvm::ArrayType>(APType->getElementType()); 58216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 583c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed uint64_t NumInitElements = E->getNumInits(); 584c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 585c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->getNumInits() > 0) { 586c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed QualType T1 = E->getType(); 58716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed QualType T2 = E->getInit(0)->getType(); 58816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { 589c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitAggLoadOfLValue(E->getInit(0)); 590c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 59116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed } 592c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 593c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 594c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed uint64_t NumArrayElements = AType->getNumElements(); 59516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed QualType ElementType = CGF.getContext().getCanonicalType(E->getType()); 59616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType(); 59716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 59816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed // FIXME: were we intentionally ignoring address spaces and GC attributes? 599c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed Qualifiers Quals = CGF.MakeQualifiers(ElementType); 60016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed 601c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed for (uint64_t i = 0; i != NumArrayElements; ++i) { 602c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array"); 603c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (i < NumInitElements) 60416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed EmitInitializationToLValue(E->getInit(i), 605c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed LValue::MakeAddr(NextVal, Quals), 606c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed ElementType); 607c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed else 608c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals), 609c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed ElementType); 610c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 611c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed return; 612c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed } 613c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 614c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed assert(E->getType()->isRecordType() && "Only support structs/unions here!"); 615c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 616c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Do struct initialization; this code just sets each individual member 617c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // to the approprate value. This makes bitfield support automatic; 618c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // the disadvantage is that the generated code is more difficult for 619c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // the optimizer, especially with bitfields. 620c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed unsigned NumInitElements = E->getNumInits(); 62116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); 622c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed unsigned CurInitVal = 0; 623c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed 624c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed if (E->getType()->isUnionType()) { 625c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // Only initialize one field of a union. The field itself is 626c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed // specified by the initializer list. 627 if (!E->getInitializedFieldInUnion()) { 628 // Empty union; we have nothing to do. 629 630#ifndef NDEBUG 631 // Make sure that it's really an empty and not a failure of 632 // semantic analysis. 633 for (RecordDecl::field_iterator Field = SD->field_begin(), 634 FieldEnd = SD->field_end(); 635 Field != FieldEnd; ++Field) 636 assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); 637#endif 638 return; 639 } 640 641 // FIXME: volatility 642 FieldDecl *Field = E->getInitializedFieldInUnion(); 643 LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); 644 645 if (NumInitElements) { 646 // Store the initializer into the field 647 EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType()); 648 } else { 649 // Default-initialize to null 650 EmitNullInitializationToLValue(FieldLoc, Field->getType()); 651 } 652 653 return; 654 } 655 656 // Here we iterate over the fields; this makes it simpler to both 657 // default-initialize fields and skip over unnamed fields. 658 for (RecordDecl::field_iterator Field = SD->field_begin(), 659 FieldEnd = SD->field_end(); 660 Field != FieldEnd; ++Field) { 661 // We're done once we hit the flexible array member 662 if (Field->getType()->isIncompleteArrayType()) 663 break; 664 665 if (Field->isUnnamedBitfield()) 666 continue; 667 668 // FIXME: volatility 669 LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0); 670 // We never generate write-barries for initialized fields. 671 LValue::SetObjCNonGC(FieldLoc, true); 672 if (CurInitVal < NumInitElements) { 673 // Store the initializer into the field 674 EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, 675 Field->getType()); 676 } else { 677 // We're out of initalizers; default-initialize to null 678 EmitNullInitializationToLValue(FieldLoc, Field->getType()); 679 } 680 } 681} 682 683//===----------------------------------------------------------------------===// 684// Entry Points into this File 685//===----------------------------------------------------------------------===// 686 687/// EmitAggExpr - Emit the computation of the specified expression of aggregate 688/// type. The result is computed into DestPtr. Note that if DestPtr is null, 689/// the value of the aggregate expression is not needed. If VolatileDest is 690/// true, DestPtr cannot be 0. 691// 692// FIXME: Take Qualifiers object. 693void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr, 694 bool VolatileDest, bool IgnoreResult, 695 bool IsInitializer, 696 bool RequiresGCollection) { 697 assert(E && hasAggregateLLVMType(E->getType()) && 698 "Invalid aggregate expression to emit"); 699 assert ((DestPtr != 0 || VolatileDest == false) 700 && "volatile aggregate can't be 0"); 701 702 AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer, 703 RequiresGCollection) 704 .Visit(const_cast<Expr*>(E)); 705} 706 707LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { 708 assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!"); 709 Qualifiers Q = MakeQualifiers(E->getType()); 710 llvm::Value *Temp = CreateMemTemp(E->getType()); 711 EmitAggExpr(E, Temp, Q.hasVolatile()); 712 return LValue::MakeAddr(Temp, Q); 713} 714 715void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) { 716 assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); 717 718 EmitMemSetToZero(DestPtr, Ty); 719} 720 721void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, 722 llvm::Value *SrcPtr, QualType Ty, 723 bool isVolatile) { 724 assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); 725 726 // Aggregate assignment turns into llvm.memcpy. This is almost valid per 727 // C99 6.5.16.1p3, which states "If the value being stored in an object is 728 // read from another object that overlaps in anyway the storage of the first 729 // object, then the overlap shall be exact and the two objects shall have 730 // qualified or unqualified versions of a compatible type." 731 // 732 // memcpy is not defined if the source and destination pointers are exactly 733 // equal, but other compilers do this optimization, and almost every memcpy 734 // implementation handles this case safely. If there is a libc that does not 735 // safely handle this, we can add a target hook. 736 const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); 737 if (DestPtr->getType() != BP) 738 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp"); 739 if (SrcPtr->getType() != BP) 740 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp"); 741 742 // Get size and alignment info for this aggregate. 743 std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); 744 745 // FIXME: Handle variable sized types. 746 const llvm::Type *IntPtr = 747 llvm::IntegerType::get(VMContext, LLVMPointerWidth); 748 749 // FIXME: If we have a volatile struct, the optimizer can remove what might 750 // appear to be `extra' memory ops: 751 // 752 // volatile struct { int i; } a, b; 753 // 754 // int main() { 755 // a = b; 756 // a = b; 757 // } 758 // 759 // we need to use a differnt call here. We use isVolatile to indicate when 760 // either the source or the destination is volatile. 761 Builder.CreateCall4(CGM.getMemCpyFn(), 762 DestPtr, SrcPtr, 763 // TypeInfo.first describes size in bits. 764 llvm::ConstantInt::get(IntPtr, TypeInfo.first/8), 765 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 766 TypeInfo.second/8)); 767} 768