CGExprAgg.cpp revision cd940a1e13e588a43973cd7ae33b5c33a3062739
1566b6ce741c742cc3f8cb85e2376ec4a3490ff5fChris Lattner//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
2af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//
3af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//                     The LLVM Compiler Infrastructure
4af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
7af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//
8af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//===----------------------------------------------------------------------===//
9af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//
10af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner// This contains code to emit Aggregate Expr nodes as LLVM code.
11af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//
12af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner//===----------------------------------------------------------------------===//
13af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner
14af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattner#include "CodeGenFunction.h"
15883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner#include "CodeGenModule.h"
16082b02e8403d3ee9d2ded969fbe0e5d472f04cd8Fariborz Jahanian#include "CGObjCRuntime.h"
17de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/ASTContext.h"
18b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson#include "clang/AST/DeclCXX.h"
19de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/StmtVisitor.h"
20883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner#include "llvm/Constants.h"
21883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner#include "llvm/Function.h"
22636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel#include "llvm/GlobalVariable.h"
23f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner#include "llvm/Intrinsics.h"
24af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattnerusing namespace clang;
25af6f528b2bd6c3ee517e02d346238addb74159ccChris Lattnerusing namespace CodeGen;
26883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
279c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner//===----------------------------------------------------------------------===//
289c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner//                        Aggregate Expression Emitter
299c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner//===----------------------------------------------------------------------===//
309c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
319c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnernamespace  {
3285b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramerclass AggExprEmitter : public StmtVisitor<AggExprEmitter> {
339c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  CodeGenFunction &CGF;
3445d196b8387dcefc4df26cda114fa34c6528e928Daniel Dunbar  CGBuilderTy &Builder;
35558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Dest;
3649d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  bool IgnoreResult;
37ef072fd2f3347cfd857d6eb787b245b950771430John McCall
38ef072fd2f3347cfd857d6eb787b245b950771430John McCall  ReturnValueSlot getReturnValueSlot() const {
39fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    // If the destination slot requires garbage collection, we can't
40fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    // use the real return value slot, because we have to use the GC
41fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    // API.
42d1a5f13140a5bfcf9107b28de906518d2313fdf0John McCall    if (Dest.requiresGCollection()) return ReturnValueSlot();
43fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
44558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
45558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  }
46558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
47558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot EnsureSlot(QualType T) {
48558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    if (!Dest.isIgnored()) return Dest;
49558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    return CGF.CreateAggTemp(T, "agg.tmp.ensured");
50ef072fd2f3347cfd857d6eb787b245b950771430John McCall  }
51fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
529c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnerpublic:
53558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
54474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian                 bool ignore)
55558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
56474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian      IgnoreResult(ignore) {
579c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  }
589c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
59ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
60ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //                               Utilities
61ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
62ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
639c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// EmitAggLoadOfLValue - Given an expression with aggregate type that
649c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// represents a value lvalue, this method emits the address of the lvalue,
659c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// then loads the result into DestPtr.
669c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void EmitAggLoadOfLValue(const Expr *E);
67922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
684ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
6949d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
7049d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
714ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
72fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  void EmitGCMove(const Expr *E, RValue Src);
73fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
74fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  bool TypeRequiresGCollection(QualType T);
75fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
76ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
77ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //                            Visitor Methods
78ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
809c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitStmt(Stmt *S) {
81488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar    CGF.ErrorUnsupported(S, "aggregate expression");
829c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  }
839c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
8412444a24419fe88b42a16b46106db3c11ac5cd35Eli Friedman  void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
859c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
869c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  // l-values.
879b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
889b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
899b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
905be028f84243e0f6906c259e67cbdaf9bee431b2Daniel Dunbar  void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
91f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitAggLoadOfLValue(E);
93f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  }
949b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
959b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon    EmitAggLoadOfLValue(E);
969b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  }
97f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitAggLoadOfLValue(E);
99f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  }
100f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  void VisitPredefinedExpr(const PredefinedExpr *E) {
1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitAggLoadOfLValue(E);
102f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  }
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1049c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  // Operators.
1054d8673b645ad86e496b886a0f80b60763f67071dAnders Carlsson  void VisitCastExpr(CastExpr *E);
106148fe6772733166c720e28b7bb5084af6e624b44Anders Carlsson  void VisitCallExpr(const CallExpr *E);
107b2d963f527674275c9109252474948368b6e6161Chris Lattner  void VisitStmtExpr(const StmtExpr *E);
1089c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitBinaryOperator(const BinaryOperator *BO);
1098bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
11003d6fb99224c36935c9af9f4785cb33453c99b2bChris Lattner  void VisitBinAssign(const BinaryOperator *E);
11107fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman  void VisitBinComma(const BinaryOperator *E);
1129c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
1138fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  void VisitObjCMessageExpr(ObjCMessageExpr *E);
1140a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
1150a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar    EmitAggLoadOfLValue(E);
1160a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar  }
1179c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1199c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitConditionalOperator(const ConditionalOperator *CO);
120a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson  void VisitChooseExpr(const ChooseExpr *CE);
121636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel  void VisitInitListExpr(InitListExpr *E);
12230311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson  void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
12304421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
12404421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner    Visit(DAE->getExpr());
12504421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner  }
126b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson  void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
12731ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson  void VisitCXXConstructExpr(const CXXConstructExpr *E);
1287f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson  void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
129ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
1302710c4159ff4761ba9867aca18f60a178b297686Mike Stump  void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
1317f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson
132b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman  void VisitVAArgExpr(VAArgExpr *E);
133f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner
13478e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson  void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
135f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  void EmitNullInitializationToLValue(LValue Address, QualType T);
1369c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  //  case Expr::ChooseExprClass:
13739406b1395f69341c045e863a6620310abdc55b6Mike Stump  void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
1389c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner};
1399c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner}  // end anonymous namespace.
1409c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
141ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
142ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                                Utilities
143ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
1449c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
145883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// EmitAggLoadOfLValue - Given an expression with aggregate type that
146883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// represents a value lvalue, this method emits the address of the lvalue,
147883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// then loads the result into DestPtr.
1489c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnervoid AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
1499c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  LValue LV = CGF.EmitLValue(E);
1504ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  EmitFinalDestCopy(E, LV);
1514ac20ddc7ab324a59862657f756bdd060076b137Mike Stump}
1524ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
153fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// \brief True if the given aggregate type requires special GC API calls.
154fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCallbool AggExprEmitter::TypeRequiresGCollection(QualType T) {
155fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Only record types have members that might require garbage collection.
156fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  const RecordType *RecordTy = T->getAs<RecordType>();
157fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  if (!RecordTy) return false;
158fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
159fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Don't mess with non-trivial C++ types.
160fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RecordDecl *Record = RecordTy->getDecl();
161fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  if (isa<CXXRecordDecl>(Record) &&
162fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall      (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() ||
163fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall       !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
164fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    return false;
165fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
166fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Check whether the type has an object member.
167fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  return Record->hasObjectMember();
168fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall}
169fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
170fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// \brief Perform the final move to DestPtr if RequiresGCollection is set.
171fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall///
172fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// The idea is that you do something like this:
173fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall///   RValue Result = EmitSomething(..., getReturnValueSlot());
174fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall///   EmitGCMove(E, Result);
175fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// If GC doesn't interfere, this will cause the result to be emitted
176fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// directly into the return value slot.  If GC does interfere, a final
177fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// move will be performed.
178fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCallvoid AggExprEmitter::EmitGCMove(const Expr *E, RValue Src) {
179d1a5f13140a5bfcf9107b28de906518d2313fdf0John McCall  if (Dest.requiresGCollection()) {
18055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    std::pair<uint64_t, unsigned> TypeInfo =
18155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      CGF.getContext().getTypeInfo(E->getType());
18255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    unsigned long size = TypeInfo.first/8;
18355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
18455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
185558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, Dest.getAddr(),
186fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall                                                    Src.getAggregateAddr(),
18755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                                    SizeVal);
18855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  }
189fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall}
190fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
1914ac20ddc7ab324a59862657f756bdd060076b137Mike Stump/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
19249d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stumpvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
1934ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  assert(Src.isAggregate() && "value must be aggregate value!");
1944ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
195558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // If Dest is ignored, then we're evaluating an aggregate expression
196a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // in a context (like an expression statement) that doesn't care
197a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // about the result.  C says that an lvalue-to-rvalue conversion is
198a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // performed in these cases; C++ says that it is not.  In either
199a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // case, we don't actually need to do anything unless the value is
200a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // volatile.
201558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  if (Dest.isIgnored()) {
202a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall    if (!Src.isVolatileQualified() ||
203a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall        CGF.CGM.getLangOptions().CPlusPlus ||
204a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall        (IgnoreResult && Ignore))
2059ccb103c6f777fc42343b23b19a8c2c9a740e6e8Mike Stump      return;
2068a97005f97a2a93fc2cd942c040668c5d4df7537Fariborz Jahanian
20749d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    // If the source is volatile, we must read from it; to do that, we need
20849d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    // some place to put it.
209558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
2109ccb103c6f777fc42343b23b19a8c2c9a740e6e8Mike Stump  }
211883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
212d1a5f13140a5bfcf9107b28de906518d2313fdf0John McCall  if (Dest.requiresGCollection()) {
21355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    std::pair<uint64_t, unsigned> TypeInfo =
21455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    CGF.getContext().getTypeInfo(E->getType());
21555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    unsigned long size = TypeInfo.first/8;
21655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
21755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
21808c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
219558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      Dest.getAddr(),
220558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      Src.getAggregateAddr(),
221558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      SizeVal);
22208c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian    return;
22308c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian  }
2244ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // If the result of the assignment is used, copy the LHS there also.
2254ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
2264ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // from the source as well, as we can't eliminate it if either operand
2274ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // is volatile, unless copy has volatile for both source and destination..
228558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(),
229558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                        Dest.isVolatile()|Src.isVolatileQualified());
2304ac20ddc7ab324a59862657f756bdd060076b137Mike Stump}
2314ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
2324ac20ddc7ab324a59862657f756bdd060076b137Mike Stump/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
23349d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stumpvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
2344ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
2354ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
2364ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
23749d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump                                            Src.isVolatileQualified()),
23849d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump                    Ignore);
239883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
240883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
241ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
242ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                            Visitor Methods
243ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
244ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
2454d8673b645ad86e496b886a0f80b60763f67071dAnders Carlssonvoid AggExprEmitter::VisitCastExpr(CastExpr *E) {
246558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  if (Dest.isIgnored() && E->getCastKind() != CK_Dynamic) {
2474ce46c2db2b17ef52b34dbeeec01e448025c8edcDouglas Gregor    Visit(E->getSubExpr());
2484ce46c2db2b17ef52b34dbeeec01e448025c8edcDouglas Gregor    return;
2494ce46c2db2b17ef52b34dbeeec01e448025c8edcDouglas Gregor  }
2504ce46c2db2b17ef52b34dbeeec01e448025c8edcDouglas Gregor
2513016842613674ab80796567239c15d529aff1458Anders Carlsson  switch (E->getCastKind()) {
2522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_Dynamic: {
25369cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
25469cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
25569cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    // FIXME: Do we also need to handle property references here?
25669cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    if (LV.isSimple())
25769cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor      CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
25869cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    else
25969cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor      CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
26069cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor
261558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    if (!Dest.isIgnored())
262558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall      CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
26369cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    break;
26469cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor  }
26569cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor
2662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_ToUnion: {
2674d8673b645ad86e496b886a0f80b60763f67071dAnders Carlsson    // GCC union extension
26879c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    QualType Ty = E->getSubExpr()->getType();
26979c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    QualType PtrTy = CGF.getContext().getPointerType(Ty);
270558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
27134ebf4d1767e6748a1a59a5d1935c495cd8877e8Eli Friedman                                                 CGF.ConvertType(PtrTy));
27279c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty),
27379c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar                               Ty);
2743016842613674ab80796567239c15d529aff1458Anders Carlsson    break;
2757e91627301b05cd8f2324795e19d87a62f444c31Nuno Lopes  }
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_DerivedToBase:
2782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_BaseToDerived:
2792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_UncheckedDerivedToBase: {
2802d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor    assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: "
2812d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor                "should have been unpacked before we got here");
2822d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor    break;
2832d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  }
2842d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor
285f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  case CK_GetObjCProperty: {
286f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    LValue LV = CGF.EmitLValue(E->getSubExpr());
287f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    assert(LV.isPropertyRef());
288f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot());
289f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    EmitGCMove(E, RV);
290f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    break;
291f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  }
292f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
293f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  case CK_LValueToRValue: // hope for downstream optimization
2942de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_NoOp:
2952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_UserDefinedConversion:
2962de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_ConstructorConversion:
2973016842613674ab80796567239c15d529aff1458Anders Carlsson    assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
2983016842613674ab80796567239c15d529aff1458Anders Carlsson                                                   E->getType()) &&
2993016842613674ab80796567239c15d529aff1458Anders Carlsson           "Implicit cast types must be compatible");
3003016842613674ab80796567239c15d529aff1458Anders Carlsson    Visit(E->getSubExpr());
3013016842613674ab80796567239c15d529aff1458Anders Carlsson    break;
3020ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall
3032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_LValueBitCast:
3040ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall    llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
305e39a3894513349908cdb3beba2614e53cb288e6cDouglas Gregor    break;
3060ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall
3070ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_Dependent:
3080ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_BitCast:
3090ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ArrayToPointerDecay:
3100ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FunctionToPointerDecay:
3110ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_NullToPointer:
3120ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_NullToMemberPointer:
3130ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_BaseToDerivedMemberPointer:
3140ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_DerivedToBaseMemberPointer:
3150ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_MemberPointerToBoolean:
3160ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToPointer:
3170ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_PointerToIntegral:
3180ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_PointerToBoolean:
3190ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ToVoid:
3200ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_VectorSplat:
3210ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralCast:
3220ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToBoolean:
3230ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToFloating:
3240ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingToIntegral:
3250ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingToBoolean:
3260ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingCast:
3270ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_AnyPointerToObjCPointerCast:
3280ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_AnyPointerToBlockPointerCast:
3290ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ObjCObjectLValueCast:
3300ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingRealToComplex:
3310ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToReal:
3320ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToBoolean:
3330ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexCast:
3340ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToIntegralComplex:
3350ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralRealToComplex:
3360ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToReal:
3370ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToBoolean:
3380ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexCast:
3390ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToFloatingComplex:
3400ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall    llvm_unreachable("cast kind invalid for aggregate types");
3413016842613674ab80796567239c15d529aff1458Anders Carlsson  }
342e4707ff0bb48add651c6a1ad9acfcb22609462d1Anders Carlsson}
343e4707ff0bb48add651c6a1ad9acfcb22609462d1Anders Carlsson
3449619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitCallExpr(const CallExpr *E) {
345e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson  if (E->getCallReturnType()->isReferenceType()) {
346e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson    EmitAggLoadOfLValue(E);
347e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson    return;
348e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson  }
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
350fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot());
351fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  EmitGCMove(E, RV);
352796ef3d4a32ce8d9e76df0d5bcab07db97883064Nate Begeman}
3539619662a1d42e2008b865d3459c0677e149dad1bChris Lattner
3549619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
355fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
356fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  EmitGCMove(E, RV);
3578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
358796ef3d4a32ce8d9e76df0d5bcab07db97883064Nate Begeman
3599c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbarvoid AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
360f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  llvm_unreachable("direct property access not surrounded by "
361f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall                   "lvalue-to-rvalue cast");
3625daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian}
3635daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian
3649619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
3652a41637a995affa1563f4d82a8b026e326a2faa0John McCall  CGF.EmitIgnoredExpr(E->getLHS());
366558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Visit(E->getRHS());
36707fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman}
36807fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman
369b2d963f527674275c9109252474948368b6e6161Chris Lattnervoid AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
370558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest);
371b2d963f527674275c9109252474948368b6e6161Chris Lattner}
372b2d963f527674275c9109252474948368b6e6161Chris Lattner
3739c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnervoid AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
3742de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)
3758bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian    VisitPointerToDataMemberBinaryOperator(E);
3768bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  else
3778bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian    CGF.ErrorUnsupported(E, "aggregate binary expression");
3788bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian}
3798bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian
3808bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanianvoid AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
3818bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian                                                    const BinaryOperator *E) {
3828bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
3838bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  EmitFinalDestCopy(E, LV);
384ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner}
385ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
38603d6fb99224c36935c9af9f4785cb33453c99b2bChris Lattnervoid AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
387ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman  // For an assignment to work, the value on the right has
388ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman  // to be compatible with the value on the left.
3892dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
3902dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman                                                 E->getRHS()->getType())
391ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman         && "Invalid assignment");
392cd940a1e13e588a43973cd7ae33b5c33a3062739John McCall
393cd940a1e13e588a43973cd7ae33b5c33a3062739John McCall  // FIXME:  __block variables need the RHS evaluated first!
3949c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  LValue LHS = CGF.EmitLValue(E->getLHS());
395883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
3967f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  // We have to special case property setters, otherwise we must have
3977f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  // a simple lvalue (no aggregates inside vectors, bitfields).
3987f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  if (LHS.isPropertyRef()) {
399558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
400558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    CGF.EmitAggExpr(E->getRHS(), Slot);
401119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    CGF.EmitStoreThroughPropertyRefLValue(Slot.asRValue(), LHS);
4027f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  } else {
403474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian    bool GCollection = false;
404fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    if (CGF.getContext().getLangOptions().getGCMode())
405474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian      GCollection = TypeRequiresGCollection(E->getLHS()->getType());
406fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
4077f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar    // Codegen the RHS so that it stores directly into the LHS.
408474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true,
409474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian                                                   GCollection);
410474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
41149d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    EmitFinalDestCopy(E, LHS, true);
4127f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  }
413883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
414883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
4159c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnervoid AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
4168e274bd14bcca8466542477844b88e90e90cde1aEli Friedman  if (!E->getLHS()) {
4178e274bd14bcca8466542477844b88e90e90cde1aEli Friedman    CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
4188e274bd14bcca8466542477844b88e90e90cde1aEli Friedman    return;
4198e274bd14bcca8466542477844b88e90e90cde1aEli Friedman  }
4208e274bd14bcca8466542477844b88e90e90cde1aEli Friedman
4219615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
4229615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
4239615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4258e274bd14bcca8466542477844b88e90e90cde1aEli Friedman  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42772119a887c4af39c90f10b6bdc158389071f42eaAnders Carlsson  CGF.BeginConditionalBranch();
4289c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  CGF.EmitBlock(LHSBlock);
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43074fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // Save whether the destination's lifetime is externally managed.
43174fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  bool DestLifetimeManaged = Dest.isLifetimeExternallyManaged();
432883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
433c748f27f4055f5732a3c231f31dc7325c5279020Chris Lattner  Visit(E->getLHS());
43472119a887c4af39c90f10b6bdc158389071f42eaAnders Carlsson  CGF.EndConditionalBranch();
435d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar  CGF.EmitBranch(ContBlock);
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43772119a887c4af39c90f10b6bdc158389071f42eaAnders Carlsson  CGF.BeginConditionalBranch();
4389c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  CGF.EmitBlock(RHSBlock);
4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44074fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // If the result of an agg expression is unused, then the emission
44174fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // of the LHS might need to create a destination slot.  That's fine
44274fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // with us, and we can safely emit the RHS into the same slot, but
44374fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // we shouldn't claim that its lifetime is externally managed.
44474fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  Dest.setLifetimeExternallyManaged(DestLifetimeManaged);
44574fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall
446c748f27f4055f5732a3c231f31dc7325c5279020Chris Lattner  Visit(E->getRHS());
44772119a887c4af39c90f10b6bdc158389071f42eaAnders Carlsson  CGF.EndConditionalBranch();
448d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar  CGF.EmitBranch(ContBlock);
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4509c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  CGF.EmitBlock(ContBlock);
451883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
452ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
453a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlssonvoid AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
454a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson  Visit(CE->getChosenSubExpr(CGF.getContext()));
455a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson}
456a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson
457b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedmanvoid AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
4580785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar  llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
459ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
460ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
4610262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl  if (!ArgPtr) {
462ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
4630262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl    return;
4640262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl  }
4650262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl
46679c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType()));
467b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman}
468b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman
469b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlssonvoid AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
470558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // Ensure that we have a slot, but if we already do, remember
471558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // whether its lifetime was externally managed.
472558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  bool WasManaged = Dest.isLifetimeExternallyManaged();
473558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Dest = EnsureSlot(E->getType());
474558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Dest.setLifetimeExternallyManaged();
475558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
476558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Visit(E->getSubExpr());
477558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
478558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // Set up the temporary's destructor if its lifetime wasn't already
479558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // being managed.
480558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  if (!WasManaged)
481558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    CGF.EmitCXXTemporary(E->getTemporary(), Dest.getAddr());
482b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson}
483b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson
484b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
48531ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonAggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
486558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(E->getType());
487558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitCXXConstructExpr(E, Slot);
4887f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson}
4897f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson
4907f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlssonvoid AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
491558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitCXXExprWithTemporaries(E, Dest);
492b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
493b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
494ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregorvoid AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
495558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  QualType T = E->getType();
496558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(T);
497558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
49830311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson}
49930311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson
50030311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlssonvoid AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
501558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  QualType T = E->getType();
502558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(T);
503558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
504329763b1e9ec8c216025e3a8379ed446d7372cbcNuno Lopes}
505329763b1e9ec8c216025e3a8379ed446d7372cbcNuno Lopes
5061b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// isSimpleZero - If emitting this value will obviously just cause a store of
5071b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// zero to memory, return true.  This can return false if uncertain, so it just
5081b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// handles simple cases.
5091b726771d00762fb5c4c2638e60d134c385493aeChris Lattnerstatic bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) {
5101b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // (0)
5111b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
5121b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return isSimpleZero(PE->getSubExpr(), CGF);
5131b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // 0
5141b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
5151b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return IL->getValue() == 0;
5161b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // +0.0
5171b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E))
5181b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return FL->getValue().isPosZero();
5191b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // int()
5201b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) &&
5211b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      CGF.getTypes().isZeroInitializable(E->getType()))
5221b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return true;
5231b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // (int*)0 - Null pointer expressions.
5241b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
5251b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return ICE->getCastKind() == CK_NullToPointer;
5261b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // '\0'
5271b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
5281b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return CL->getValue() == 0;
5291b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
5301b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Otherwise, hard case: conservatively return false.
5311b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  return false;
5321b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
5331b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
5341b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
53578e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlssonvoid
53678e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders CarlssonAggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
5377f79f9be5916c51c35da4f126b7c12596a101607Mike Stump  // FIXME: Ignore result?
538f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // FIXME: Are initializers affected by volatile?
5391b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (Dest.isZeroed() && isSimpleZero(E, CGF)) {
5401b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // Storing "i32 0" to a zero'd memory location is a noop.
5411b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  } else if (isa<ImplicitValueInitExpr>(E)) {
54278e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson    EmitNullInitializationToLValue(LV, T);
543e78ccb4d609a113c3e06a9c4583e845e90b1a037Anders Carlsson  } else if (T->isReferenceType()) {
54432f36baa6c8d491c374af622b4e3ac28d597453cAnders Carlsson    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
545e78ccb4d609a113c3e06a9c4583e845e90b1a037Anders Carlsson    CGF.EmitStoreThroughLValue(RV, LV, T);
54678e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson  } else if (T->isAnyComplexType()) {
5473498bdb9e9cb300de74c7b51c92608e2902b2348Douglas Gregor    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
54878e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson  } else if (CGF.hasAggregateLLVMType(T)) {
5491b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    CGF.EmitAggExpr(E, AggValueSlot::forAddr(LV.getAddress(), false, true,
5501b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                                             false, Dest.isZeroed()));
551c8ba9614ca5469c3ae259e3ec09792f4b8969397Eli Friedman  } else {
5522a41637a995affa1563f4d82a8b026e326a2faa0John McCall    CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, T);
553f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
554f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner}
555305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio
556f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattnervoid AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
5571b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the destination slot is already zeroed out before the aggregate is
5581b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // copied into it, we don't have to emit any zeros here.
5591b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(T))
5601b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
5611b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
562f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  if (!CGF.hasAggregateLLVMType(T)) {
563f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // For non-aggregates, we can store zero
564c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
56582397139c47a41675ab337290f6dca7644e541d5Daniel Dunbar    CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
566f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  } else {
567f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // There's a potential optimization opportunity in combining
568f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // memsets; that would be easy for arrays, but relatively
569f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // difficult for structures with the current code.
5701884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson    CGF.EmitNullInitialization(LV.getAddress(), T);
571f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
572f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner}
573305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio
574f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattnervoid AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
575a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman#if 0
57613a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
57713a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  // (Length of globals? Chunks of zeroed-out space?).
578a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman  //
579f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // If we can, prefer a copy from a global; this is a lot less code for long
580f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // globals, and it's easier for the current optimizers to analyze.
58113a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
582994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman    llvm::GlobalVariable* GV =
58313a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
58413a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman                             llvm::GlobalValue::InternalLinkage, C, "");
58579c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
586994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman    return;
587994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman  }
588a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman#endif
589d0db03a561671b8b466b07026cc8fbbb037bb639Chris Lattner  if (E->hadArrayRangeDesignator())
590a9c878086036de36482cc21e35a33cabe9699b0aDouglas Gregor    CGF.ErrorUnsupported(E, "GNU array range designator extension");
591a9c878086036de36482cc21e35a33cabe9699b0aDouglas Gregor
592558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  llvm::Value *DestPtr = Dest.getAddr();
593558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
594f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Handle initialization of an array.
595f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  if (E->getType()->isArrayType()) {
596f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    const llvm::PointerType *APType =
597f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      cast<llvm::PointerType>(DestPtr->getType());
598f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    const llvm::ArrayType *AType =
599f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      cast<llvm::ArrayType>(APType->getElementType());
6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
601f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    uint64_t NumInitElements = E->getNumInits();
602922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
6039619662a1d42e2008b865d3459c0677e149dad1bChris Lattner    if (E->getNumInits() > 0) {
6049619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      QualType T1 = E->getType();
6059619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      QualType T2 = E->getInit(0)->getType();
6062dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
6079619662a1d42e2008b865d3459c0677e149dad1bChris Lattner        EmitAggLoadOfLValue(E->getInit(0));
6089619662a1d42e2008b865d3459c0677e149dad1bChris Lattner        return;
6099619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      }
610922696f03ec9637449e2cba260493808b4977cd3Eli Friedman    }
611922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
612f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    uint64_t NumArrayElements = AType->getNumElements();
613c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner    QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
6144c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    // FIXME: were we intentionally ignoring address spaces and GC attributes?
6171e692ace08959399794363e77499b73da5494af9Eli Friedman
618f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    for (uint64_t i = 0; i != NumArrayElements; ++i) {
6191b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // If we're done emitting initializers and the destination is known-zeroed
6201b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // then we're done.
6211b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      if (i == NumInitElements &&
6221b726771d00762fb5c4c2638e60d134c385493aeChris Lattner          Dest.isZeroed() &&
6231b726771d00762fb5c4c2638e60d134c385493aeChris Lattner          CGF.getTypes().isZeroInitializable(ElementType))
6241b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        break;
6251b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
626f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
6279f553f5b3bd45304dfda6bdc5cd2baac64b3315bDaniel Dunbar      LValue LV = CGF.MakeAddrLValue(NextVal, ElementType);
6281b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
629f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      if (i < NumInitElements)
6309f553f5b3bd45304dfda6bdc5cd2baac64b3315bDaniel Dunbar        EmitInitializationToLValue(E->getInit(i), LV, ElementType);
631f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      else
6329f553f5b3bd45304dfda6bdc5cd2baac64b3315bDaniel Dunbar        EmitNullInitializationToLValue(LV, ElementType);
6331b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
6341b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // If the GEP didn't get used because of a dead zero init or something
6351b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // else, clean it up for -O0 builds and general tidiness.
6361b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      if (llvm::GetElementPtrInst *GEP =
6371b726771d00762fb5c4c2638e60d134c385493aeChris Lattner            dyn_cast<llvm::GetElementPtrInst>(NextVal))
6381b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        if (GEP->use_empty())
6391b726771d00762fb5c4c2638e60d134c385493aeChris Lattner          GEP->eraseFromParent();
640f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    }
641305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio    return;
642f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
644f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  assert(E->getType()->isRecordType() && "Only support structs/unions here!");
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
646f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Do struct initialization; this code just sets each individual member
647f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // to the approprate value.  This makes bitfield support automatic;
648f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // the disadvantage is that the generated code is more difficult for
649f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // the optimizer, especially with bitfields.
650f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  unsigned NumInitElements = E->getNumInits();
6516217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
652bd7de38eae1fc20ee88db63f469c54241bc240f8Chris Lattner
6530bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor  if (E->getType()->isUnionType()) {
6540bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // Only initialize one field of a union. The field itself is
6550bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // specified by the initializer list.
6560bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    if (!E->getInitializedFieldInUnion()) {
6570bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Empty union; we have nothing to do.
6581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6590bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor#ifndef NDEBUG
6600bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Make sure that it's really an empty and not a failure of
6610bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // semantic analysis.
66217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      for (RecordDecl::field_iterator Field = SD->field_begin(),
66317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                                   FieldEnd = SD->field_end();
6640bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor           Field != FieldEnd; ++Field)
6650bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
6660bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor#endif
6670bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      return;
6680bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    }
6690bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
6700bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // FIXME: volatility
6710bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    FieldDecl *Field = E->getInitializedFieldInUnion();
6720bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
6731b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
6740bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    if (NumInitElements) {
6750bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Store the initializer into the field
67678e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson      EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
6770bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    } else {
6781b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // Default-initialize to null.
6790bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      EmitNullInitializationToLValue(FieldLoc, Field->getType());
6800bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    }
6810bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
6820bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    return;
6830bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor  }
6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
685f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Here we iterate over the fields; this makes it simpler to both
686f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // default-initialize fields and skip over unnamed fields.
687bd7de38eae1fc20ee88db63f469c54241bc240f8Chris Lattner  unsigned CurInitVal = 0;
68817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (RecordDecl::field_iterator Field = SD->field_begin(),
68917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                               FieldEnd = SD->field_end();
69044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Field != FieldEnd; ++Field) {
69144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We're done once we hit the flexible array member
69244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Field->getType()->isIncompleteArrayType())
69344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      break;
69444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
69534e7946831a63f96d3ba3478c74ca8e25ee52d7eDouglas Gregor    if (Field->isUnnamedBitfield())
696f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      continue;
69734e7946831a63f96d3ba3478c74ca8e25ee52d7eDouglas Gregor
6981b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // Don't emit GEP before a noop store of zero.
6991b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    if (CurInitVal == NumInitElements && Dest.isZeroed() &&
7001b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        CGF.getTypes().isZeroInitializable(E->getType()))
7011b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      break;
7021b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7031e692ace08959399794363e77499b73da5494af9Eli Friedman    // FIXME: volatility
704e78ccb4d609a113c3e06a9c4583e845e90b1a037Anders Carlsson    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
70514674ffb81dccbc4e1bf78ab5b7987685819b445Fariborz Jahanian    // We never generate write-barries for initialized fields.
706ea619177353e0a9f35b7d926a92df0e103515dbeDaniel Dunbar    FieldLoc.setNonGC(true);
7071b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
708f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    if (CurInitVal < NumInitElements) {
709b35baae19b906245b5c2266b47ef411abcc6b25aChris Lattner      // Store the initializer into the field.
710b35baae19b906245b5c2266b47ef411abcc6b25aChris Lattner      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
71178e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlsson                                 Field->getType());
712f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    } else {
713f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      // We're out of initalizers; default-initialize to null
71444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      EmitNullInitializationToLValue(FieldLoc, Field->getType());
715f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    }
7161b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7171b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // If the GEP didn't get used because of a dead zero init or something
7181b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // else, clean it up for -O0 builds and general tidiness.
7191b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    if (FieldLoc.isSimple())
7201b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      if (llvm::GetElementPtrInst *GEP =
7211b726771d00762fb5c4c2638e60d134c385493aeChris Lattner            dyn_cast<llvm::GetElementPtrInst>(FieldLoc.getAddress()))
7221b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        if (GEP->use_empty())
7231b726771d00762fb5c4c2638e60d134c385493aeChris Lattner          GEP->eraseFromParent();
724145cd89f9233d375381aa13bd28b2d36f83e6181Lauro Ramos Venancio  }
725636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel}
726636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel
727ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
728ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                        Entry Points into this File
729ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
730ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
7311b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// GetNumNonZeroBytesInInit - Get an approximate count of the number of
7321b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// non-zero bytes that will be stored when outputting the initializer for the
7331b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// specified initializer expression.
7341b726771d00762fb5c4c2638e60d134c385493aeChris Lattnerstatic uint64_t GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
7351b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
7361b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return GetNumNonZeroBytesInInit(PE->getSubExpr(), CGF);
7371b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7381b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // 0 and 0.0 won't require any non-zero stores!
7391b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (isSimpleZero(E, CGF)) return 0;
7401b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7411b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If this is an initlist expr, sum up the size of sizes of the (present)
7421b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // elements.  If this is something weird, assume the whole thing is non-zero.
7431b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
7441b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType()))
7451b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return CGF.getContext().getTypeSize(E->getType())/8;
7461b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
747d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // InitListExprs for structs have to be handled carefully.  If there are
748d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // reference members, we need to consider the size of the reference, not the
749d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // referencee.  InitListExprs for unions and arrays can't have references.
7508c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner  if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
7518c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner    if (!RT->isUnionType()) {
7528c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
7538c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      uint64_t NumNonZeroBytes = 0;
754d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
7558c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      unsigned ILEElement = 0;
7568c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      for (RecordDecl::field_iterator Field = SD->field_begin(),
7578c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner           FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) {
7588c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // We're done once we hit the flexible array member or run out of
7598c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // InitListExpr elements.
7608c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->getType()->isIncompleteArrayType() ||
7618c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner            ILEElement == ILE->getNumInits())
7628c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          break;
7638c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->isUnnamedBitfield())
7648c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          continue;
7658c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner
7668c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        const Expr *E = ILE->getInit(ILEElement++);
7678c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner
7688c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // Reference values are always non-null and have the width of a pointer.
7698c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->getType()->isReferenceType())
7708c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          NumNonZeroBytes += CGF.getContext().Target.getPointerWidth(0);
7718c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        else
7728c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF);
7738c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      }
774d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
7758c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      return NumNonZeroBytes;
776d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner    }
777d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  }
778d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
779d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
7801b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  uint64_t NumNonZeroBytes = 0;
7811b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
7821b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF);
7831b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  return NumNonZeroBytes;
7841b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
7851b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7861b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// CheckAggExprForMemSetUse - If the initializer is large and has a lot of
7871b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// zeros in it, emit a memset and avoid storing the individual zeros.
7881b726771d00762fb5c4c2638e60d134c385493aeChris Lattner///
7891b726771d00762fb5c4c2638e60d134c385493aeChris Lattnerstatic void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
7901b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                                     CodeGenFunction &CGF) {
7911b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the slot is already known to be zeroed, nothing to do.  Don't mess with
7921b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // volatile stores.
7931b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return;
7941b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
7951b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the type is 16-bytes or smaller, prefer individual stores over memset.
7961b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  std::pair<uint64_t, unsigned> TypeInfo =
7971b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    CGF.getContext().getTypeInfo(E->getType());
7981b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (TypeInfo.first/8 <= 16)
7991b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
8001b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8011b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Check to see if over 3/4 of the initializer are known to be zero.  If so,
8021b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // we prefer to emit memset + individual stores for the rest.
8031b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  uint64_t NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF);
8041b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (NumNonZeroBytes*4 > TypeInfo.first/8)
8051b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
8061b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8071b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Okay, it seems like a good idea to use an initial memset, emit the call.
8081b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first/8);
8091b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  llvm::ConstantInt *AlignVal = CGF.Builder.getInt32(TypeInfo.second/8);
8101b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8111b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  llvm::Value *Loc = Slot.getAddr();
8121b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
8131b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8141b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  Loc = CGF.Builder.CreateBitCast(Loc, BP);
8151b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  CGF.Builder.CreateCall5(CGF.CGM.getMemSetFn(Loc->getType(),
8161b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                                              SizeVal->getType()),
8171b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                          Loc, CGF.Builder.getInt8(0), SizeVal, AlignVal,
8181b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                          CGF.Builder.getFalse());
8191b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8201b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Tell the AggExprEmitter that the slot is known zero.
8211b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  Slot.setZeroed();
8221b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
8231b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8241b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8251b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8261b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
827e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// EmitAggExpr - Emit the computation of the specified expression of aggregate
828e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
829e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// the value of the aggregate expression is not needed.  If VolatileDest is
830e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// true, DestPtr cannot be 0.
831558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall///
832558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall/// \param IsInitializer - true if this evaluation is initializing an
833558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall/// object whose lifetime is already being managed.
83418aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar//
83518aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar// FIXME: Take Qualifiers object.
836558d2abc7f9fd6801cc7677200992313ae90b5d8John McCallvoid CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
837474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian                                  bool IgnoreResult) {
838ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  assert(E && hasAggregateLLVMType(E->getType()) &&
839ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner         "Invalid aggregate expression to emit");
8401b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  assert((Slot.getAddr() != 0 || Slot.isIgnored()) &&
8411b726771d00762fb5c4c2638e60d134c385493aeChris Lattner         "slot has bits but no address");
8421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8431b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Optimize the slot if possible.
8441b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  CheckAggExprForMemSetUse(Slot, E, *this);
8451b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8461b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E));
847ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner}
8487482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar
84918aba0dd518e486d8b50523e7dafb4b5657135d2Daniel DunbarLValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
85018aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar  assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
851195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *Temp = CreateMemTemp(E->getType());
85279c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  LValue LV = MakeAddrLValue(Temp, E->getType());
8531b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  EmitAggExpr(E, AggValueSlot::forAddr(Temp, LV.isVolatileQualified(), false));
85479c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  return LV;
85518aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar}
85618aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar
8577482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbarvoid CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
85827fe2e6c97a3782a0639d87b460741e8ba5d076dMike Stump                                        llvm::Value *SrcPtr, QualType Ty,
85927fe2e6c97a3782a0639d87b460741e8ba5d076dMike Stump                                        bool isVolatile) {
8607482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
8611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8620d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson  if (getContext().getLangOptions().CPlusPlus) {
8630d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson    if (const RecordType *RT = Ty->getAs<RecordType>()) {
864e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
865e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      assert((Record->hasTrivialCopyConstructor() ||
8661d49f2112572c247ff9c209de112fbf5d9ecf765Fariborz Jahanian              Record->hasTrivialCopyAssignment()) &&
867e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor             "Trying to aggregate-copy a type without a trivial copy "
868e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor             "constructor or assignment operator");
869419aa964ae845aa5b1183fabb2f1cff78faaedddDouglas Gregor      // Ignore empty classes in C++.
870e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      if (Record->isEmpty())
8710d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson        return;
8720d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson    }
8730d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson  }
8740d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson
87583c9629291e3f4d4619fa98f8a57e4ec347c6154Chris Lattner  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
876ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // C99 6.5.16.1p3, which states "If the value being stored in an object is
877ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // read from another object that overlaps in anyway the storage of the first
878ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // object, then the overlap shall be exact and the two objects shall have
879ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // qualified or unqualified versions of a compatible type."
880ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  //
88183c9629291e3f4d4619fa98f8a57e4ec347c6154Chris Lattner  // memcpy is not defined if the source and destination pointers are exactly
882ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // equal, but other compilers do this optimization, and almost every memcpy
883ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // implementation handles this case safely.  If there is a libc that does not
884ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // safely handle this, we can add a target hook.
8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8867482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  // Get size and alignment info for this aggregate.
8877482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8897482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  // FIXME: Handle variable sized types.
8901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
891fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // FIXME: If we have a volatile struct, the optimizer can remove what might
892fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // appear to be `extra' memory ops:
893fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
894fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // volatile struct { int i; } a, b;
895fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
896fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // int main() {
897fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //   a = b;
898fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //   a = b;
899fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // }
900fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
9013ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang  // we need to use a different call here.  We use isVolatile to indicate when
90249d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  // either the source or the destination is volatile.
9033ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
9043ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang  const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
905098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner  const llvm::Type *DBP =
906098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner    llvm::Type::getInt8PtrTy(VMContext, DPT->getAddressSpace());
907098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner  DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
9083ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
9093ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang  const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
910098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner  const llvm::Type *SBP =
911098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner    llvm::Type::getInt8PtrTy(VMContext, SPT->getAddressSpace());
912098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
9133ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
91455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
91555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    RecordDecl *Record = RecordTy->getDecl();
91655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    if (Record->hasObjectMember()) {
91755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      unsigned long size = TypeInfo.first/8;
91855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
91955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
92055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
92155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                                    SizeVal);
92255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      return;
92355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    }
92455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  } else if (getContext().getAsArrayType(Ty)) {
92555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    QualType BaseType = getContext().getBaseElementType(Ty);
92655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
92755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      if (RecordTy->getDecl()->hasObjectMember()) {
92855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        unsigned long size = TypeInfo.first/8;
92955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
93055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
93155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
93255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                                      SizeVal);
93355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        return;
93455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      }
93555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    }
93655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  }
93755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian
9383ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang  Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
93977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner                                      IntPtrTy),
9407482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar                      DestPtr, SrcPtr,
9417482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar                      // TypeInfo.first describes size in bits.
94277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner                      llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
943098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner                      Builder.getInt32(TypeInfo.second/8),
944098432c3119cd4e421a2b906d06187b004d3a86bChris Lattner                      Builder.getInt1(isVolatile));
9457482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar}
946