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
38410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  /// We want to use 'dest' as the return slot except under two
39410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  /// conditions:
40410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  ///   - The destination slot requires garbage collection, so we
41410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  ///     need to use the GC API.
42410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  ///   - The destination slot is potentially aliased.
43410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  bool shouldUseDestForReturnSlot() const {
44410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    return !(Dest.requiresGCollection() || Dest.isPotentiallyAliased());
45410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  }
46410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall
47ef072fd2f3347cfd857d6eb787b245b950771430John McCall  ReturnValueSlot getReturnValueSlot() const {
48410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    if (!shouldUseDestForReturnSlot())
49410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall      return ReturnValueSlot();
50fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
51558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
52558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  }
53558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
54558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot EnsureSlot(QualType T) {
55558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    if (!Dest.isIgnored()) return Dest;
56558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    return CGF.CreateAggTemp(T, "agg.tmp.ensured");
57ef072fd2f3347cfd857d6eb787b245b950771430John McCall  }
58fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
599c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnerpublic:
60558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
61474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian                 bool ignore)
62558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
63474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian      IgnoreResult(ignore) {
649c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  }
659c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
66ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
67ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //                               Utilities
68ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
69ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
709c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// EmitAggLoadOfLValue - Given an expression with aggregate type that
719c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// represents a value lvalue, this method emits the address of the lvalue,
729c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  /// then loads the result into DestPtr.
739c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void EmitAggLoadOfLValue(const Expr *E);
74922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
754ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
7649d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
7749d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
784ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
79410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
80fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
817c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall  AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
82e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor    if (CGF.getLangOptions().getGC() && TypeRequiresGCollection(T))
837c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall      return AggValueSlot::NeedsGCBarriers;
847c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall    return AggValueSlot::DoesNotNeedGCBarriers;
857c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall  }
867c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall
87fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  bool TypeRequiresGCollection(QualType T);
88fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
89ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
90ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //                            Visitor Methods
91ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  //===--------------------------------------------------------------------===//
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
939c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitStmt(Stmt *S) {
94488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar    CGF.ErrorUnsupported(S, "aggregate expression");
959c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  }
969c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
97f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  void VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
98f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne    Visit(GE->getResultExpr());
99f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  }
10012444a24419fe88b42a16b46106db3c11ac5cd35Eli Friedman  void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
10191a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall  void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
10291a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall    return Visit(E->getReplacement());
10391a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall  }
1049c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
1059c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  // l-values.
1069b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
1079b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
1089b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
1095be028f84243e0f6906c259e67cbdaf9bee431b2Daniel Dunbar  void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
110751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
1119b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
1129b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon    EmitAggLoadOfLValue(E);
1139b73b39f6fbf987acbbe6570d557d13f07c7e0f7Seo Sanghyeon  }
114f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitAggLoadOfLValue(E);
116f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  }
117f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  void VisitPredefinedExpr(const PredefinedExpr *E) {
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitAggLoadOfLValue(E);
119f0a990c2aa0b596a7e3cdd8fa2a5909d591ffe66Chris Lattner  }
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1219c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  // Operators.
1224d8673b645ad86e496b886a0f80b60763f67071dAnders Carlsson  void VisitCastExpr(CastExpr *E);
123148fe6772733166c720e28b7bb5084af6e624b44Anders Carlsson  void VisitCallExpr(const CallExpr *E);
124b2d963f527674275c9109252474948368b6e6161Chris Lattner  void VisitStmtExpr(const StmtExpr *E);
1259c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  void VisitBinaryOperator(const BinaryOperator *BO);
1268bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
12703d6fb99224c36935c9af9f4785cb33453c99b2bChris Lattner  void VisitBinAssign(const BinaryOperator *E);
12807fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman  void VisitBinComma(const BinaryOperator *E);
1299c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
1308fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  void VisitObjCMessageExpr(ObjCMessageExpr *E);
1310a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
1320a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar    EmitAggLoadOfLValue(E);
1330a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar  }
1349c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
137a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson  void VisitChooseExpr(const ChooseExpr *CE);
138636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel  void VisitInitListExpr(InitListExpr *E);
13930311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson  void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
14004421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
14104421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner    Visit(DAE->getExpr());
14204421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner  }
143b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson  void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
14431ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson  void VisitCXXConstructExpr(const CXXConstructExpr *E);
1454765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall  void VisitExprWithCleanups(ExprWithCleanups *E);
146ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
1472710c4159ff4761ba9867aca18f60a178b297686Mike Stump  void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
14803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor  void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
149e996ffd240f20a1048179d7727a6ee3227261921John McCall  void VisitOpaqueValueExpr(OpaqueValueExpr *E);
150e996ffd240f20a1048179d7727a6ee3227261921John McCall
151b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman  void VisitVAArgExpr(VAArgExpr *E);
152f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner
153a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  void EmitInitializationToLValue(Expr *E, LValue Address);
154a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  void EmitNullInitializationToLValue(LValue Address);
1559c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  //  case Expr::ChooseExprClass:
15639406b1395f69341c045e863a6620310abdc55b6Mike Stump  void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
157276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  void VisitAtomicExpr(AtomicExpr *E) {
158276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman    CGF.EmitAtomicExpr(E, EnsureSlot(E->getType()).getAddr());
159276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  }
1609c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner};
1619c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner}  // end anonymous namespace.
1629c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
163ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
164ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                                Utilities
165ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
1669c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner
167883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// EmitAggLoadOfLValue - Given an expression with aggregate type that
168883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// represents a value lvalue, this method emits the address of the lvalue,
169883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner/// then loads the result into DestPtr.
1709c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnervoid AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
1719c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  LValue LV = CGF.EmitLValue(E);
1724ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  EmitFinalDestCopy(E, LV);
1734ac20ddc7ab324a59862657f756bdd060076b137Mike Stump}
1744ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
175fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// \brief True if the given aggregate type requires special GC API calls.
176fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCallbool AggExprEmitter::TypeRequiresGCollection(QualType T) {
177fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Only record types have members that might require garbage collection.
178fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  const RecordType *RecordTy = T->getAs<RecordType>();
179fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  if (!RecordTy) return false;
180fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
181fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Don't mess with non-trivial C++ types.
182fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RecordDecl *Record = RecordTy->getDecl();
183fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  if (isa<CXXRecordDecl>(Record) &&
184fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall      (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() ||
185fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall       !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
186fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall    return false;
187fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
188fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  // Check whether the type has an object member.
189fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  return Record->hasObjectMember();
190fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall}
191fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
192410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall/// \brief Perform the final move to DestPtr if for some reason
193410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall/// getReturnValueSlot() didn't use it directly.
194fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall///
195fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall/// The idea is that you do something like this:
196fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall///   RValue Result = EmitSomething(..., getReturnValueSlot());
197410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall///   EmitMoveFromReturnSlot(E, Result);
198410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall///
199410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall/// If nothing interferes, this will cause the result to be emitted
200410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall/// directly into the return value slot.  Otherwise, a final move
201410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall/// will be performed.
202410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCallvoid AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue Src) {
203410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  if (shouldUseDestForReturnSlot()) {
204410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    // Logically, Dest.getAddr() should equal Src.getAggregateAddr().
205410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    // The possibility of undef rvalues complicates that a lot,
206410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    // though, so we can't really assert.
207410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    return;
20855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  }
209410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall
210410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  // Otherwise, do a final copy,
211410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  assert(Dest.getAddr() != Src.getAggregateAddr());
212410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  EmitFinalDestCopy(E, Src, /*Ignore*/ true);
213fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall}
214fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall
2154ac20ddc7ab324a59862657f756bdd060076b137Mike Stump/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
21649d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stumpvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
2174ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  assert(Src.isAggregate() && "value must be aggregate value!");
2184ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
219558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // If Dest is ignored, then we're evaluating an aggregate expression
220a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // in a context (like an expression statement) that doesn't care
221a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // about the result.  C says that an lvalue-to-rvalue conversion is
222a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // performed in these cases; C++ says that it is not.  In either
223a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // case, we don't actually need to do anything unless the value is
224a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall  // volatile.
225558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  if (Dest.isIgnored()) {
226a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall    if (!Src.isVolatileQualified() ||
227a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall        CGF.CGM.getLangOptions().CPlusPlus ||
228a8f28da6265950eea768f7e4ade15e4ebaddd56fJohn McCall        (IgnoreResult && Ignore))
2299ccb103c6f777fc42343b23b19a8c2c9a740e6e8Mike Stump      return;
2308a97005f97a2a93fc2cd942c040668c5d4df7537Fariborz Jahanian
23149d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    // If the source is volatile, we must read from it; to do that, we need
23249d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    // some place to put it.
233558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
2349ccb103c6f777fc42343b23b19a8c2c9a740e6e8Mike Stump  }
235883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
236d1a5f13140a5bfcf9107b28de906518d2313fdf0John McCall  if (Dest.requiresGCollection()) {
237479b61ccd8cd847281eef0b43e6873f0930f1b98Ken Dyck    CharUnits size = CGF.getContext().getTypeSizeInChars(E->getType());
2382acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
239479b61ccd8cd847281eef0b43e6873f0930f1b98Ken Dyck    llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
24008c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
241558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      Dest.getAddr(),
242558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      Src.getAggregateAddr(),
243558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                                                      SizeVal);
24408c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian    return;
24508c321380fff07d476a19daab6d29522c046cd49Fariborz Jahanian  }
2464ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // If the result of the assignment is used, copy the LHS there also.
2474ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
2484ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // from the source as well, as we can't eliminate it if either operand
2494ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  // is volatile, unless copy has volatile for both source and destination..
250558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(),
251558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall                        Dest.isVolatile()|Src.isVolatileQualified());
2524ac20ddc7ab324a59862657f756bdd060076b137Mike Stump}
2534ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
2544ac20ddc7ab324a59862657f756bdd060076b137Mike Stump/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
25549d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stumpvoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
2564ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
2574ac20ddc7ab324a59862657f756bdd060076b137Mike Stump
2584ac20ddc7ab324a59862657f756bdd060076b137Mike Stump  EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
25949d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump                                            Src.isVolatileQualified()),
26049d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump                    Ignore);
261883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
262883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
263ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
264ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                            Visitor Methods
265ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
266ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
26703e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregorvoid AggExprEmitter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E){
26803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor  Visit(E->GetTemporaryExpr());
26903e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor}
27003e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor
271e996ffd240f20a1048179d7727a6ee3227261921John McCallvoid AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
27256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  EmitFinalDestCopy(e, CGF.getOpaqueLValueMapping(e));
273e996ffd240f20a1048179d7727a6ee3227261921John McCall}
274e996ffd240f20a1048179d7727a6ee3227261921John McCall
275751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregorvoid
276751ec9be961888f14342fb63b39bf8727f0dee49Douglas GregorAggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
277673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor  if (E->getType().isPODType(CGF.getContext())) {
278673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    // For a POD type, just emit a load of the lvalue + a copy, because our
279673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    // compound literal might alias the destination.
280673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    // FIXME: This is a band-aid; the real problem appears to be in our handling
281673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    // of assignments, where we store directly into the LHS without checking
282673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    // whether anything in the RHS aliases.
283673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    EmitAggLoadOfLValue(E);
284673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor    return;
285673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor  }
286673e98b4814642eb040a661fcc0f7953edd4c150Douglas Gregor
287751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor  AggValueSlot Slot = EnsureSlot(E->getType());
288751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor  CGF.EmitAggExpr(E->getInitializer(), Slot);
289751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor}
290751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor
291751ec9be961888f14342fb63b39bf8727f0dee49Douglas Gregor
2924d8673b645ad86e496b886a0f80b60763f67071dAnders Carlssonvoid AggExprEmitter::VisitCastExpr(CastExpr *E) {
2933016842613674ab80796567239c15d529aff1458Anders Carlsson  switch (E->getCastKind()) {
294575b374fdbfc2c2224fd3047ac11ffc4b8db9ae5Anders Carlsson  case CK_Dynamic: {
29569cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
29669cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
29769cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    // FIXME: Do we also need to handle property references here?
29869cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    if (LV.isSimple())
29969cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor      CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
30069cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    else
30169cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor      CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
30269cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor
303558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    if (!Dest.isIgnored())
304558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall      CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
30569cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor    break;
30669cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor  }
30769cfeb1036ad22c911b7243dca0eecee72e452d3Douglas Gregor
3082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_ToUnion: {
3096591271275f7a3db357f3cb7af37ef86e800e4baJohn McCall    if (Dest.isIgnored()) break;
3106591271275f7a3db357f3cb7af37ef86e800e4baJohn McCall
3114d8673b645ad86e496b886a0f80b60763f67071dAnders Carlsson    // GCC union extension
31279c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    QualType Ty = E->getSubExpr()->getType();
31379c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    QualType PtrTy = CGF.getContext().getPointerType(Ty);
314558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
31534ebf4d1767e6748a1a59a5d1935c495cd8877e8Eli Friedman                                                 CGF.ConvertType(PtrTy));
316a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall    EmitInitializationToLValue(E->getSubExpr(),
317a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall                               CGF.MakeAddrLValue(CastPtr, Ty));
3183016842613674ab80796567239c15d529aff1458Anders Carlsson    break;
3197e91627301b05cd8f2324795e19d87a62f444c31Nuno Lopes  }
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_DerivedToBase:
3222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_BaseToDerived:
3232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_UncheckedDerivedToBase: {
324b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("cannot perform hierarchy conversion in EmitAggExpr: "
3252d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor                "should have been unpacked before we got here");
3262d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  }
3272d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor
328f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  case CK_GetObjCProperty: {
329f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    LValue LV = CGF.EmitLValue(E->getSubExpr());
330f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    assert(LV.isPropertyRef());
331f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot());
332410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    EmitMoveFromReturnSlot(E, RV);
333f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    break;
334f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  }
335f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
336f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  case CK_LValueToRValue: // hope for downstream optimization
3372de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_NoOp:
3382de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_UserDefinedConversion:
3392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_ConstructorConversion:
3403016842613674ab80796567239c15d529aff1458Anders Carlsson    assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
3413016842613674ab80796567239c15d529aff1458Anders Carlsson                                                   E->getType()) &&
3423016842613674ab80796567239c15d529aff1458Anders Carlsson           "Implicit cast types must be compatible");
3433016842613674ab80796567239c15d529aff1458Anders Carlsson    Visit(E->getSubExpr());
3443016842613674ab80796567239c15d529aff1458Anders Carlsson    break;
3450ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall
3462de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  case CK_LValueBitCast:
3470ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall    llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
348e39a3894513349908cdb3beba2614e53cb288e6cDouglas Gregor    break;
3491de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCall
3500ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_Dependent:
3510ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_BitCast:
3520ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ArrayToPointerDecay:
3530ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FunctionToPointerDecay:
3540ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_NullToPointer:
3550ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_NullToMemberPointer:
3560ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_BaseToDerivedMemberPointer:
3570ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_DerivedToBaseMemberPointer:
3580ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_MemberPointerToBoolean:
3590ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToPointer:
3600ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_PointerToIntegral:
3610ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_PointerToBoolean:
3620ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ToVoid:
3630ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_VectorSplat:
3640ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralCast:
3650ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToBoolean:
3660ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralToFloating:
3670ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingToIntegral:
3680ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingToBoolean:
3690ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingCast:
3701d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  case CK_CPointerToObjCPointerCast:
3711d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  case CK_BlockPointerToObjCPointerCast:
3720ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_AnyPointerToBlockPointerCast:
3730ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_ObjCObjectLValueCast:
3740ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingRealToComplex:
3750ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToReal:
3760ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToBoolean:
3770ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexCast:
3780ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_FloatingComplexToIntegralComplex:
3790ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralRealToComplex:
3800ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToReal:
3810ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToBoolean:
3820ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexCast:
3830ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall  case CK_IntegralComplexToFloatingComplex:
38433e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall  case CK_ARCProduceObject:
38533e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall  case CK_ARCConsumeObject:
38633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall  case CK_ARCReclaimReturnedObject:
38733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall  case CK_ARCExtendBlockObject:
3880ae287a498b8cec2086fe6b7e753cbb3df63e74aJohn McCall    llvm_unreachable("cast kind invalid for aggregate types");
3893016842613674ab80796567239c15d529aff1458Anders Carlsson  }
390e4707ff0bb48add651c6a1ad9acfcb22609462d1Anders Carlsson}
391e4707ff0bb48add651c6a1ad9acfcb22609462d1Anders Carlsson
3929619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitCallExpr(const CallExpr *E) {
393e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson  if (E->getCallReturnType()->isReferenceType()) {
394e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson    EmitAggLoadOfLValue(E);
395e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson    return;
396e70e8f7fef3efb3d526ee25b3a0e2a4bf67a04b6Anders Carlsson  }
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
398fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot());
399410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  EmitMoveFromReturnSlot(E, RV);
400796ef3d4a32ce8d9e76df0d5bcab07db97883064Nate Begeman}
4019619662a1d42e2008b865d3459c0677e149dad1bChris Lattner
4029619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
403fa037bd3f79d3c70197a3224bb1b29c6c4af0098John McCall  RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
404410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall  EmitMoveFromReturnSlot(E, RV);
4058fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
406796ef3d4a32ce8d9e76df0d5bcab07db97883064Nate Begeman
4079c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbarvoid AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
408f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  llvm_unreachable("direct property access not surrounded by "
409f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall                   "lvalue-to-rvalue cast");
4105daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian}
4115daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian
4129619662a1d42e2008b865d3459c0677e149dad1bChris Lattnervoid AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
4132a41637a995affa1563f4d82a8b026e326a2faa0John McCall  CGF.EmitIgnoredExpr(E->getLHS());
414558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Visit(E->getRHS());
41507fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman}
41607fa52ab33a75d7a5736ea5bd0d4e3134fb10c7eEli Friedman
417b2d963f527674275c9109252474948368b6e6161Chris Lattnervoid AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
418150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  CodeGenFunction::StmtExprEvaluation eval(CGF);
419558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest);
420b2d963f527674275c9109252474948368b6e6161Chris Lattner}
421b2d963f527674275c9109252474948368b6e6161Chris Lattner
4229c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattnervoid AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
4232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)
4248bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian    VisitPointerToDataMemberBinaryOperator(E);
4258bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  else
4268bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian    CGF.ErrorUnsupported(E, "aggregate binary expression");
4278bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian}
4288bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian
4298bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanianvoid AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
4308bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian                                                    const BinaryOperator *E) {
4318bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
4328bfd31f9dad09cd52225d868bbd92a9bebe87775Fariborz Jahanian  EmitFinalDestCopy(E, LV);
433ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner}
434ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
43503d6fb99224c36935c9af9f4785cb33453c99b2bChris Lattnervoid AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
436ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman  // For an assignment to work, the value on the right has
437ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman  // to be compatible with the value on the left.
4382dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
4392dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman                                                 E->getRHS()->getType())
440ff6e2b7d31b0f5494f583419e5061c32ea4e6180Eli Friedman         && "Invalid assignment");
441cd940a1e13e588a43973cd7ae33b5c33a3062739John McCall
4422c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS()))
44373a6f8e8ad2174fb70cfb4c7d7afe424cfe8a147Fariborz Jahanian    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4442c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian      if (VD->hasAttr<BlocksAttr>() &&
4452c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian          E->getRHS()->HasSideEffects(CGF.getContext())) {
4462c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        // When __block variable on LHS, the RHS must be evaluated first
4472c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        // as it may change the 'forwarding' field via call to Block_copy.
4482c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        LValue RHS = CGF.EmitLValue(E->getRHS());
4492c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        LValue LHS = CGF.EmitLValue(E->getLHS());
4507c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall        Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
4514418439220a8f8e0b1deffdccce2354854c702f5John McCall                                       needsGC(E->getLHS()->getType()),
4524418439220a8f8e0b1deffdccce2354854c702f5John McCall                                       AggValueSlot::IsAliased);
4532c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        EmitFinalDestCopy(E, RHS, true);
4542c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian        return;
4552c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian      }
4562c7168c660ab2b961ad48087e02cca96f7bb94d2Fariborz Jahanian
4579c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  LValue LHS = CGF.EmitLValue(E->getLHS());
458883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
4597f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  // We have to special case property setters, otherwise we must have
4607f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  // a simple lvalue (no aggregates inside vectors, bitfields).
4617f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  if (LHS.isPropertyRef()) {
46268af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    const ObjCPropertyRefExpr *RE = LHS.getPropertyRefExpr();
46368af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    QualType ArgType = RE->getSetterArgType();
46468af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    RValue Src;
46568af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    if (ArgType->isReferenceType())
46668af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian      Src = CGF.EmitReferenceBindingToExpr(E->getRHS(), 0);
46768af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    else {
46868af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian      AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
46968af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian      CGF.EmitAggExpr(E->getRHS(), Slot);
47068af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian      Src = Slot.asRValue();
47168af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    }
47268af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian    CGF.EmitStoreThroughPropertyRefLValue(Src, LHS);
4737f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  } else {
4747f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar    // Codegen the RHS so that it stores directly into the LHS.
4757c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall    AggValueSlot LHSSlot =
4767c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall      AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
4774418439220a8f8e0b1deffdccce2354854c702f5John McCall                              needsGC(E->getLHS()->getType()),
4784418439220a8f8e0b1deffdccce2354854c702f5John McCall                              AggValueSlot::IsAliased);
479474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
48049d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump    EmitFinalDestCopy(E, LHS, true);
4817f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  }
482883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
483883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
48456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallvoid AggExprEmitter::
48556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallVisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
4869615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
4879615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
4889615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  // Bind the common expression if necessary.
49156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  CodeGenFunction::OpaqueValueMapping binding(CGF, E);
49256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
493150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  CodeGenFunction::ConditionalEvaluation eval(CGF);
4948e274bd14bcca8466542477844b88e90e90cde1aEli Friedman  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49674fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // Save whether the destination's lifetime is externally managed.
497fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  bool isExternallyDestructed = Dest.isExternallyDestructed();
498883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner
499150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  eval.begin(CGF);
500150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  CGF.EmitBlock(LHSBlock);
50156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  Visit(E->getTrueExpr());
502150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  eval.end(CGF);
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
504150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  assert(CGF.HaveInsertPoint() && "expression evaluation ended with no IP!");
505150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  CGF.Builder.CreateBr(ContBlock);
5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50774fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // If the result of an agg expression is unused, then the emission
50874fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // of the LHS might need to create a destination slot.  That's fine
50974fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall  // with us, and we can safely emit the RHS into the same slot, but
510fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  // we shouldn't claim that it's already being destructed.
511fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  Dest.setExternallyDestructed(isExternallyDestructed);
51274fb0edb44b7ed52af9b8053032ccaab29b5c0ccJohn McCall
513150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  eval.begin(CGF);
514150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  CGF.EmitBlock(RHSBlock);
51556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  Visit(E->getFalseExpr());
516150b462afc7a713edd19bcbbbb22381fe060d4f5John McCall  eval.end(CGF);
5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5189c03356918aee078e925c35f9854dfdf2492dfc3Chris Lattner  CGF.EmitBlock(ContBlock);
519883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner}
520ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
521a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlssonvoid AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
522a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson  Visit(CE->getChosenSubExpr(CGF.getContext()));
523a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson}
524a294ca8c64fbb345f32e4af9d8fabdf2f64e4883Anders Carlsson
525b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedmanvoid AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5260785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar  llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
527ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
528ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
5290262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl  if (!ArgPtr) {
530ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
5310262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl    return;
5320262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl  }
5330262f02cbaa35cafb61b1b994e0adff7c422a235Sebastian Redl
53479c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType()));
535b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman}
536b1851249d787f573b9e1312fff8ca4bbcf351f10Eli Friedman
537b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlssonvoid AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
538558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  // Ensure that we have a slot, but if we already do, remember
539fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  // whether it was externally destructed.
540fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  bool wasExternallyDestructed = Dest.isExternallyDestructed();
541558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Dest = EnsureSlot(E->getType());
542fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall
543fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  // We're going to push a destructor if there isn't already one.
544fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  Dest.setExternallyDestructed();
545558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
546558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  Visit(E->getSubExpr());
547558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
548fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  // Push that destructor we promised.
549fd71fb81c5f9382caf0131946e890b133e12ceb5John McCall  if (!wasExternallyDestructed)
550558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    CGF.EmitCXXTemporary(E->getTemporary(), Dest.getAddr());
551b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson}
552b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson
553b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
55431ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonAggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
555558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(E->getType());
556558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  CGF.EmitCXXConstructExpr(E, Slot);
5577f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson}
5587f6ad153565245026c7569314f65a4d4ff4ac41fAnders Carlsson
5594765fa05b5652fcc4356371c2f481d0ea9a1b007John McCallvoid AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
5604765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall  CGF.EmitExprWithCleanups(E, Dest);
561b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
562b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
563ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregorvoid AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
564558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  QualType T = E->getType();
565558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(T);
566a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
56730311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson}
56830311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlsson
56930311fa6b0735b9cb73b01e25bf9652a4b9b0c53Anders Carlssonvoid AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
570558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  QualType T = E->getType();
571558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  AggValueSlot Slot = EnsureSlot(T);
572a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
573329763b1e9ec8c216025e3a8379ed446d7372cbcNuno Lopes}
574329763b1e9ec8c216025e3a8379ed446d7372cbcNuno Lopes
5751b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// isSimpleZero - If emitting this value will obviously just cause a store of
5761b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// zero to memory, return true.  This can return false if uncertain, so it just
5771b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// handles simple cases.
5781b726771d00762fb5c4c2638e60d134c385493aeChris Lattnerstatic bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) {
579f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  E = E->IgnoreParens();
580f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne
5811b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // 0
5821b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
5831b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return IL->getValue() == 0;
5841b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // +0.0
5851b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E))
5861b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return FL->getValue().isPosZero();
5871b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // int()
5881b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) &&
5891b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      CGF.getTypes().isZeroInitializable(E->getType()))
5901b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return true;
5911b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // (int*)0 - Null pointer expressions.
5921b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
5931b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return ICE->getCastKind() == CK_NullToPointer;
5941b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // '\0'
5951b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
5961b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return CL->getValue() == 0;
5971b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
5981b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Otherwise, hard case: conservatively return false.
5991b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  return false;
6001b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
6011b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
6021b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
60378e83f881e59d4b8648a7b85ec6f2d36ef5cc680Anders Carlssonvoid
604a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCallAggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
605a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  QualType type = LV.getType();
6067f79f9be5916c51c35da4f126b7c12596a101607Mike Stump  // FIXME: Ignore result?
607f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // FIXME: Are initializers affected by volatile?
6081b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (Dest.isZeroed() && isSimpleZero(E, CGF)) {
6091b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // Storing "i32 0" to a zero'd memory location is a noop.
6101b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  } else if (isa<ImplicitValueInitExpr>(E)) {
611a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall    EmitNullInitializationToLValue(LV);
612a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  } else if (type->isReferenceType()) {
61332f36baa6c8d491c374af622b4e3ac28d597453cAnders Carlsson    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
614545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreThroughLValue(RV, LV);
615a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  } else if (type->isAnyComplexType()) {
6163498bdb9e9cb300de74c7b51c92608e2902b2348Douglas Gregor    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
617a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  } else if (CGF.hasAggregateLLVMType(type)) {
6187c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall    CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV,
6197c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall                                               AggValueSlot::IsDestructed,
6207c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall                                      AggValueSlot::DoesNotNeedGCBarriers,
621410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                               AggValueSlot::IsNotAliased,
622a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall                                               Dest.isZeroed()));
623f85e193739c953358c865005855253af4f68a497John McCall  } else if (LV.isSimple()) {
624a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall    CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false);
625c8ba9614ca5469c3ae259e3ec09792f4b8969397Eli Friedman  } else {
626545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV);
627f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
628f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner}
629305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio
630a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCallvoid AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
631a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  QualType type = lv.getType();
632a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall
6331b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the destination slot is already zeroed out before the aggregate is
6341b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // copied into it, we don't have to emit any zeros here.
635a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type))
6361b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
6371b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
638a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall  if (!CGF.hasAggregateLLVMType(type)) {
639f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // For non-aggregates, we can store zero
640a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall    llvm::Value *null = llvm::Constant::getNullValue(CGF.ConvertType(type));
641545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreThroughLValue(RValue::get(null), lv);
642f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  } else {
643f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // There's a potential optimization opportunity in combining
644f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // memsets; that would be easy for arrays, but relatively
645f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    // difficult for structures with the current code.
646a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall    CGF.EmitNullInitialization(lv.getAddress(), lv.getType());
647f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
648f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner}
649305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio
650f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattnervoid AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
651a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman#if 0
65213a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
65313a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  // (Length of globals? Chunks of zeroed-out space?).
654a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman  //
655f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // If we can, prefer a copy from a global; this is a lot less code for long
656f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // globals, and it's easier for the current optimizers to analyze.
65713a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
658994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman    llvm::GlobalVariable* GV =
65913a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
66013a5be10b198a5dc7e3e72c54481cd8b70f68495Eli Friedman                             llvm::GlobalValue::InternalLinkage, C, "");
66179c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar    EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
662994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman    return;
663994ffef4353056363ba5915eeecf0e1b0678f286Eli Friedman  }
664a385b3c9c442831fc6a9ec6e8823b2067bd65710Eli Friedman#endif
665d0db03a561671b8b466b07026cc8fbbb037bb639Chris Lattner  if (E->hadArrayRangeDesignator())
666a9c878086036de36482cc21e35a33cabe9699b0aDouglas Gregor    CGF.ErrorUnsupported(E, "GNU array range designator extension");
667a9c878086036de36482cc21e35a33cabe9699b0aDouglas Gregor
668558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  llvm::Value *DestPtr = Dest.getAddr();
669558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall
670f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Handle initialization of an array.
671f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  if (E->getType()->isArrayType()) {
6722acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::PointerType *APType =
673f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      cast<llvm::PointerType>(DestPtr->getType());
6742acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::ArrayType *AType =
675f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      cast<llvm::ArrayType>(APType->getElementType());
6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
677f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    uint64_t NumInitElements = E->getNumInits();
678922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
6799619662a1d42e2008b865d3459c0677e149dad1bChris Lattner    if (E->getNumInits() > 0) {
6809619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      QualType T1 = E->getType();
6819619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      QualType T2 = E->getInit(0)->getType();
6822dce5f8a99b5c48f1287ff3941288ca6f7fde2deEli Friedman      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
6839619662a1d42e2008b865d3459c0677e149dad1bChris Lattner        EmitAggLoadOfLValue(E->getInit(0));
6849619662a1d42e2008b865d3459c0677e149dad1bChris Lattner        return;
6859619662a1d42e2008b865d3459c0677e149dad1bChris Lattner      }
686922696f03ec9637449e2cba260493808b4977cd3Eli Friedman    }
687922696f03ec9637449e2cba260493808b4977cd3Eli Friedman
688f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    uint64_t NumArrayElements = AType->getNumElements();
689bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    assert(NumInitElements <= NumArrayElements);
690bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
691bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    QualType elementType = E->getType().getCanonicalType();
692bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    elementType = CGF.getContext().getQualifiedType(
693bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                    cast<ArrayType>(elementType)->getElementType(),
694bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                    elementType.getQualifiers() + Dest.getQualifiers());
695bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
696bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // DestPtr is an array*.  Construct an elementType* by drilling
697bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // down a level.
698bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
699bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::Value *indices[] = { zero, zero };
700bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::Value *begin =
7010f6ac7cf7bc6a02c1a5c19d2c90ec0d1dd7786e7Jay Foad      Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");
702bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
703bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Exception safety requires us to destroy all the
704bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // already-constructed members if an initializer throws.
705bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // For that, we'll need an EH cleanup.
706bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    QualType::DestructionKind dtorKind = elementType.isDestructedType();
707bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::AllocaInst *endOfInit = 0;
708bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    EHScopeStack::stable_iterator cleanup;
709bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    if (CGF.needsEHCleanup(dtorKind)) {
710bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // In principle we could tell the cleanup where we are more
711bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // directly, but the control flow can get so varied here that it
712bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // would actually be quite complex.  Therefore we go through an
713bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // alloca.
714bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      endOfInit = CGF.CreateTempAlloca(begin->getType(),
715bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                       "arrayinit.endOfInit");
716bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      Builder.CreateStore(begin, endOfInit);
7172673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
7182673c68aa58e277ebc755b71d81aca618cdedbf9John McCall                                           CGF.getDestroyer(dtorKind));
719bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      cleanup = CGF.EHStack.stable_begin();
720bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
721bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Otherwise, remember that we didn't need a cleanup.
722bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    } else {
723bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      dtorKind = QualType::DK_none;
724bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    }
7253b4d490b09347e0b68ec0511ddfae79dfaba77a6Argyrios Kyrtzidis
726bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
727bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
728bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // The 'current element to initialize'.  The invariants on this
729bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // variable are complicated.  Essentially, after each iteration of
730bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // the loop, it points to the last initialized element, except
731bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // that it points to the beginning of the array before any
732bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // elements have been initialized.
733bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    llvm::Value *element = begin;
734bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
735bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Emit the explicit initializers.
736bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    for (uint64_t i = 0; i != NumInitElements; ++i) {
737bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Advance to the next element.
7382673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      if (i > 0) {
739bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
740bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
7412673c68aa58e277ebc755b71d81aca618cdedbf9John McCall        // Tell the cleanup that it needs to destroy up to this
7422673c68aa58e277ebc755b71d81aca618cdedbf9John McCall        // element.  TODO: some of these stores can be trivially
7432673c68aa58e277ebc755b71d81aca618cdedbf9John McCall        // observed to be unnecessary.
7442673c68aa58e277ebc755b71d81aca618cdedbf9John McCall        if (endOfInit) Builder.CreateStore(element, endOfInit);
7452673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      }
7462673c68aa58e277ebc755b71d81aca618cdedbf9John McCall
747bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      LValue elementLV = CGF.MakeAddrLValue(element, elementType);
748bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      EmitInitializationToLValue(E->getInit(i), elementLV);
749bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    }
750bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
751bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Check whether there's a non-trivial array-fill expression.
752bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Note that this will be a CXXConstructExpr even if the element
753bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // type is an array (or array of array, etc.) of class type.
754bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    Expr *filler = E->getArrayFiller();
755bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    bool hasTrivialFiller = true;
756bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
757bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      assert(cons->getConstructor()->isDefaultConstructor());
758bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      hasTrivialFiller = cons->getConstructor()->isTrivial();
759bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    }
760bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
761bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Any remaining elements need to be zero-initialized, possibly
762bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // using the filler expression.  We can skip this if the we're
763bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // emitting to zeroed memory.
764bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    if (NumInitElements != NumArrayElements &&
765bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        !(Dest.isZeroed() && hasTrivialFiller &&
766bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall          CGF.getTypes().isZeroInitializable(elementType))) {
767bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
768bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Use an actual loop.  This is basically
769bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      //   do { *array++ = filler; } while (array != end);
770bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
771bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Advance to the start of the rest of the array.
7722673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      if (NumInitElements) {
773bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
7742673c68aa58e277ebc755b71d81aca618cdedbf9John McCall        if (endOfInit) Builder.CreateStore(element, endOfInit);
7752673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      }
776bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
777bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Compute the end of the array.
778bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::Value *end = Builder.CreateInBoundsGEP(begin,
779bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                        llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
780bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                   "arrayinit.end");
781bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
782bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
783bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
784bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
785bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Jump into the body.
786bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      CGF.EmitBlock(bodyBB);
787bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::PHINode *currentElement =
788bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
789bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      currentElement->addIncoming(element, entryBB);
790bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
791bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Emit the actual filler expression.
792bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
793bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      if (filler)
794bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        EmitInitializationToLValue(filler, elementLV);
795f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      else
796bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        EmitNullInitializationToLValue(elementLV);
797bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
798bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Move on to the next element.
799bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::Value *nextElement =
800bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall        Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");
801bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
8022673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      // Tell the EH cleanup that we finished with the last element.
8032673c68aa58e277ebc755b71d81aca618cdedbf9John McCall      if (endOfInit) Builder.CreateStore(nextElement, endOfInit);
8042673c68aa58e277ebc755b71d81aca618cdedbf9John McCall
805bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      // Leave the loop if we're done.
806bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
807bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                               "arrayinit.done");
808bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
809bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      Builder.CreateCondBr(done, endBB, bodyBB);
810bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
811bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
812bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall      CGF.EmitBlock(endBB);
813f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    }
814bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
815bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    // Leave the partial-array cleanup if we entered one.
816bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall    if (dtorKind) CGF.DeactivateCleanupBlock(cleanup);
817bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
818305762c08975cd6e0bebd684ca910fa208792483Lauro Ramos Venancio    return;
819f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  }
8201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
821f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  assert(E->getType()->isRecordType() && "Only support structs/unions here!");
8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
823f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Do struct initialization; this code just sets each individual member
824f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // to the approprate value.  This makes bitfield support automatic;
825f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // the disadvantage is that the generated code is more difficult for
826f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // the optimizer, especially with bitfields.
827f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  unsigned NumInitElements = E->getNumInits();
8282b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl();
829bd7de38eae1fc20ee88db63f469c54241bc240f8Chris Lattner
8302b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  if (record->isUnion()) {
8310bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // Only initialize one field of a union. The field itself is
8320bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // specified by the initializer list.
8330bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    if (!E->getInitializedFieldInUnion()) {
8340bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Empty union; we have nothing to do.
8351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8360bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor#ifndef NDEBUG
8370bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Make sure that it's really an empty and not a failure of
8380bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // semantic analysis.
8392b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      for (RecordDecl::field_iterator Field = record->field_begin(),
8402b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall                                   FieldEnd = record->field_end();
8410bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor           Field != FieldEnd; ++Field)
8420bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
8430bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor#endif
8440bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      return;
8450bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    }
8460bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
8470bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    // FIXME: volatility
8480bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    FieldDecl *Field = E->getInitializedFieldInUnion();
8490bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
8501b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
8510bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    if (NumInitElements) {
8520bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor      // Store the initializer into the field
853a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall      EmitInitializationToLValue(E->getInit(0), FieldLoc);
8540bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    } else {
8551b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      // Default-initialize to null.
856a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall      EmitNullInitializationToLValue(FieldLoc);
8570bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    }
8580bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor
8590bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor    return;
8600bb76897bedb8b747efc6523efb432fc24966118Douglas Gregor  }
8611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8622b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  // We'll need to enter cleanup scopes in case any of the member
8632b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  // initializers throw an exception.
8645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
8652b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall
866f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // Here we iterate over the fields; this makes it simpler to both
867f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner  // default-initialize fields and skip over unnamed fields.
8682b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  unsigned curInitIndex = 0;
8692b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  for (RecordDecl::field_iterator field = record->field_begin(),
8702b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall                               fieldEnd = record->field_end();
8712b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall       field != fieldEnd; ++field) {
8722b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // We're done once we hit the flexible array member.
8732b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (field->getType()->isIncompleteArrayType())
87444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      break;
87544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
8762b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // Always skip anonymous bitfields.
8772b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (field->isUnnamedBitfield())
878f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      continue;
87934e7946831a63f96d3ba3478c74ca8e25ee52d7eDouglas Gregor
8802b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // We're done if we reach the end of the explicit initializers, we
8812b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // have a zeroed object, and the rest of the fields are
8822b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // zero-initializable.
8832b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (curInitIndex == NumInitElements && Dest.isZeroed() &&
8841b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        CGF.getTypes().isZeroInitializable(E->getType()))
8851b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      break;
8861b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8871e692ace08959399794363e77499b73da5494af9Eli Friedman    // FIXME: volatility
8882b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0);
88914674ffb81dccbc4e1bf78ab5b7987685819b445Fariborz Jahanian    // We never generate write-barries for initialized fields.
8902b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    LV.setNonGC(true);
8911b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
8922b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (curInitIndex < NumInitElements) {
893b35baae19b906245b5c2266b47ef411abcc6b25aChris Lattner      // Store the initializer into the field.
8942b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      EmitInitializationToLValue(E->getInit(curInitIndex++), LV);
895f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    } else {
896f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner      // We're out of initalizers; default-initialize to null
8972b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      EmitNullInitializationToLValue(LV);
8982b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    }
8992b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall
9002b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // Push a destructor if necessary.
9012b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // FIXME: if we have an array of structures, all explicitly
9022b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    // initialized, we can end up pushing a linear number of cleanups.
9032b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    bool pushedCleanup = false;
9042b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (QualType::DestructionKind dtorKind
9052b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall          = field->getType().isDestructedType()) {
9062b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      assert(LV.isSimple());
9072b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      if (CGF.needsEHCleanup(dtorKind)) {
9082b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall        CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(),
9092b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall                        CGF.getDestroyer(dtorKind), false);
9102b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall        cleanups.push_back(CGF.EHStack.stable_begin());
9112b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall        pushedCleanup = true;
9122b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall      }
913f81557cb719dd0d1ce3713f050fb76b0a0cb729aChris Lattner    }
9141b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
9151b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // If the GEP didn't get used because of a dead zero init or something
9161b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    // else, clean it up for -O0 builds and general tidiness.
9172b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    if (!pushedCleanup && LV.isSimple())
9181b726771d00762fb5c4c2638e60d134c385493aeChris Lattner      if (llvm::GetElementPtrInst *GEP =
9192b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall            dyn_cast<llvm::GetElementPtrInst>(LV.getAddress()))
9201b726771d00762fb5c4c2638e60d134c385493aeChris Lattner        if (GEP->use_empty())
9211b726771d00762fb5c4c2638e60d134c385493aeChris Lattner          GEP->eraseFromParent();
922145cd89f9233d375381aa13bd28b2d36f83e6181Lauro Ramos Venancio  }
9232b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall
9242b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  // Deactivate all the partial cleanups in reverse order, which
9252b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  // generally means popping them.
9262b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall  for (unsigned i = cleanups.size(); i != 0; --i)
9272b30dcfb769e4015f8d41c5c9a4e723ff3d522a0John McCall    CGF.DeactivateCleanupBlock(cleanups[i-1]);
928636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel}
929636c3d04673da8c8605d7e45640a2ff7aec648f1Devang Patel
930ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
931ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//                        Entry Points into this File
932ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner//===----------------------------------------------------------------------===//
933ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner
9341b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// GetNumNonZeroBytesInInit - Get an approximate count of the number of
9351b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// non-zero bytes that will be stored when outputting the initializer for the
9361b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// specified initializer expression.
93702c45333b8310bb792a15f85f219706025f9752cKen Dyckstatic CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
938f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne  E = E->IgnoreParens();
9391b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
9401b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // 0 and 0.0 won't require any non-zero stores!
94102c45333b8310bb792a15f85f219706025f9752cKen Dyck  if (isSimpleZero(E, CGF)) return CharUnits::Zero();
9421b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
9431b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If this is an initlist expr, sum up the size of sizes of the (present)
9441b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // elements.  If this is something weird, assume the whole thing is non-zero.
9451b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
9461b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType()))
94702c45333b8310bb792a15f85f219706025f9752cKen Dyck    return CGF.getContext().getTypeSizeInChars(E->getType());
9481b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
949d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // InitListExprs for structs have to be handled carefully.  If there are
950d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // reference members, we need to consider the size of the reference, not the
951d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  // referencee.  InitListExprs for unions and arrays can't have references.
9528c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner  if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
9538c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner    if (!RT->isUnionType()) {
9548c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
95502c45333b8310bb792a15f85f219706025f9752cKen Dyck      CharUnits NumNonZeroBytes = CharUnits::Zero();
956d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
9578c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      unsigned ILEElement = 0;
9588c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      for (RecordDecl::field_iterator Field = SD->field_begin(),
9598c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner           FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) {
9608c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // We're done once we hit the flexible array member or run out of
9618c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // InitListExpr elements.
9628c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->getType()->isIncompleteArrayType() ||
9638c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner            ILEElement == ILE->getNumInits())
9648c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          break;
9658c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->isUnnamedBitfield())
9668c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          continue;
9678c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner
9688c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        const Expr *E = ILE->getInit(ILEElement++);
9698c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner
9708c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        // Reference values are always non-null and have the width of a pointer.
9718c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        if (Field->getType()->isReferenceType())
97202c45333b8310bb792a15f85f219706025f9752cKen Dyck          NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits(
973bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor              CGF.getContext().getTargetInfo().getPointerWidth(0));
9748c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner        else
9758c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner          NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF);
9768c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      }
977d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
9788c00ad1e3897e8a00f41bbd52135be8390d5c15cChris Lattner      return NumNonZeroBytes;
979d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner    }
980d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner  }
981d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
982d1d56df188e25c633f9bc65d229897b42442b0f7Chris Lattner
98302c45333b8310bb792a15f85f219706025f9752cKen Dyck  CharUnits NumNonZeroBytes = CharUnits::Zero();
9841b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
9851b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF);
9861b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  return NumNonZeroBytes;
9871b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
9881b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
9891b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// CheckAggExprForMemSetUse - If the initializer is large and has a lot of
9901b726771d00762fb5c4c2638e60d134c385493aeChris Lattner/// zeros in it, emit a memset and avoid storing the individual zeros.
9911b726771d00762fb5c4c2638e60d134c385493aeChris Lattner///
9921b726771d00762fb5c4c2638e60d134c385493aeChris Lattnerstatic void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
9931b726771d00762fb5c4c2638e60d134c385493aeChris Lattner                                     CodeGenFunction &CGF) {
9941b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the slot is already known to be zeroed, nothing to do.  Don't mess with
9951b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // volatile stores.
9961b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return;
997657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis
998657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis  // C++ objects with a user-declared constructor don't need zero'ing.
999657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis  if (CGF.getContext().getLangOptions().CPlusPlus)
1000657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis    if (const RecordType *RT = CGF.getContext()
1001657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis                       .getBaseElementType(E->getType())->getAs<RecordType>()) {
1002657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis      const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1003657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis      if (RD->hasUserDeclaredConstructor())
1004657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis        return;
1005657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis    }
1006657baf19ca8a48a926bd3bc148b6ad1b17e53199Argyrios Kyrtzidis
10071b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // If the type is 16-bytes or smaller, prefer individual stores over memset.
10085ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  std::pair<CharUnits, CharUnits> TypeInfo =
10095ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck    CGF.getContext().getTypeInfoInChars(E->getType());
10105ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  if (TypeInfo.first <= CharUnits::fromQuantity(16))
10111b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
10121b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10131b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Check to see if over 3/4 of the initializer are known to be zero.  If so,
10141b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // we prefer to emit memset + individual stores for the rest.
10155ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  CharUnits NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF);
10165ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  if (NumNonZeroBytes*4 > TypeInfo.first)
10171b726771d00762fb5c4c2638e60d134c385493aeChris Lattner    return;
10181b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10191b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Okay, it seems like a good idea to use an initial memset, emit the call.
10205ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first.getQuantity());
10215ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  CharUnits Align = TypeInfo.second;
10221b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10231b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  llvm::Value *Loc = Slot.getAddr();
10242acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
10251b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10261b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  Loc = CGF.Builder.CreateBitCast(Loc, BP);
10275ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck  CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal,
10285ff1a3508b39cfe3c9d108679a6532d85586b5ceKen Dyck                           Align.getQuantity(), false);
10291b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10301b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Tell the AggExprEmitter that the slot is known zero.
10311b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  Slot.setZeroed();
10321b726771d00762fb5c4c2638e60d134c385493aeChris Lattner}
10331b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10341b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10351b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10361b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
1037e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// EmitAggExpr - Emit the computation of the specified expression of aggregate
1038e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
1039e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// the value of the aggregate expression is not needed.  If VolatileDest is
1040e1129a92b25f9b05f1b97fdd81d38ea451875414Mike Stump/// true, DestPtr cannot be 0.
1041558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall///
1042558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall/// \param IsInitializer - true if this evaluation is initializing an
1043558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall/// object whose lifetime is already being managed.
1044558d2abc7f9fd6801cc7677200992313ae90b5d8John McCallvoid CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
1045474e2fe4957e6e72cee36ed189eaf21878ad0e91Fariborz Jahanian                                  bool IgnoreResult) {
1046ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner  assert(E && hasAggregateLLVMType(E->getType()) &&
1047ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner         "Invalid aggregate expression to emit");
10481b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  assert((Slot.getAddr() != 0 || Slot.isIgnored()) &&
10491b726771d00762fb5c4c2638e60d134c385493aeChris Lattner         "slot has bits but no address");
10501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10511b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  // Optimize the slot if possible.
10521b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  CheckAggExprForMemSetUse(Slot, E, *this);
10531b726771d00762fb5c4c2638e60d134c385493aeChris Lattner
10541b726771d00762fb5c4c2638e60d134c385493aeChris Lattner  AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E));
1055ee755f9118c4061b21e0a787d4a20484df36f603Chris Lattner}
10567482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar
105718aba0dd518e486d8b50523e7dafb4b5657135d2Daniel DunbarLValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
105818aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar  assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
1059195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *Temp = CreateMemTemp(E->getType());
106079c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  LValue LV = MakeAddrLValue(Temp, E->getType());
10617c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall  EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed,
10624418439220a8f8e0b1deffdccce2354854c702f5John McCall                                         AggValueSlot::DoesNotNeedGCBarriers,
10634418439220a8f8e0b1deffdccce2354854c702f5John McCall                                         AggValueSlot::IsNotAliased));
106479c3928d816f317dd27109fb92e7d190c1c68329Daniel Dunbar  return LV;
106518aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar}
106618aba0dd518e486d8b50523e7dafb4b5657135d2Daniel Dunbar
10677482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbarvoid CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
106827fe2e6c97a3782a0639d87b460741e8ba5d076dMike Stump                                        llvm::Value *SrcPtr, QualType Ty,
106927fe2e6c97a3782a0639d87b460741e8ba5d076dMike Stump                                        bool isVolatile) {
10707482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10720d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson  if (getContext().getLangOptions().CPlusPlus) {
10730d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson    if (const RecordType *RT = Ty->getAs<RecordType>()) {
1074e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
1075e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      assert((Record->hasTrivialCopyConstructor() ||
1076b2b5658a8e4ad566303ec98caceaa3485e7635f7Douglas Gregor              Record->hasTrivialCopyAssignment() ||
1077b2b5658a8e4ad566303ec98caceaa3485e7635f7Douglas Gregor              Record->hasTrivialMoveConstructor() ||
1078b2b5658a8e4ad566303ec98caceaa3485e7635f7Douglas Gregor              Record->hasTrivialMoveAssignment()) &&
1079e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor             "Trying to aggregate-copy a type without a trivial copy "
1080e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor             "constructor or assignment operator");
1081419aa964ae845aa5b1183fabb2f1cff78faaedddDouglas Gregor      // Ignore empty classes in C++.
1082e9979484670ca2b528146d1b681e149fdc29f7ccDouglas Gregor      if (Record->isEmpty())
10830d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson        return;
10840d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson    }
10850d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson  }
10860d7c583a4b4d0f57c6b69c66fd73babec4ef3799Anders Carlsson
108783c9629291e3f4d4619fa98f8a57e4ec347c6154Chris Lattner  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
1088ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // C99 6.5.16.1p3, which states "If the value being stored in an object is
1089ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // read from another object that overlaps in anyway the storage of the first
1090ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // object, then the overlap shall be exact and the two objects shall have
1091ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // qualified or unqualified versions of a compatible type."
1092ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  //
109383c9629291e3f4d4619fa98f8a57e4ec347c6154Chris Lattner  // memcpy is not defined if the source and destination pointers are exactly
1094ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // equal, but other compilers do this optimization, and almost every memcpy
1095ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // implementation handles this case safely.  If there is a libc that does not
1096ca4fc2c2620e184e8b96845a87b19d54f9e045c1Chris Lattner  // safely handle this, we can add a target hook.
10971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10987482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  // Get size and alignment info for this aggregate.
10991a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck  std::pair<CharUnits, CharUnits> TypeInfo =
11001a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck    getContext().getTypeInfoInChars(Ty);
11011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11027482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar  // FIXME: Handle variable sized types.
11031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1104fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // FIXME: If we have a volatile struct, the optimizer can remove what might
1105fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // appear to be `extra' memory ops:
1106fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
1107fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // volatile struct { int i; } a, b;
1108fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
1109fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // int main() {
1110fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //   a = b;
1111fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //   a = b;
1112fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  // }
1113fde6420cb9142f7f4efe5ec69a216295d83bcda4Mike Stump  //
11143ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang  // we need to use a different call here.  We use isVolatile to indicate when
111549d1cd5a09ed3df353371fd7f206674a85e0fb45Mike Stump  // either the source or the destination is volatile.
11163ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
11172acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
11182acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *DBP =
1119d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall    llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace());
1120578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  DestPtr = Builder.CreateBitCast(DestPtr, DBP);
11213ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
11222acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
11232acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *SBP =
1124d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall    llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace());
1125578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP);
11263ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang
1127f85e193739c953358c865005855253af4f68a497John McCall  // Don't do any of the memmove_collectable tests if GC isn't set.
1128e289d81369914678db386f6aa86faf8f178e245dDouglas Gregor  if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
1129f85e193739c953358c865005855253af4f68a497John McCall    // fall through
1130f85e193739c953358c865005855253af4f68a497John McCall  } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
113155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    RecordDecl *Record = RecordTy->getDecl();
113255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    if (Record->hasObjectMember()) {
11331a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck      CharUnits size = TypeInfo.first;
11342acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner      llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
11351a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck      llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
113655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
113755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                                    SizeVal);
113855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      return;
113955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    }
1140f85e193739c953358c865005855253af4f68a497John McCall  } else if (Ty->isArrayType()) {
114155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    QualType BaseType = getContext().getBaseElementType(Ty);
114255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
114355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      if (RecordTy->getDecl()->hasObjectMember()) {
11441a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck        CharUnits size = TypeInfo.first;
11452acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner        llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
11461a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck        llvm::Value *SizeVal =
11471a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck          llvm::ConstantInt::get(SizeTy, size.getQuantity());
114855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
114955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian                                                      SizeVal);
115055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian        return;
115155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian      }
115255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian    }
115355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian  }
115455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian
11559f0c7cc36d29cf591c33962931f5862847145f3eBenjamin Kramer  Builder.CreateMemCpy(DestPtr, SrcPtr,
11561a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck                       llvm::ConstantInt::get(IntPtrTy,
11571a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck                                              TypeInfo.first.getQuantity()),
11581a8c15a8b7f7c6d851e0d3dd1b86d5f78515ffa4Ken Dyck                       TypeInfo.second.getQuantity(), isVolatile);
11597482d12c345c6391f8956850545e2d4aa7701ce6Daniel Dunbar}
1160