xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/CGExprAgg.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This contains code to emit Aggregate Expr nodes as LLVM code.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "CodeGenFunction.h"
15f4a2713aSLionel Sambuc #include "CGObjCRuntime.h"
16f4a2713aSLionel Sambuc #include "CodeGenModule.h"
17f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
20f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
21f4a2713aSLionel Sambuc #include "llvm/IR/Constants.h"
22f4a2713aSLionel Sambuc #include "llvm/IR/Function.h"
23f4a2713aSLionel Sambuc #include "llvm/IR/GlobalVariable.h"
24f4a2713aSLionel Sambuc #include "llvm/IR/Intrinsics.h"
25f4a2713aSLionel Sambuc using namespace clang;
26f4a2713aSLionel Sambuc using namespace CodeGen;
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
29f4a2713aSLionel Sambuc //                        Aggregate Expression Emitter
30f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc namespace  {
33f4a2713aSLionel Sambuc class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
34f4a2713aSLionel Sambuc   CodeGenFunction &CGF;
35f4a2713aSLionel Sambuc   CGBuilderTy &Builder;
36f4a2713aSLionel Sambuc   AggValueSlot Dest;
37f4a2713aSLionel Sambuc 
38f4a2713aSLionel Sambuc   /// We want to use 'dest' as the return slot except under two
39f4a2713aSLionel Sambuc   /// conditions:
40f4a2713aSLionel Sambuc   ///   - The destination slot requires garbage collection, so we
41f4a2713aSLionel Sambuc   ///     need to use the GC API.
42f4a2713aSLionel Sambuc   ///   - The destination slot is potentially aliased.
shouldUseDestForReturnSlot() const43f4a2713aSLionel Sambuc   bool shouldUseDestForReturnSlot() const {
44f4a2713aSLionel Sambuc     return !(Dest.requiresGCollection() || Dest.isPotentiallyAliased());
45f4a2713aSLionel Sambuc   }
46f4a2713aSLionel Sambuc 
getReturnValueSlot() const47f4a2713aSLionel Sambuc   ReturnValueSlot getReturnValueSlot() const {
48f4a2713aSLionel Sambuc     if (!shouldUseDestForReturnSlot())
49f4a2713aSLionel Sambuc       return ReturnValueSlot();
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc     return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
52f4a2713aSLionel Sambuc   }
53f4a2713aSLionel Sambuc 
EnsureSlot(QualType T)54f4a2713aSLionel Sambuc   AggValueSlot EnsureSlot(QualType T) {
55f4a2713aSLionel Sambuc     if (!Dest.isIgnored()) return Dest;
56f4a2713aSLionel Sambuc     return CGF.CreateAggTemp(T, "agg.tmp.ensured");
57f4a2713aSLionel Sambuc   }
EnsureDest(QualType T)58f4a2713aSLionel Sambuc   void EnsureDest(QualType T) {
59f4a2713aSLionel Sambuc     if (!Dest.isIgnored()) return;
60f4a2713aSLionel Sambuc     Dest = CGF.CreateAggTemp(T, "agg.tmp.ensured");
61f4a2713aSLionel Sambuc   }
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc public:
AggExprEmitter(CodeGenFunction & cgf,AggValueSlot Dest)64f4a2713aSLionel Sambuc   AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest)
65f4a2713aSLionel Sambuc     : CGF(cgf), Builder(CGF.Builder), Dest(Dest) {
66f4a2713aSLionel Sambuc   }
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
69f4a2713aSLionel Sambuc   //                               Utilities
70f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc   /// EmitAggLoadOfLValue - Given an expression with aggregate type that
73f4a2713aSLionel Sambuc   /// represents a value lvalue, this method emits the address of the lvalue,
74f4a2713aSLionel Sambuc   /// then loads the result into DestPtr.
75f4a2713aSLionel Sambuc   void EmitAggLoadOfLValue(const Expr *E);
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc   /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
78f4a2713aSLionel Sambuc   void EmitFinalDestCopy(QualType type, const LValue &src);
79f4a2713aSLionel Sambuc   void EmitFinalDestCopy(QualType type, RValue src,
80f4a2713aSLionel Sambuc                          CharUnits srcAlignment = CharUnits::Zero());
81f4a2713aSLionel Sambuc   void EmitCopy(QualType type, const AggValueSlot &dest,
82f4a2713aSLionel Sambuc                 const AggValueSlot &src);
83f4a2713aSLionel Sambuc 
84f4a2713aSLionel Sambuc   void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   void EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
87f4a2713aSLionel Sambuc                      QualType elementType, InitListExpr *E);
88f4a2713aSLionel Sambuc 
needsGC(QualType T)89f4a2713aSLionel Sambuc   AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
90f4a2713aSLionel Sambuc     if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
91f4a2713aSLionel Sambuc       return AggValueSlot::NeedsGCBarriers;
92f4a2713aSLionel Sambuc     return AggValueSlot::DoesNotNeedGCBarriers;
93f4a2713aSLionel Sambuc   }
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc   bool TypeRequiresGCollection(QualType T);
96f4a2713aSLionel Sambuc 
97f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
98f4a2713aSLionel Sambuc   //                            Visitor Methods
99f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
100f4a2713aSLionel Sambuc 
VisitStmt(Stmt * S)101f4a2713aSLionel Sambuc   void VisitStmt(Stmt *S) {
102f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(S, "aggregate expression");
103f4a2713aSLionel Sambuc   }
VisitParenExpr(ParenExpr * PE)104f4a2713aSLionel Sambuc   void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)105f4a2713aSLionel Sambuc   void VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
106f4a2713aSLionel Sambuc     Visit(GE->getResultExpr());
107f4a2713aSLionel Sambuc   }
VisitUnaryExtension(UnaryOperator * E)108f4a2713aSLionel Sambuc   void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)109f4a2713aSLionel Sambuc   void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
110f4a2713aSLionel Sambuc     return Visit(E->getReplacement());
111f4a2713aSLionel Sambuc   }
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc   // l-values.
VisitDeclRefExpr(DeclRefExpr * E)114f4a2713aSLionel Sambuc   void VisitDeclRefExpr(DeclRefExpr *E) {
115f4a2713aSLionel Sambuc     // For aggregates, we should always be able to emit the variable
116f4a2713aSLionel Sambuc     // as an l-value unless it's a reference.  This is due to the fact
117f4a2713aSLionel Sambuc     // that we can't actually ever see a normal l2r conversion on an
118f4a2713aSLionel Sambuc     // aggregate in C++, and in C there's no language standard
119f4a2713aSLionel Sambuc     // actively preventing us from listing variables in the captures
120f4a2713aSLionel Sambuc     // list of a block.
121f4a2713aSLionel Sambuc     if (E->getDecl()->getType()->isReferenceType()) {
122f4a2713aSLionel Sambuc       if (CodeGenFunction::ConstantEmission result
123f4a2713aSLionel Sambuc             = CGF.tryEmitAsConstant(E)) {
124f4a2713aSLionel Sambuc         EmitFinalDestCopy(E->getType(), result.getReferenceLValue(CGF, E));
125f4a2713aSLionel Sambuc         return;
126f4a2713aSLionel Sambuc       }
127f4a2713aSLionel Sambuc     }
128f4a2713aSLionel Sambuc 
129f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
130f4a2713aSLionel Sambuc   }
131f4a2713aSLionel Sambuc 
VisitMemberExpr(MemberExpr * ME)132f4a2713aSLionel Sambuc   void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
VisitUnaryDeref(UnaryOperator * E)133f4a2713aSLionel Sambuc   void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
VisitStringLiteral(StringLiteral * E)134f4a2713aSLionel Sambuc   void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
135f4a2713aSLionel Sambuc   void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
VisitArraySubscriptExpr(ArraySubscriptExpr * E)136f4a2713aSLionel Sambuc   void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
137f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
138f4a2713aSLionel Sambuc   }
VisitPredefinedExpr(const PredefinedExpr * E)139f4a2713aSLionel Sambuc   void VisitPredefinedExpr(const PredefinedExpr *E) {
140f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
141f4a2713aSLionel Sambuc   }
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc   // Operators.
144f4a2713aSLionel Sambuc   void VisitCastExpr(CastExpr *E);
145f4a2713aSLionel Sambuc   void VisitCallExpr(const CallExpr *E);
146f4a2713aSLionel Sambuc   void VisitStmtExpr(const StmtExpr *E);
147f4a2713aSLionel Sambuc   void VisitBinaryOperator(const BinaryOperator *BO);
148f4a2713aSLionel Sambuc   void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
149f4a2713aSLionel Sambuc   void VisitBinAssign(const BinaryOperator *E);
150f4a2713aSLionel Sambuc   void VisitBinComma(const BinaryOperator *E);
151f4a2713aSLionel Sambuc 
152f4a2713aSLionel Sambuc   void VisitObjCMessageExpr(ObjCMessageExpr *E);
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)153f4a2713aSLionel Sambuc   void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
154f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
155f4a2713aSLionel Sambuc   }
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
158f4a2713aSLionel Sambuc   void VisitChooseExpr(const ChooseExpr *CE);
159f4a2713aSLionel Sambuc   void VisitInitListExpr(InitListExpr *E);
160f4a2713aSLionel Sambuc   void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)161f4a2713aSLionel Sambuc   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
162f4a2713aSLionel Sambuc     Visit(DAE->getExpr());
163f4a2713aSLionel Sambuc   }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)164f4a2713aSLionel Sambuc   void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
165f4a2713aSLionel Sambuc     CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
166f4a2713aSLionel Sambuc     Visit(DIE->getExpr());
167f4a2713aSLionel Sambuc   }
168f4a2713aSLionel Sambuc   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
169f4a2713aSLionel Sambuc   void VisitCXXConstructExpr(const CXXConstructExpr *E);
170f4a2713aSLionel Sambuc   void VisitLambdaExpr(LambdaExpr *E);
171f4a2713aSLionel Sambuc   void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
172f4a2713aSLionel Sambuc   void VisitExprWithCleanups(ExprWithCleanups *E);
173f4a2713aSLionel Sambuc   void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
VisitCXXTypeidExpr(CXXTypeidExpr * E)174f4a2713aSLionel Sambuc   void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
175f4a2713aSLionel Sambuc   void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
176f4a2713aSLionel Sambuc   void VisitOpaqueValueExpr(OpaqueValueExpr *E);
177f4a2713aSLionel Sambuc 
VisitPseudoObjectExpr(PseudoObjectExpr * E)178f4a2713aSLionel Sambuc   void VisitPseudoObjectExpr(PseudoObjectExpr *E) {
179f4a2713aSLionel Sambuc     if (E->isGLValue()) {
180f4a2713aSLionel Sambuc       LValue LV = CGF.EmitPseudoObjectLValue(E);
181f4a2713aSLionel Sambuc       return EmitFinalDestCopy(E->getType(), LV);
182f4a2713aSLionel Sambuc     }
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc     CGF.EmitPseudoObjectRValue(E, EnsureSlot(E->getType()));
185f4a2713aSLionel Sambuc   }
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc   void VisitVAArgExpr(VAArgExpr *E);
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc   void EmitInitializationToLValue(Expr *E, LValue Address);
190f4a2713aSLionel Sambuc   void EmitNullInitializationToLValue(LValue Address);
191f4a2713aSLionel Sambuc   //  case Expr::ChooseExprClass:
VisitCXXThrowExpr(const CXXThrowExpr * E)192f4a2713aSLionel Sambuc   void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
VisitAtomicExpr(AtomicExpr * E)193f4a2713aSLionel Sambuc   void VisitAtomicExpr(AtomicExpr *E) {
194f4a2713aSLionel Sambuc     CGF.EmitAtomicExpr(E, EnsureSlot(E->getType()).getAddr());
195f4a2713aSLionel Sambuc   }
196f4a2713aSLionel Sambuc };
197f4a2713aSLionel Sambuc }  // end anonymous namespace.
198f4a2713aSLionel Sambuc 
199f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
200f4a2713aSLionel Sambuc //                                Utilities
201f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc /// EmitAggLoadOfLValue - Given an expression with aggregate type that
204f4a2713aSLionel Sambuc /// represents a value lvalue, this method emits the address of the lvalue,
205f4a2713aSLionel Sambuc /// then loads the result into DestPtr.
EmitAggLoadOfLValue(const Expr * E)206f4a2713aSLionel Sambuc void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
207f4a2713aSLionel Sambuc   LValue LV = CGF.EmitLValue(E);
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc   // If the type of the l-value is atomic, then do an atomic load.
210f4a2713aSLionel Sambuc   if (LV.getType()->isAtomicType()) {
211f4a2713aSLionel Sambuc     CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);
212f4a2713aSLionel Sambuc     return;
213f4a2713aSLionel Sambuc   }
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc   EmitFinalDestCopy(E->getType(), LV);
216f4a2713aSLionel Sambuc }
217f4a2713aSLionel Sambuc 
218f4a2713aSLionel Sambuc /// \brief True if the given aggregate type requires special GC API calls.
TypeRequiresGCollection(QualType T)219f4a2713aSLionel Sambuc bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
220f4a2713aSLionel Sambuc   // Only record types have members that might require garbage collection.
221f4a2713aSLionel Sambuc   const RecordType *RecordTy = T->getAs<RecordType>();
222f4a2713aSLionel Sambuc   if (!RecordTy) return false;
223f4a2713aSLionel Sambuc 
224f4a2713aSLionel Sambuc   // Don't mess with non-trivial C++ types.
225f4a2713aSLionel Sambuc   RecordDecl *Record = RecordTy->getDecl();
226f4a2713aSLionel Sambuc   if (isa<CXXRecordDecl>(Record) &&
227f4a2713aSLionel Sambuc       (cast<CXXRecordDecl>(Record)->hasNonTrivialCopyConstructor() ||
228f4a2713aSLionel Sambuc        !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
229f4a2713aSLionel Sambuc     return false;
230f4a2713aSLionel Sambuc 
231f4a2713aSLionel Sambuc   // Check whether the type has an object member.
232f4a2713aSLionel Sambuc   return Record->hasObjectMember();
233f4a2713aSLionel Sambuc }
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc /// \brief Perform the final move to DestPtr if for some reason
236f4a2713aSLionel Sambuc /// getReturnValueSlot() didn't use it directly.
237f4a2713aSLionel Sambuc ///
238f4a2713aSLionel Sambuc /// The idea is that you do something like this:
239f4a2713aSLionel Sambuc ///   RValue Result = EmitSomething(..., getReturnValueSlot());
240f4a2713aSLionel Sambuc ///   EmitMoveFromReturnSlot(E, Result);
241f4a2713aSLionel Sambuc ///
242f4a2713aSLionel Sambuc /// If nothing interferes, this will cause the result to be emitted
243f4a2713aSLionel Sambuc /// directly into the return value slot.  Otherwise, a final move
244f4a2713aSLionel Sambuc /// will be performed.
EmitMoveFromReturnSlot(const Expr * E,RValue src)245f4a2713aSLionel Sambuc void AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue src) {
246f4a2713aSLionel Sambuc   if (shouldUseDestForReturnSlot()) {
247f4a2713aSLionel Sambuc     // Logically, Dest.getAddr() should equal Src.getAggregateAddr().
248f4a2713aSLionel Sambuc     // The possibility of undef rvalues complicates that a lot,
249f4a2713aSLionel Sambuc     // though, so we can't really assert.
250f4a2713aSLionel Sambuc     return;
251f4a2713aSLionel Sambuc   }
252f4a2713aSLionel Sambuc 
253f4a2713aSLionel Sambuc   // Otherwise, copy from there to the destination.
254f4a2713aSLionel Sambuc   assert(Dest.getAddr() != src.getAggregateAddr());
255f4a2713aSLionel Sambuc   std::pair<CharUnits, CharUnits> typeInfo =
256f4a2713aSLionel Sambuc     CGF.getContext().getTypeInfoInChars(E->getType());
257f4a2713aSLionel Sambuc   EmitFinalDestCopy(E->getType(), src, typeInfo.second);
258f4a2713aSLionel Sambuc }
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
EmitFinalDestCopy(QualType type,RValue src,CharUnits srcAlign)261f4a2713aSLionel Sambuc void AggExprEmitter::EmitFinalDestCopy(QualType type, RValue src,
262f4a2713aSLionel Sambuc                                        CharUnits srcAlign) {
263f4a2713aSLionel Sambuc   assert(src.isAggregate() && "value must be aggregate value!");
264f4a2713aSLionel Sambuc   LValue srcLV = CGF.MakeAddrLValue(src.getAggregateAddr(), type, srcAlign);
265f4a2713aSLionel Sambuc   EmitFinalDestCopy(type, srcLV);
266f4a2713aSLionel Sambuc }
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
EmitFinalDestCopy(QualType type,const LValue & src)269f4a2713aSLionel Sambuc void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src) {
270f4a2713aSLionel Sambuc   // If Dest is ignored, then we're evaluating an aggregate expression
271f4a2713aSLionel Sambuc   // in a context that doesn't care about the result.  Note that loads
272f4a2713aSLionel Sambuc   // from volatile l-values force the existence of a non-ignored
273f4a2713aSLionel Sambuc   // destination.
274f4a2713aSLionel Sambuc   if (Dest.isIgnored())
275f4a2713aSLionel Sambuc     return;
276f4a2713aSLionel Sambuc 
277f4a2713aSLionel Sambuc   AggValueSlot srcAgg =
278f4a2713aSLionel Sambuc     AggValueSlot::forLValue(src, AggValueSlot::IsDestructed,
279f4a2713aSLionel Sambuc                             needsGC(type), AggValueSlot::IsAliased);
280f4a2713aSLionel Sambuc   EmitCopy(type, Dest, srcAgg);
281f4a2713aSLionel Sambuc }
282f4a2713aSLionel Sambuc 
283f4a2713aSLionel Sambuc /// Perform a copy from the source into the destination.
284f4a2713aSLionel Sambuc ///
285f4a2713aSLionel Sambuc /// \param type - the type of the aggregate being copied; qualifiers are
286f4a2713aSLionel Sambuc ///   ignored
EmitCopy(QualType type,const AggValueSlot & dest,const AggValueSlot & src)287f4a2713aSLionel Sambuc void AggExprEmitter::EmitCopy(QualType type, const AggValueSlot &dest,
288f4a2713aSLionel Sambuc                               const AggValueSlot &src) {
289f4a2713aSLionel Sambuc   if (dest.requiresGCollection()) {
290f4a2713aSLionel Sambuc     CharUnits sz = CGF.getContext().getTypeSizeInChars(type);
291f4a2713aSLionel Sambuc     llvm::Value *size = llvm::ConstantInt::get(CGF.SizeTy, sz.getQuantity());
292f4a2713aSLionel Sambuc     CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
293f4a2713aSLionel Sambuc                                                       dest.getAddr(),
294f4a2713aSLionel Sambuc                                                       src.getAddr(),
295f4a2713aSLionel Sambuc                                                       size);
296f4a2713aSLionel Sambuc     return;
297f4a2713aSLionel Sambuc   }
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc   // If the result of the assignment is used, copy the LHS there also.
300f4a2713aSLionel Sambuc   // It's volatile if either side is.  Use the minimum alignment of
301f4a2713aSLionel Sambuc   // the two sides.
302f4a2713aSLionel Sambuc   CGF.EmitAggregateCopy(dest.getAddr(), src.getAddr(), type,
303f4a2713aSLionel Sambuc                         dest.isVolatile() || src.isVolatile(),
304f4a2713aSLionel Sambuc                         std::min(dest.getAlignment(), src.getAlignment()));
305f4a2713aSLionel Sambuc }
306f4a2713aSLionel Sambuc 
307f4a2713aSLionel Sambuc /// \brief Emit the initializer for a std::initializer_list initialized with a
308f4a2713aSLionel Sambuc /// real initializer list.
309f4a2713aSLionel Sambuc void
VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr * E)310f4a2713aSLionel Sambuc AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
311f4a2713aSLionel Sambuc   // Emit an array containing the elements.  The array is externally destructed
312f4a2713aSLionel Sambuc   // if the std::initializer_list object is.
313f4a2713aSLionel Sambuc   ASTContext &Ctx = CGF.getContext();
314f4a2713aSLionel Sambuc   LValue Array = CGF.EmitLValue(E->getSubExpr());
315f4a2713aSLionel Sambuc   assert(Array.isSimple() && "initializer_list array not a simple lvalue");
316f4a2713aSLionel Sambuc   llvm::Value *ArrayPtr = Array.getAddress();
317f4a2713aSLionel Sambuc 
318f4a2713aSLionel Sambuc   const ConstantArrayType *ArrayType =
319f4a2713aSLionel Sambuc       Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
320f4a2713aSLionel Sambuc   assert(ArrayType && "std::initializer_list constructed from non-array");
321f4a2713aSLionel Sambuc 
322f4a2713aSLionel Sambuc   // FIXME: Perform the checks on the field types in SemaInit.
323f4a2713aSLionel Sambuc   RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
324f4a2713aSLionel Sambuc   RecordDecl::field_iterator Field = Record->field_begin();
325f4a2713aSLionel Sambuc   if (Field == Record->field_end()) {
326f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "weird std::initializer_list");
327f4a2713aSLionel Sambuc     return;
328f4a2713aSLionel Sambuc   }
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc   // Start pointer.
331f4a2713aSLionel Sambuc   if (!Field->getType()->isPointerType() ||
332f4a2713aSLionel Sambuc       !Ctx.hasSameType(Field->getType()->getPointeeType(),
333f4a2713aSLionel Sambuc                        ArrayType->getElementType())) {
334f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "weird std::initializer_list");
335f4a2713aSLionel Sambuc     return;
336f4a2713aSLionel Sambuc   }
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc   AggValueSlot Dest = EnsureSlot(E->getType());
339f4a2713aSLionel Sambuc   LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),
340f4a2713aSLionel Sambuc                                      Dest.getAlignment());
341f4a2713aSLionel Sambuc   LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
342f4a2713aSLionel Sambuc   llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);
343f4a2713aSLionel Sambuc   llvm::Value *IdxStart[] = { Zero, Zero };
344f4a2713aSLionel Sambuc   llvm::Value *ArrayStart =
345f4a2713aSLionel Sambuc       Builder.CreateInBoundsGEP(ArrayPtr, IdxStart, "arraystart");
346f4a2713aSLionel Sambuc   CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start);
347f4a2713aSLionel Sambuc   ++Field;
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc   if (Field == Record->field_end()) {
350f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "weird std::initializer_list");
351f4a2713aSLionel Sambuc     return;
352f4a2713aSLionel Sambuc   }
353f4a2713aSLionel Sambuc 
354f4a2713aSLionel Sambuc   llvm::Value *Size = Builder.getInt(ArrayType->getSize());
355f4a2713aSLionel Sambuc   LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
356f4a2713aSLionel Sambuc   if (Field->getType()->isPointerType() &&
357f4a2713aSLionel Sambuc       Ctx.hasSameType(Field->getType()->getPointeeType(),
358f4a2713aSLionel Sambuc                       ArrayType->getElementType())) {
359f4a2713aSLionel Sambuc     // End pointer.
360f4a2713aSLionel Sambuc     llvm::Value *IdxEnd[] = { Zero, Size };
361f4a2713aSLionel Sambuc     llvm::Value *ArrayEnd =
362f4a2713aSLionel Sambuc         Builder.CreateInBoundsGEP(ArrayPtr, IdxEnd, "arrayend");
363f4a2713aSLionel Sambuc     CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength);
364f4a2713aSLionel Sambuc   } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {
365f4a2713aSLionel Sambuc     // Length.
366f4a2713aSLionel Sambuc     CGF.EmitStoreThroughLValue(RValue::get(Size), EndOrLength);
367f4a2713aSLionel Sambuc   } else {
368f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "weird std::initializer_list");
369f4a2713aSLionel Sambuc     return;
370f4a2713aSLionel Sambuc   }
371f4a2713aSLionel Sambuc }
372f4a2713aSLionel Sambuc 
373*0a6a1f1dSLionel Sambuc /// \brief Determine if E is a trivial array filler, that is, one that is
374*0a6a1f1dSLionel Sambuc /// equivalent to zero-initialization.
isTrivialFiller(Expr * E)375*0a6a1f1dSLionel Sambuc static bool isTrivialFiller(Expr *E) {
376*0a6a1f1dSLionel Sambuc   if (!E)
377*0a6a1f1dSLionel Sambuc     return true;
378*0a6a1f1dSLionel Sambuc 
379*0a6a1f1dSLionel Sambuc   if (isa<ImplicitValueInitExpr>(E))
380*0a6a1f1dSLionel Sambuc     return true;
381*0a6a1f1dSLionel Sambuc 
382*0a6a1f1dSLionel Sambuc   if (auto *ILE = dyn_cast<InitListExpr>(E)) {
383*0a6a1f1dSLionel Sambuc     if (ILE->getNumInits())
384*0a6a1f1dSLionel Sambuc       return false;
385*0a6a1f1dSLionel Sambuc     return isTrivialFiller(ILE->getArrayFiller());
386*0a6a1f1dSLionel Sambuc   }
387*0a6a1f1dSLionel Sambuc 
388*0a6a1f1dSLionel Sambuc   if (auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
389*0a6a1f1dSLionel Sambuc     return Cons->getConstructor()->isDefaultConstructor() &&
390*0a6a1f1dSLionel Sambuc            Cons->getConstructor()->isTrivial();
391*0a6a1f1dSLionel Sambuc 
392*0a6a1f1dSLionel Sambuc   // FIXME: Are there other cases where we can avoid emitting an initializer?
393*0a6a1f1dSLionel Sambuc   return false;
394*0a6a1f1dSLionel Sambuc }
395*0a6a1f1dSLionel Sambuc 
396f4a2713aSLionel Sambuc /// \brief Emit initialization of an array from an initializer list.
EmitArrayInit(llvm::Value * DestPtr,llvm::ArrayType * AType,QualType elementType,InitListExpr * E)397f4a2713aSLionel Sambuc void AggExprEmitter::EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
398f4a2713aSLionel Sambuc                                    QualType elementType, InitListExpr *E) {
399f4a2713aSLionel Sambuc   uint64_t NumInitElements = E->getNumInits();
400f4a2713aSLionel Sambuc 
401f4a2713aSLionel Sambuc   uint64_t NumArrayElements = AType->getNumElements();
402f4a2713aSLionel Sambuc   assert(NumInitElements <= NumArrayElements);
403f4a2713aSLionel Sambuc 
404f4a2713aSLionel Sambuc   // DestPtr is an array*.  Construct an elementType* by drilling
405f4a2713aSLionel Sambuc   // down a level.
406f4a2713aSLionel Sambuc   llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
407f4a2713aSLionel Sambuc   llvm::Value *indices[] = { zero, zero };
408f4a2713aSLionel Sambuc   llvm::Value *begin =
409f4a2713aSLionel Sambuc     Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");
410f4a2713aSLionel Sambuc 
411f4a2713aSLionel Sambuc   // Exception safety requires us to destroy all the
412f4a2713aSLionel Sambuc   // already-constructed members if an initializer throws.
413f4a2713aSLionel Sambuc   // For that, we'll need an EH cleanup.
414f4a2713aSLionel Sambuc   QualType::DestructionKind dtorKind = elementType.isDestructedType();
415*0a6a1f1dSLionel Sambuc   llvm::AllocaInst *endOfInit = nullptr;
416f4a2713aSLionel Sambuc   EHScopeStack::stable_iterator cleanup;
417*0a6a1f1dSLionel Sambuc   llvm::Instruction *cleanupDominator = nullptr;
418f4a2713aSLionel Sambuc   if (CGF.needsEHCleanup(dtorKind)) {
419f4a2713aSLionel Sambuc     // In principle we could tell the cleanup where we are more
420f4a2713aSLionel Sambuc     // directly, but the control flow can get so varied here that it
421f4a2713aSLionel Sambuc     // would actually be quite complex.  Therefore we go through an
422f4a2713aSLionel Sambuc     // alloca.
423f4a2713aSLionel Sambuc     endOfInit = CGF.CreateTempAlloca(begin->getType(),
424f4a2713aSLionel Sambuc                                      "arrayinit.endOfInit");
425f4a2713aSLionel Sambuc     cleanupDominator = Builder.CreateStore(begin, endOfInit);
426f4a2713aSLionel Sambuc     CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
427f4a2713aSLionel Sambuc                                          CGF.getDestroyer(dtorKind));
428f4a2713aSLionel Sambuc     cleanup = CGF.EHStack.stable_begin();
429f4a2713aSLionel Sambuc 
430f4a2713aSLionel Sambuc   // Otherwise, remember that we didn't need a cleanup.
431f4a2713aSLionel Sambuc   } else {
432f4a2713aSLionel Sambuc     dtorKind = QualType::DK_none;
433f4a2713aSLionel Sambuc   }
434f4a2713aSLionel Sambuc 
435f4a2713aSLionel Sambuc   llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
436f4a2713aSLionel Sambuc 
437f4a2713aSLionel Sambuc   // The 'current element to initialize'.  The invariants on this
438f4a2713aSLionel Sambuc   // variable are complicated.  Essentially, after each iteration of
439f4a2713aSLionel Sambuc   // the loop, it points to the last initialized element, except
440f4a2713aSLionel Sambuc   // that it points to the beginning of the array before any
441f4a2713aSLionel Sambuc   // elements have been initialized.
442f4a2713aSLionel Sambuc   llvm::Value *element = begin;
443f4a2713aSLionel Sambuc 
444f4a2713aSLionel Sambuc   // Emit the explicit initializers.
445f4a2713aSLionel Sambuc   for (uint64_t i = 0; i != NumInitElements; ++i) {
446f4a2713aSLionel Sambuc     // Advance to the next element.
447f4a2713aSLionel Sambuc     if (i > 0) {
448f4a2713aSLionel Sambuc       element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
449f4a2713aSLionel Sambuc 
450f4a2713aSLionel Sambuc       // Tell the cleanup that it needs to destroy up to this
451f4a2713aSLionel Sambuc       // element.  TODO: some of these stores can be trivially
452f4a2713aSLionel Sambuc       // observed to be unnecessary.
453f4a2713aSLionel Sambuc       if (endOfInit) Builder.CreateStore(element, endOfInit);
454f4a2713aSLionel Sambuc     }
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc     LValue elementLV = CGF.MakeAddrLValue(element, elementType);
457f4a2713aSLionel Sambuc     EmitInitializationToLValue(E->getInit(i), elementLV);
458f4a2713aSLionel Sambuc   }
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc   // Check whether there's a non-trivial array-fill expression.
461f4a2713aSLionel Sambuc   Expr *filler = E->getArrayFiller();
462*0a6a1f1dSLionel Sambuc   bool hasTrivialFiller = isTrivialFiller(filler);
463f4a2713aSLionel Sambuc 
464f4a2713aSLionel Sambuc   // Any remaining elements need to be zero-initialized, possibly
465f4a2713aSLionel Sambuc   // using the filler expression.  We can skip this if the we're
466f4a2713aSLionel Sambuc   // emitting to zeroed memory.
467f4a2713aSLionel Sambuc   if (NumInitElements != NumArrayElements &&
468f4a2713aSLionel Sambuc       !(Dest.isZeroed() && hasTrivialFiller &&
469f4a2713aSLionel Sambuc         CGF.getTypes().isZeroInitializable(elementType))) {
470f4a2713aSLionel Sambuc 
471f4a2713aSLionel Sambuc     // Use an actual loop.  This is basically
472f4a2713aSLionel Sambuc     //   do { *array++ = filler; } while (array != end);
473f4a2713aSLionel Sambuc 
474f4a2713aSLionel Sambuc     // Advance to the start of the rest of the array.
475f4a2713aSLionel Sambuc     if (NumInitElements) {
476f4a2713aSLionel Sambuc       element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
477f4a2713aSLionel Sambuc       if (endOfInit) Builder.CreateStore(element, endOfInit);
478f4a2713aSLionel Sambuc     }
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc     // Compute the end of the array.
481f4a2713aSLionel Sambuc     llvm::Value *end = Builder.CreateInBoundsGEP(begin,
482f4a2713aSLionel Sambuc                       llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
483f4a2713aSLionel Sambuc                                                  "arrayinit.end");
484f4a2713aSLionel Sambuc 
485f4a2713aSLionel Sambuc     llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
486f4a2713aSLionel Sambuc     llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
487f4a2713aSLionel Sambuc 
488f4a2713aSLionel Sambuc     // Jump into the body.
489f4a2713aSLionel Sambuc     CGF.EmitBlock(bodyBB);
490f4a2713aSLionel Sambuc     llvm::PHINode *currentElement =
491f4a2713aSLionel Sambuc       Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
492f4a2713aSLionel Sambuc     currentElement->addIncoming(element, entryBB);
493f4a2713aSLionel Sambuc 
494f4a2713aSLionel Sambuc     // Emit the actual filler expression.
495f4a2713aSLionel Sambuc     LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
496f4a2713aSLionel Sambuc     if (filler)
497f4a2713aSLionel Sambuc       EmitInitializationToLValue(filler, elementLV);
498f4a2713aSLionel Sambuc     else
499f4a2713aSLionel Sambuc       EmitNullInitializationToLValue(elementLV);
500f4a2713aSLionel Sambuc 
501f4a2713aSLionel Sambuc     // Move on to the next element.
502f4a2713aSLionel Sambuc     llvm::Value *nextElement =
503f4a2713aSLionel Sambuc       Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");
504f4a2713aSLionel Sambuc 
505f4a2713aSLionel Sambuc     // Tell the EH cleanup that we finished with the last element.
506f4a2713aSLionel Sambuc     if (endOfInit) Builder.CreateStore(nextElement, endOfInit);
507f4a2713aSLionel Sambuc 
508f4a2713aSLionel Sambuc     // Leave the loop if we're done.
509f4a2713aSLionel Sambuc     llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
510f4a2713aSLionel Sambuc                                              "arrayinit.done");
511f4a2713aSLionel Sambuc     llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
512f4a2713aSLionel Sambuc     Builder.CreateCondBr(done, endBB, bodyBB);
513f4a2713aSLionel Sambuc     currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
514f4a2713aSLionel Sambuc 
515f4a2713aSLionel Sambuc     CGF.EmitBlock(endBB);
516f4a2713aSLionel Sambuc   }
517f4a2713aSLionel Sambuc 
518f4a2713aSLionel Sambuc   // Leave the partial-array cleanup if we entered one.
519f4a2713aSLionel Sambuc   if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
520f4a2713aSLionel Sambuc }
521f4a2713aSLionel Sambuc 
522f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
523f4a2713aSLionel Sambuc //                            Visitor Methods
524f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
525f4a2713aSLionel Sambuc 
VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr * E)526f4a2713aSLionel Sambuc void AggExprEmitter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E){
527f4a2713aSLionel Sambuc   Visit(E->GetTemporaryExpr());
528f4a2713aSLionel Sambuc }
529f4a2713aSLionel Sambuc 
VisitOpaqueValueExpr(OpaqueValueExpr * e)530f4a2713aSLionel Sambuc void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
531f4a2713aSLionel Sambuc   EmitFinalDestCopy(e->getType(), CGF.getOpaqueLValueMapping(e));
532f4a2713aSLionel Sambuc }
533f4a2713aSLionel Sambuc 
534f4a2713aSLionel Sambuc void
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)535f4a2713aSLionel Sambuc AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
536f4a2713aSLionel Sambuc   if (Dest.isPotentiallyAliased() &&
537f4a2713aSLionel Sambuc       E->getType().isPODType(CGF.getContext())) {
538f4a2713aSLionel Sambuc     // For a POD type, just emit a load of the lvalue + a copy, because our
539f4a2713aSLionel Sambuc     // compound literal might alias the destination.
540f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
541f4a2713aSLionel Sambuc     return;
542f4a2713aSLionel Sambuc   }
543f4a2713aSLionel Sambuc 
544f4a2713aSLionel Sambuc   AggValueSlot Slot = EnsureSlot(E->getType());
545f4a2713aSLionel Sambuc   CGF.EmitAggExpr(E->getInitializer(), Slot);
546f4a2713aSLionel Sambuc }
547f4a2713aSLionel Sambuc 
548f4a2713aSLionel Sambuc /// Attempt to look through various unimportant expressions to find a
549f4a2713aSLionel Sambuc /// cast of the given kind.
findPeephole(Expr * op,CastKind kind)550f4a2713aSLionel Sambuc static Expr *findPeephole(Expr *op, CastKind kind) {
551f4a2713aSLionel Sambuc   while (true) {
552f4a2713aSLionel Sambuc     op = op->IgnoreParens();
553f4a2713aSLionel Sambuc     if (CastExpr *castE = dyn_cast<CastExpr>(op)) {
554f4a2713aSLionel Sambuc       if (castE->getCastKind() == kind)
555f4a2713aSLionel Sambuc         return castE->getSubExpr();
556f4a2713aSLionel Sambuc       if (castE->getCastKind() == CK_NoOp)
557f4a2713aSLionel Sambuc         continue;
558f4a2713aSLionel Sambuc     }
559*0a6a1f1dSLionel Sambuc     return nullptr;
560f4a2713aSLionel Sambuc   }
561f4a2713aSLionel Sambuc }
562f4a2713aSLionel Sambuc 
VisitCastExpr(CastExpr * E)563f4a2713aSLionel Sambuc void AggExprEmitter::VisitCastExpr(CastExpr *E) {
564f4a2713aSLionel Sambuc   switch (E->getCastKind()) {
565f4a2713aSLionel Sambuc   case CK_Dynamic: {
566f4a2713aSLionel Sambuc     // FIXME: Can this actually happen? We have no test coverage for it.
567f4a2713aSLionel Sambuc     assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
568f4a2713aSLionel Sambuc     LValue LV = CGF.EmitCheckedLValue(E->getSubExpr(),
569f4a2713aSLionel Sambuc                                       CodeGenFunction::TCK_Load);
570f4a2713aSLionel Sambuc     // FIXME: Do we also need to handle property references here?
571f4a2713aSLionel Sambuc     if (LV.isSimple())
572f4a2713aSLionel Sambuc       CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
573f4a2713aSLionel Sambuc     else
574f4a2713aSLionel Sambuc       CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
575f4a2713aSLionel Sambuc 
576f4a2713aSLionel Sambuc     if (!Dest.isIgnored())
577f4a2713aSLionel Sambuc       CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
578f4a2713aSLionel Sambuc     break;
579f4a2713aSLionel Sambuc   }
580f4a2713aSLionel Sambuc 
581f4a2713aSLionel Sambuc   case CK_ToUnion: {
582f4a2713aSLionel Sambuc     if (Dest.isIgnored()) break;
583f4a2713aSLionel Sambuc 
584f4a2713aSLionel Sambuc     // GCC union extension
585f4a2713aSLionel Sambuc     QualType Ty = E->getSubExpr()->getType();
586f4a2713aSLionel Sambuc     QualType PtrTy = CGF.getContext().getPointerType(Ty);
587f4a2713aSLionel Sambuc     llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
588f4a2713aSLionel Sambuc                                                  CGF.ConvertType(PtrTy));
589f4a2713aSLionel Sambuc     EmitInitializationToLValue(E->getSubExpr(),
590f4a2713aSLionel Sambuc                                CGF.MakeAddrLValue(CastPtr, Ty));
591f4a2713aSLionel Sambuc     break;
592f4a2713aSLionel Sambuc   }
593f4a2713aSLionel Sambuc 
594f4a2713aSLionel Sambuc   case CK_DerivedToBase:
595f4a2713aSLionel Sambuc   case CK_BaseToDerived:
596f4a2713aSLionel Sambuc   case CK_UncheckedDerivedToBase: {
597f4a2713aSLionel Sambuc     llvm_unreachable("cannot perform hierarchy conversion in EmitAggExpr: "
598f4a2713aSLionel Sambuc                 "should have been unpacked before we got here");
599f4a2713aSLionel Sambuc   }
600f4a2713aSLionel Sambuc 
601f4a2713aSLionel Sambuc   case CK_NonAtomicToAtomic:
602f4a2713aSLionel Sambuc   case CK_AtomicToNonAtomic: {
603f4a2713aSLionel Sambuc     bool isToAtomic = (E->getCastKind() == CK_NonAtomicToAtomic);
604f4a2713aSLionel Sambuc 
605f4a2713aSLionel Sambuc     // Determine the atomic and value types.
606f4a2713aSLionel Sambuc     QualType atomicType = E->getSubExpr()->getType();
607f4a2713aSLionel Sambuc     QualType valueType = E->getType();
608f4a2713aSLionel Sambuc     if (isToAtomic) std::swap(atomicType, valueType);
609f4a2713aSLionel Sambuc 
610f4a2713aSLionel Sambuc     assert(atomicType->isAtomicType());
611f4a2713aSLionel Sambuc     assert(CGF.getContext().hasSameUnqualifiedType(valueType,
612f4a2713aSLionel Sambuc                           atomicType->castAs<AtomicType>()->getValueType()));
613f4a2713aSLionel Sambuc 
614f4a2713aSLionel Sambuc     // Just recurse normally if we're ignoring the result or the
615f4a2713aSLionel Sambuc     // atomic type doesn't change representation.
616f4a2713aSLionel Sambuc     if (Dest.isIgnored() || !CGF.CGM.isPaddedAtomicType(atomicType)) {
617f4a2713aSLionel Sambuc       return Visit(E->getSubExpr());
618f4a2713aSLionel Sambuc     }
619f4a2713aSLionel Sambuc 
620f4a2713aSLionel Sambuc     CastKind peepholeTarget =
621f4a2713aSLionel Sambuc       (isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
622f4a2713aSLionel Sambuc 
623f4a2713aSLionel Sambuc     // These two cases are reverses of each other; try to peephole them.
624f4a2713aSLionel Sambuc     if (Expr *op = findPeephole(E->getSubExpr(), peepholeTarget)) {
625f4a2713aSLionel Sambuc       assert(CGF.getContext().hasSameUnqualifiedType(op->getType(),
626f4a2713aSLionel Sambuc                                                      E->getType()) &&
627f4a2713aSLionel Sambuc            "peephole significantly changed types?");
628f4a2713aSLionel Sambuc       return Visit(op);
629f4a2713aSLionel Sambuc     }
630f4a2713aSLionel Sambuc 
631f4a2713aSLionel Sambuc     // If we're converting an r-value of non-atomic type to an r-value
632f4a2713aSLionel Sambuc     // of atomic type, just emit directly into the relevant sub-object.
633f4a2713aSLionel Sambuc     if (isToAtomic) {
634f4a2713aSLionel Sambuc       AggValueSlot valueDest = Dest;
635f4a2713aSLionel Sambuc       if (!valueDest.isIgnored() && CGF.CGM.isPaddedAtomicType(atomicType)) {
636f4a2713aSLionel Sambuc         // Zero-initialize.  (Strictly speaking, we only need to intialize
637f4a2713aSLionel Sambuc         // the padding at the end, but this is simpler.)
638f4a2713aSLionel Sambuc         if (!Dest.isZeroed())
639f4a2713aSLionel Sambuc           CGF.EmitNullInitialization(Dest.getAddr(), atomicType);
640f4a2713aSLionel Sambuc 
641f4a2713aSLionel Sambuc         // Build a GEP to refer to the subobject.
642f4a2713aSLionel Sambuc         llvm::Value *valueAddr =
643f4a2713aSLionel Sambuc             CGF.Builder.CreateStructGEP(valueDest.getAddr(), 0);
644f4a2713aSLionel Sambuc         valueDest = AggValueSlot::forAddr(valueAddr,
645f4a2713aSLionel Sambuc                                           valueDest.getAlignment(),
646f4a2713aSLionel Sambuc                                           valueDest.getQualifiers(),
647f4a2713aSLionel Sambuc                                           valueDest.isExternallyDestructed(),
648f4a2713aSLionel Sambuc                                           valueDest.requiresGCollection(),
649f4a2713aSLionel Sambuc                                           valueDest.isPotentiallyAliased(),
650f4a2713aSLionel Sambuc                                           AggValueSlot::IsZeroed);
651f4a2713aSLionel Sambuc       }
652f4a2713aSLionel Sambuc 
653f4a2713aSLionel Sambuc       CGF.EmitAggExpr(E->getSubExpr(), valueDest);
654f4a2713aSLionel Sambuc       return;
655f4a2713aSLionel Sambuc     }
656f4a2713aSLionel Sambuc 
657f4a2713aSLionel Sambuc     // Otherwise, we're converting an atomic type to a non-atomic type.
658f4a2713aSLionel Sambuc     // Make an atomic temporary, emit into that, and then copy the value out.
659f4a2713aSLionel Sambuc     AggValueSlot atomicSlot =
660f4a2713aSLionel Sambuc       CGF.CreateAggTemp(atomicType, "atomic-to-nonatomic.temp");
661f4a2713aSLionel Sambuc     CGF.EmitAggExpr(E->getSubExpr(), atomicSlot);
662f4a2713aSLionel Sambuc 
663f4a2713aSLionel Sambuc     llvm::Value *valueAddr =
664f4a2713aSLionel Sambuc       Builder.CreateStructGEP(atomicSlot.getAddr(), 0);
665f4a2713aSLionel Sambuc     RValue rvalue = RValue::getAggregate(valueAddr, atomicSlot.isVolatile());
666f4a2713aSLionel Sambuc     return EmitFinalDestCopy(valueType, rvalue);
667f4a2713aSLionel Sambuc   }
668f4a2713aSLionel Sambuc 
669f4a2713aSLionel Sambuc   case CK_LValueToRValue:
670f4a2713aSLionel Sambuc     // If we're loading from a volatile type, force the destination
671f4a2713aSLionel Sambuc     // into existence.
672f4a2713aSLionel Sambuc     if (E->getSubExpr()->getType().isVolatileQualified()) {
673f4a2713aSLionel Sambuc       EnsureDest(E->getType());
674f4a2713aSLionel Sambuc       return Visit(E->getSubExpr());
675f4a2713aSLionel Sambuc     }
676f4a2713aSLionel Sambuc 
677f4a2713aSLionel Sambuc     // fallthrough
678f4a2713aSLionel Sambuc 
679f4a2713aSLionel Sambuc   case CK_NoOp:
680f4a2713aSLionel Sambuc   case CK_UserDefinedConversion:
681f4a2713aSLionel Sambuc   case CK_ConstructorConversion:
682f4a2713aSLionel Sambuc     assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
683f4a2713aSLionel Sambuc                                                    E->getType()) &&
684f4a2713aSLionel Sambuc            "Implicit cast types must be compatible");
685f4a2713aSLionel Sambuc     Visit(E->getSubExpr());
686f4a2713aSLionel Sambuc     break;
687f4a2713aSLionel Sambuc 
688f4a2713aSLionel Sambuc   case CK_LValueBitCast:
689f4a2713aSLionel Sambuc     llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
690f4a2713aSLionel Sambuc 
691f4a2713aSLionel Sambuc   case CK_Dependent:
692f4a2713aSLionel Sambuc   case CK_BitCast:
693f4a2713aSLionel Sambuc   case CK_ArrayToPointerDecay:
694f4a2713aSLionel Sambuc   case CK_FunctionToPointerDecay:
695f4a2713aSLionel Sambuc   case CK_NullToPointer:
696f4a2713aSLionel Sambuc   case CK_NullToMemberPointer:
697f4a2713aSLionel Sambuc   case CK_BaseToDerivedMemberPointer:
698f4a2713aSLionel Sambuc   case CK_DerivedToBaseMemberPointer:
699f4a2713aSLionel Sambuc   case CK_MemberPointerToBoolean:
700f4a2713aSLionel Sambuc   case CK_ReinterpretMemberPointer:
701f4a2713aSLionel Sambuc   case CK_IntegralToPointer:
702f4a2713aSLionel Sambuc   case CK_PointerToIntegral:
703f4a2713aSLionel Sambuc   case CK_PointerToBoolean:
704f4a2713aSLionel Sambuc   case CK_ToVoid:
705f4a2713aSLionel Sambuc   case CK_VectorSplat:
706f4a2713aSLionel Sambuc   case CK_IntegralCast:
707f4a2713aSLionel Sambuc   case CK_IntegralToBoolean:
708f4a2713aSLionel Sambuc   case CK_IntegralToFloating:
709f4a2713aSLionel Sambuc   case CK_FloatingToIntegral:
710f4a2713aSLionel Sambuc   case CK_FloatingToBoolean:
711f4a2713aSLionel Sambuc   case CK_FloatingCast:
712f4a2713aSLionel Sambuc   case CK_CPointerToObjCPointerCast:
713f4a2713aSLionel Sambuc   case CK_BlockPointerToObjCPointerCast:
714f4a2713aSLionel Sambuc   case CK_AnyPointerToBlockPointerCast:
715f4a2713aSLionel Sambuc   case CK_ObjCObjectLValueCast:
716f4a2713aSLionel Sambuc   case CK_FloatingRealToComplex:
717f4a2713aSLionel Sambuc   case CK_FloatingComplexToReal:
718f4a2713aSLionel Sambuc   case CK_FloatingComplexToBoolean:
719f4a2713aSLionel Sambuc   case CK_FloatingComplexCast:
720f4a2713aSLionel Sambuc   case CK_FloatingComplexToIntegralComplex:
721f4a2713aSLionel Sambuc   case CK_IntegralRealToComplex:
722f4a2713aSLionel Sambuc   case CK_IntegralComplexToReal:
723f4a2713aSLionel Sambuc   case CK_IntegralComplexToBoolean:
724f4a2713aSLionel Sambuc   case CK_IntegralComplexCast:
725f4a2713aSLionel Sambuc   case CK_IntegralComplexToFloatingComplex:
726f4a2713aSLionel Sambuc   case CK_ARCProduceObject:
727f4a2713aSLionel Sambuc   case CK_ARCConsumeObject:
728f4a2713aSLionel Sambuc   case CK_ARCReclaimReturnedObject:
729f4a2713aSLionel Sambuc   case CK_ARCExtendBlockObject:
730f4a2713aSLionel Sambuc   case CK_CopyAndAutoreleaseBlockObject:
731f4a2713aSLionel Sambuc   case CK_BuiltinFnToFnPtr:
732f4a2713aSLionel Sambuc   case CK_ZeroToOCLEvent:
733*0a6a1f1dSLionel Sambuc   case CK_AddressSpaceConversion:
734f4a2713aSLionel Sambuc     llvm_unreachable("cast kind invalid for aggregate types");
735f4a2713aSLionel Sambuc   }
736f4a2713aSLionel Sambuc }
737f4a2713aSLionel Sambuc 
VisitCallExpr(const CallExpr * E)738f4a2713aSLionel Sambuc void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
739f4a2713aSLionel Sambuc   if (E->getCallReturnType()->isReferenceType()) {
740f4a2713aSLionel Sambuc     EmitAggLoadOfLValue(E);
741f4a2713aSLionel Sambuc     return;
742f4a2713aSLionel Sambuc   }
743f4a2713aSLionel Sambuc 
744f4a2713aSLionel Sambuc   RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot());
745f4a2713aSLionel Sambuc   EmitMoveFromReturnSlot(E, RV);
746f4a2713aSLionel Sambuc }
747f4a2713aSLionel Sambuc 
VisitObjCMessageExpr(ObjCMessageExpr * E)748f4a2713aSLionel Sambuc void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
749f4a2713aSLionel Sambuc   RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
750f4a2713aSLionel Sambuc   EmitMoveFromReturnSlot(E, RV);
751f4a2713aSLionel Sambuc }
752f4a2713aSLionel Sambuc 
VisitBinComma(const BinaryOperator * E)753f4a2713aSLionel Sambuc void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
754f4a2713aSLionel Sambuc   CGF.EmitIgnoredExpr(E->getLHS());
755f4a2713aSLionel Sambuc   Visit(E->getRHS());
756f4a2713aSLionel Sambuc }
757f4a2713aSLionel Sambuc 
VisitStmtExpr(const StmtExpr * E)758f4a2713aSLionel Sambuc void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
759f4a2713aSLionel Sambuc   CodeGenFunction::StmtExprEvaluation eval(CGF);
760f4a2713aSLionel Sambuc   CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest);
761f4a2713aSLionel Sambuc }
762f4a2713aSLionel Sambuc 
VisitBinaryOperator(const BinaryOperator * E)763f4a2713aSLionel Sambuc void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
764f4a2713aSLionel Sambuc   if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)
765f4a2713aSLionel Sambuc     VisitPointerToDataMemberBinaryOperator(E);
766f4a2713aSLionel Sambuc   else
767f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "aggregate binary expression");
768f4a2713aSLionel Sambuc }
769f4a2713aSLionel Sambuc 
VisitPointerToDataMemberBinaryOperator(const BinaryOperator * E)770f4a2713aSLionel Sambuc void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
771f4a2713aSLionel Sambuc                                                     const BinaryOperator *E) {
772f4a2713aSLionel Sambuc   LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
773f4a2713aSLionel Sambuc   EmitFinalDestCopy(E->getType(), LV);
774f4a2713aSLionel Sambuc }
775f4a2713aSLionel Sambuc 
776f4a2713aSLionel Sambuc /// Is the value of the given expression possibly a reference to or
777f4a2713aSLionel Sambuc /// into a __block variable?
isBlockVarRef(const Expr * E)778f4a2713aSLionel Sambuc static bool isBlockVarRef(const Expr *E) {
779f4a2713aSLionel Sambuc   // Make sure we look through parens.
780f4a2713aSLionel Sambuc   E = E->IgnoreParens();
781f4a2713aSLionel Sambuc 
782f4a2713aSLionel Sambuc   // Check for a direct reference to a __block variable.
783f4a2713aSLionel Sambuc   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
784f4a2713aSLionel Sambuc     const VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
785f4a2713aSLionel Sambuc     return (var && var->hasAttr<BlocksAttr>());
786f4a2713aSLionel Sambuc   }
787f4a2713aSLionel Sambuc 
788f4a2713aSLionel Sambuc   // More complicated stuff.
789f4a2713aSLionel Sambuc 
790f4a2713aSLionel Sambuc   // Binary operators.
791f4a2713aSLionel Sambuc   if (const BinaryOperator *op = dyn_cast<BinaryOperator>(E)) {
792f4a2713aSLionel Sambuc     // For an assignment or pointer-to-member operation, just care
793f4a2713aSLionel Sambuc     // about the LHS.
794f4a2713aSLionel Sambuc     if (op->isAssignmentOp() || op->isPtrMemOp())
795f4a2713aSLionel Sambuc       return isBlockVarRef(op->getLHS());
796f4a2713aSLionel Sambuc 
797f4a2713aSLionel Sambuc     // For a comma, just care about the RHS.
798f4a2713aSLionel Sambuc     if (op->getOpcode() == BO_Comma)
799f4a2713aSLionel Sambuc       return isBlockVarRef(op->getRHS());
800f4a2713aSLionel Sambuc 
801f4a2713aSLionel Sambuc     // FIXME: pointer arithmetic?
802f4a2713aSLionel Sambuc     return false;
803f4a2713aSLionel Sambuc 
804f4a2713aSLionel Sambuc   // Check both sides of a conditional operator.
805f4a2713aSLionel Sambuc   } else if (const AbstractConditionalOperator *op
806f4a2713aSLionel Sambuc                = dyn_cast<AbstractConditionalOperator>(E)) {
807f4a2713aSLionel Sambuc     return isBlockVarRef(op->getTrueExpr())
808f4a2713aSLionel Sambuc         || isBlockVarRef(op->getFalseExpr());
809f4a2713aSLionel Sambuc 
810f4a2713aSLionel Sambuc   // OVEs are required to support BinaryConditionalOperators.
811f4a2713aSLionel Sambuc   } else if (const OpaqueValueExpr *op
812f4a2713aSLionel Sambuc                = dyn_cast<OpaqueValueExpr>(E)) {
813f4a2713aSLionel Sambuc     if (const Expr *src = op->getSourceExpr())
814f4a2713aSLionel Sambuc       return isBlockVarRef(src);
815f4a2713aSLionel Sambuc 
816f4a2713aSLionel Sambuc   // Casts are necessary to get things like (*(int*)&var) = foo().
817f4a2713aSLionel Sambuc   // We don't really care about the kind of cast here, except
818f4a2713aSLionel Sambuc   // we don't want to look through l2r casts, because it's okay
819f4a2713aSLionel Sambuc   // to get the *value* in a __block variable.
820f4a2713aSLionel Sambuc   } else if (const CastExpr *cast = dyn_cast<CastExpr>(E)) {
821f4a2713aSLionel Sambuc     if (cast->getCastKind() == CK_LValueToRValue)
822f4a2713aSLionel Sambuc       return false;
823f4a2713aSLionel Sambuc     return isBlockVarRef(cast->getSubExpr());
824f4a2713aSLionel Sambuc 
825f4a2713aSLionel Sambuc   // Handle unary operators.  Again, just aggressively look through
826f4a2713aSLionel Sambuc   // it, ignoring the operation.
827f4a2713aSLionel Sambuc   } else if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E)) {
828f4a2713aSLionel Sambuc     return isBlockVarRef(uop->getSubExpr());
829f4a2713aSLionel Sambuc 
830f4a2713aSLionel Sambuc   // Look into the base of a field access.
831f4a2713aSLionel Sambuc   } else if (const MemberExpr *mem = dyn_cast<MemberExpr>(E)) {
832f4a2713aSLionel Sambuc     return isBlockVarRef(mem->getBase());
833f4a2713aSLionel Sambuc 
834f4a2713aSLionel Sambuc   // Look into the base of a subscript.
835f4a2713aSLionel Sambuc   } else if (const ArraySubscriptExpr *sub = dyn_cast<ArraySubscriptExpr>(E)) {
836f4a2713aSLionel Sambuc     return isBlockVarRef(sub->getBase());
837f4a2713aSLionel Sambuc   }
838f4a2713aSLionel Sambuc 
839f4a2713aSLionel Sambuc   return false;
840f4a2713aSLionel Sambuc }
841f4a2713aSLionel Sambuc 
VisitBinAssign(const BinaryOperator * E)842f4a2713aSLionel Sambuc void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
843f4a2713aSLionel Sambuc   // For an assignment to work, the value on the right has
844f4a2713aSLionel Sambuc   // to be compatible with the value on the left.
845f4a2713aSLionel Sambuc   assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
846f4a2713aSLionel Sambuc                                                  E->getRHS()->getType())
847f4a2713aSLionel Sambuc          && "Invalid assignment");
848f4a2713aSLionel Sambuc 
849f4a2713aSLionel Sambuc   // If the LHS might be a __block variable, and the RHS can
850f4a2713aSLionel Sambuc   // potentially cause a block copy, we need to evaluate the RHS first
851f4a2713aSLionel Sambuc   // so that the assignment goes the right place.
852f4a2713aSLionel Sambuc   // This is pretty semantically fragile.
853f4a2713aSLionel Sambuc   if (isBlockVarRef(E->getLHS()) &&
854f4a2713aSLionel Sambuc       E->getRHS()->HasSideEffects(CGF.getContext())) {
855f4a2713aSLionel Sambuc     // Ensure that we have a destination, and evaluate the RHS into that.
856f4a2713aSLionel Sambuc     EnsureDest(E->getRHS()->getType());
857f4a2713aSLionel Sambuc     Visit(E->getRHS());
858f4a2713aSLionel Sambuc 
859f4a2713aSLionel Sambuc     // Now emit the LHS and copy into it.
860f4a2713aSLionel Sambuc     LValue LHS = CGF.EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
861f4a2713aSLionel Sambuc 
862f4a2713aSLionel Sambuc     // That copy is an atomic copy if the LHS is atomic.
863f4a2713aSLionel Sambuc     if (LHS.getType()->isAtomicType()) {
864f4a2713aSLionel Sambuc       CGF.EmitAtomicStore(Dest.asRValue(), LHS, /*isInit*/ false);
865f4a2713aSLionel Sambuc       return;
866f4a2713aSLionel Sambuc     }
867f4a2713aSLionel Sambuc 
868f4a2713aSLionel Sambuc     EmitCopy(E->getLHS()->getType(),
869f4a2713aSLionel Sambuc              AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
870f4a2713aSLionel Sambuc                                      needsGC(E->getLHS()->getType()),
871f4a2713aSLionel Sambuc                                      AggValueSlot::IsAliased),
872f4a2713aSLionel Sambuc              Dest);
873f4a2713aSLionel Sambuc     return;
874f4a2713aSLionel Sambuc   }
875f4a2713aSLionel Sambuc 
876f4a2713aSLionel Sambuc   LValue LHS = CGF.EmitLValue(E->getLHS());
877f4a2713aSLionel Sambuc 
878f4a2713aSLionel Sambuc   // If we have an atomic type, evaluate into the destination and then
879f4a2713aSLionel Sambuc   // do an atomic copy.
880f4a2713aSLionel Sambuc   if (LHS.getType()->isAtomicType()) {
881f4a2713aSLionel Sambuc     EnsureDest(E->getRHS()->getType());
882f4a2713aSLionel Sambuc     Visit(E->getRHS());
883f4a2713aSLionel Sambuc     CGF.EmitAtomicStore(Dest.asRValue(), LHS, /*isInit*/ false);
884f4a2713aSLionel Sambuc     return;
885f4a2713aSLionel Sambuc   }
886f4a2713aSLionel Sambuc 
887f4a2713aSLionel Sambuc   // Codegen the RHS so that it stores directly into the LHS.
888f4a2713aSLionel Sambuc   AggValueSlot LHSSlot =
889f4a2713aSLionel Sambuc     AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
890f4a2713aSLionel Sambuc                             needsGC(E->getLHS()->getType()),
891f4a2713aSLionel Sambuc                             AggValueSlot::IsAliased);
892f4a2713aSLionel Sambuc   // A non-volatile aggregate destination might have volatile member.
893f4a2713aSLionel Sambuc   if (!LHSSlot.isVolatile() &&
894f4a2713aSLionel Sambuc       CGF.hasVolatileMember(E->getLHS()->getType()))
895f4a2713aSLionel Sambuc     LHSSlot.setVolatile(true);
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc   CGF.EmitAggExpr(E->getRHS(), LHSSlot);
898f4a2713aSLionel Sambuc 
899f4a2713aSLionel Sambuc   // Copy into the destination if the assignment isn't ignored.
900f4a2713aSLionel Sambuc   EmitFinalDestCopy(E->getType(), LHS);
901f4a2713aSLionel Sambuc }
902f4a2713aSLionel Sambuc 
903f4a2713aSLionel Sambuc void AggExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)904f4a2713aSLionel Sambuc VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
905f4a2713aSLionel Sambuc   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
906f4a2713aSLionel Sambuc   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
907f4a2713aSLionel Sambuc   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
908f4a2713aSLionel Sambuc 
909f4a2713aSLionel Sambuc   // Bind the common expression if necessary.
910f4a2713aSLionel Sambuc   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
911f4a2713aSLionel Sambuc 
912*0a6a1f1dSLionel Sambuc   RegionCounter Cnt = CGF.getPGORegionCounter(E);
913f4a2713aSLionel Sambuc   CodeGenFunction::ConditionalEvaluation eval(CGF);
914*0a6a1f1dSLionel Sambuc   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
915f4a2713aSLionel Sambuc 
916f4a2713aSLionel Sambuc   // Save whether the destination's lifetime is externally managed.
917f4a2713aSLionel Sambuc   bool isExternallyDestructed = Dest.isExternallyDestructed();
918f4a2713aSLionel Sambuc 
919f4a2713aSLionel Sambuc   eval.begin(CGF);
920f4a2713aSLionel Sambuc   CGF.EmitBlock(LHSBlock);
921*0a6a1f1dSLionel Sambuc   Cnt.beginRegion(Builder);
922f4a2713aSLionel Sambuc   Visit(E->getTrueExpr());
923f4a2713aSLionel Sambuc   eval.end(CGF);
924f4a2713aSLionel Sambuc 
925f4a2713aSLionel Sambuc   assert(CGF.HaveInsertPoint() && "expression evaluation ended with no IP!");
926f4a2713aSLionel Sambuc   CGF.Builder.CreateBr(ContBlock);
927f4a2713aSLionel Sambuc 
928f4a2713aSLionel Sambuc   // If the result of an agg expression is unused, then the emission
929f4a2713aSLionel Sambuc   // of the LHS might need to create a destination slot.  That's fine
930f4a2713aSLionel Sambuc   // with us, and we can safely emit the RHS into the same slot, but
931f4a2713aSLionel Sambuc   // we shouldn't claim that it's already being destructed.
932f4a2713aSLionel Sambuc   Dest.setExternallyDestructed(isExternallyDestructed);
933f4a2713aSLionel Sambuc 
934f4a2713aSLionel Sambuc   eval.begin(CGF);
935f4a2713aSLionel Sambuc   CGF.EmitBlock(RHSBlock);
936f4a2713aSLionel Sambuc   Visit(E->getFalseExpr());
937f4a2713aSLionel Sambuc   eval.end(CGF);
938f4a2713aSLionel Sambuc 
939f4a2713aSLionel Sambuc   CGF.EmitBlock(ContBlock);
940f4a2713aSLionel Sambuc }
941f4a2713aSLionel Sambuc 
VisitChooseExpr(const ChooseExpr * CE)942f4a2713aSLionel Sambuc void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
943f4a2713aSLionel Sambuc   Visit(CE->getChosenSubExpr());
944f4a2713aSLionel Sambuc }
945f4a2713aSLionel Sambuc 
VisitVAArgExpr(VAArgExpr * VE)946f4a2713aSLionel Sambuc void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
947f4a2713aSLionel Sambuc   llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
948f4a2713aSLionel Sambuc   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
949f4a2713aSLionel Sambuc 
950f4a2713aSLionel Sambuc   if (!ArgPtr) {
951*0a6a1f1dSLionel Sambuc     // If EmitVAArg fails, we fall back to the LLVM instruction.
952*0a6a1f1dSLionel Sambuc     llvm::Value *Val =
953*0a6a1f1dSLionel Sambuc         Builder.CreateVAArg(ArgValue, CGF.ConvertType(VE->getType()));
954*0a6a1f1dSLionel Sambuc     if (!Dest.isIgnored())
955*0a6a1f1dSLionel Sambuc       Builder.CreateStore(Val, Dest.getAddr());
956f4a2713aSLionel Sambuc     return;
957f4a2713aSLionel Sambuc   }
958f4a2713aSLionel Sambuc 
959f4a2713aSLionel Sambuc   EmitFinalDestCopy(VE->getType(), CGF.MakeAddrLValue(ArgPtr, VE->getType()));
960f4a2713aSLionel Sambuc }
961f4a2713aSLionel Sambuc 
VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr * E)962f4a2713aSLionel Sambuc void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
963f4a2713aSLionel Sambuc   // Ensure that we have a slot, but if we already do, remember
964f4a2713aSLionel Sambuc   // whether it was externally destructed.
965f4a2713aSLionel Sambuc   bool wasExternallyDestructed = Dest.isExternallyDestructed();
966f4a2713aSLionel Sambuc   EnsureDest(E->getType());
967f4a2713aSLionel Sambuc 
968f4a2713aSLionel Sambuc   // We're going to push a destructor if there isn't already one.
969f4a2713aSLionel Sambuc   Dest.setExternallyDestructed();
970f4a2713aSLionel Sambuc 
971f4a2713aSLionel Sambuc   Visit(E->getSubExpr());
972f4a2713aSLionel Sambuc 
973f4a2713aSLionel Sambuc   // Push that destructor we promised.
974f4a2713aSLionel Sambuc   if (!wasExternallyDestructed)
975f4a2713aSLionel Sambuc     CGF.EmitCXXTemporary(E->getTemporary(), E->getType(), Dest.getAddr());
976f4a2713aSLionel Sambuc }
977f4a2713aSLionel Sambuc 
978f4a2713aSLionel Sambuc void
VisitCXXConstructExpr(const CXXConstructExpr * E)979f4a2713aSLionel Sambuc AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
980f4a2713aSLionel Sambuc   AggValueSlot Slot = EnsureSlot(E->getType());
981f4a2713aSLionel Sambuc   CGF.EmitCXXConstructExpr(E, Slot);
982f4a2713aSLionel Sambuc }
983f4a2713aSLionel Sambuc 
984f4a2713aSLionel Sambuc void
VisitLambdaExpr(LambdaExpr * E)985f4a2713aSLionel Sambuc AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
986f4a2713aSLionel Sambuc   AggValueSlot Slot = EnsureSlot(E->getType());
987f4a2713aSLionel Sambuc   CGF.EmitLambdaExpr(E, Slot);
988f4a2713aSLionel Sambuc }
989f4a2713aSLionel Sambuc 
VisitExprWithCleanups(ExprWithCleanups * E)990f4a2713aSLionel Sambuc void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
991f4a2713aSLionel Sambuc   CGF.enterFullExpression(E);
992f4a2713aSLionel Sambuc   CodeGenFunction::RunCleanupsScope cleanups(CGF);
993f4a2713aSLionel Sambuc   Visit(E->getSubExpr());
994f4a2713aSLionel Sambuc }
995f4a2713aSLionel Sambuc 
VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr * E)996f4a2713aSLionel Sambuc void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
997f4a2713aSLionel Sambuc   QualType T = E->getType();
998f4a2713aSLionel Sambuc   AggValueSlot Slot = EnsureSlot(T);
999f4a2713aSLionel Sambuc   EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
1000f4a2713aSLionel Sambuc }
1001f4a2713aSLionel Sambuc 
VisitImplicitValueInitExpr(ImplicitValueInitExpr * E)1002f4a2713aSLionel Sambuc void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
1003f4a2713aSLionel Sambuc   QualType T = E->getType();
1004f4a2713aSLionel Sambuc   AggValueSlot Slot = EnsureSlot(T);
1005f4a2713aSLionel Sambuc   EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
1006f4a2713aSLionel Sambuc }
1007f4a2713aSLionel Sambuc 
1008f4a2713aSLionel Sambuc /// isSimpleZero - If emitting this value will obviously just cause a store of
1009f4a2713aSLionel Sambuc /// zero to memory, return true.  This can return false if uncertain, so it just
1010f4a2713aSLionel Sambuc /// handles simple cases.
isSimpleZero(const Expr * E,CodeGenFunction & CGF)1011f4a2713aSLionel Sambuc static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) {
1012f4a2713aSLionel Sambuc   E = E->IgnoreParens();
1013f4a2713aSLionel Sambuc 
1014f4a2713aSLionel Sambuc   // 0
1015f4a2713aSLionel Sambuc   if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
1016f4a2713aSLionel Sambuc     return IL->getValue() == 0;
1017f4a2713aSLionel Sambuc   // +0.0
1018f4a2713aSLionel Sambuc   if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E))
1019f4a2713aSLionel Sambuc     return FL->getValue().isPosZero();
1020f4a2713aSLionel Sambuc   // int()
1021f4a2713aSLionel Sambuc   if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) &&
1022f4a2713aSLionel Sambuc       CGF.getTypes().isZeroInitializable(E->getType()))
1023f4a2713aSLionel Sambuc     return true;
1024f4a2713aSLionel Sambuc   // (int*)0 - Null pointer expressions.
1025f4a2713aSLionel Sambuc   if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
1026f4a2713aSLionel Sambuc     return ICE->getCastKind() == CK_NullToPointer;
1027f4a2713aSLionel Sambuc   // '\0'
1028f4a2713aSLionel Sambuc   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
1029f4a2713aSLionel Sambuc     return CL->getValue() == 0;
1030f4a2713aSLionel Sambuc 
1031f4a2713aSLionel Sambuc   // Otherwise, hard case: conservatively return false.
1032f4a2713aSLionel Sambuc   return false;
1033f4a2713aSLionel Sambuc }
1034f4a2713aSLionel Sambuc 
1035f4a2713aSLionel Sambuc 
1036f4a2713aSLionel Sambuc void
EmitInitializationToLValue(Expr * E,LValue LV)1037f4a2713aSLionel Sambuc AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) {
1038f4a2713aSLionel Sambuc   QualType type = LV.getType();
1039f4a2713aSLionel Sambuc   // FIXME: Ignore result?
1040f4a2713aSLionel Sambuc   // FIXME: Are initializers affected by volatile?
1041f4a2713aSLionel Sambuc   if (Dest.isZeroed() && isSimpleZero(E, CGF)) {
1042f4a2713aSLionel Sambuc     // Storing "i32 0" to a zero'd memory location is a noop.
1043f4a2713aSLionel Sambuc     return;
1044f4a2713aSLionel Sambuc   } else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) {
1045f4a2713aSLionel Sambuc     return EmitNullInitializationToLValue(LV);
1046f4a2713aSLionel Sambuc   } else if (type->isReferenceType()) {
1047f4a2713aSLionel Sambuc     RValue RV = CGF.EmitReferenceBindingToExpr(E);
1048f4a2713aSLionel Sambuc     return CGF.EmitStoreThroughLValue(RV, LV);
1049f4a2713aSLionel Sambuc   }
1050f4a2713aSLionel Sambuc 
1051f4a2713aSLionel Sambuc   switch (CGF.getEvaluationKind(type)) {
1052f4a2713aSLionel Sambuc   case TEK_Complex:
1053f4a2713aSLionel Sambuc     CGF.EmitComplexExprIntoLValue(E, LV, /*isInit*/ true);
1054f4a2713aSLionel Sambuc     return;
1055f4a2713aSLionel Sambuc   case TEK_Aggregate:
1056f4a2713aSLionel Sambuc     CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV,
1057f4a2713aSLionel Sambuc                                                AggValueSlot::IsDestructed,
1058f4a2713aSLionel Sambuc                                       AggValueSlot::DoesNotNeedGCBarriers,
1059f4a2713aSLionel Sambuc                                                AggValueSlot::IsNotAliased,
1060f4a2713aSLionel Sambuc                                                Dest.isZeroed()));
1061f4a2713aSLionel Sambuc     return;
1062f4a2713aSLionel Sambuc   case TEK_Scalar:
1063f4a2713aSLionel Sambuc     if (LV.isSimple()) {
1064*0a6a1f1dSLionel Sambuc       CGF.EmitScalarInit(E, /*D=*/nullptr, LV, /*Captured=*/false);
1065f4a2713aSLionel Sambuc     } else {
1066f4a2713aSLionel Sambuc       CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV);
1067f4a2713aSLionel Sambuc     }
1068f4a2713aSLionel Sambuc     return;
1069f4a2713aSLionel Sambuc   }
1070f4a2713aSLionel Sambuc   llvm_unreachable("bad evaluation kind");
1071f4a2713aSLionel Sambuc }
1072f4a2713aSLionel Sambuc 
EmitNullInitializationToLValue(LValue lv)1073f4a2713aSLionel Sambuc void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
1074f4a2713aSLionel Sambuc   QualType type = lv.getType();
1075f4a2713aSLionel Sambuc 
1076f4a2713aSLionel Sambuc   // If the destination slot is already zeroed out before the aggregate is
1077f4a2713aSLionel Sambuc   // copied into it, we don't have to emit any zeros here.
1078f4a2713aSLionel Sambuc   if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type))
1079f4a2713aSLionel Sambuc     return;
1080f4a2713aSLionel Sambuc 
1081f4a2713aSLionel Sambuc   if (CGF.hasScalarEvaluationKind(type)) {
1082f4a2713aSLionel Sambuc     // For non-aggregates, we can store the appropriate null constant.
1083f4a2713aSLionel Sambuc     llvm::Value *null = CGF.CGM.EmitNullConstant(type);
1084f4a2713aSLionel Sambuc     // Note that the following is not equivalent to
1085f4a2713aSLionel Sambuc     // EmitStoreThroughBitfieldLValue for ARC types.
1086f4a2713aSLionel Sambuc     if (lv.isBitField()) {
1087f4a2713aSLionel Sambuc       CGF.EmitStoreThroughBitfieldLValue(RValue::get(null), lv);
1088f4a2713aSLionel Sambuc     } else {
1089f4a2713aSLionel Sambuc       assert(lv.isSimple());
1090f4a2713aSLionel Sambuc       CGF.EmitStoreOfScalar(null, lv, /* isInitialization */ true);
1091f4a2713aSLionel Sambuc     }
1092f4a2713aSLionel Sambuc   } else {
1093f4a2713aSLionel Sambuc     // There's a potential optimization opportunity in combining
1094f4a2713aSLionel Sambuc     // memsets; that would be easy for arrays, but relatively
1095f4a2713aSLionel Sambuc     // difficult for structures with the current code.
1096f4a2713aSLionel Sambuc     CGF.EmitNullInitialization(lv.getAddress(), lv.getType());
1097f4a2713aSLionel Sambuc   }
1098f4a2713aSLionel Sambuc }
1099f4a2713aSLionel Sambuc 
VisitInitListExpr(InitListExpr * E)1100f4a2713aSLionel Sambuc void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
1101f4a2713aSLionel Sambuc #if 0
1102f4a2713aSLionel Sambuc   // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
1103f4a2713aSLionel Sambuc   // (Length of globals? Chunks of zeroed-out space?).
1104f4a2713aSLionel Sambuc   //
1105f4a2713aSLionel Sambuc   // If we can, prefer a copy from a global; this is a lot less code for long
1106f4a2713aSLionel Sambuc   // globals, and it's easier for the current optimizers to analyze.
1107f4a2713aSLionel Sambuc   if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
1108f4a2713aSLionel Sambuc     llvm::GlobalVariable* GV =
1109f4a2713aSLionel Sambuc     new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
1110f4a2713aSLionel Sambuc                              llvm::GlobalValue::InternalLinkage, C, "");
1111f4a2713aSLionel Sambuc     EmitFinalDestCopy(E->getType(), CGF.MakeAddrLValue(GV, E->getType()));
1112f4a2713aSLionel Sambuc     return;
1113f4a2713aSLionel Sambuc   }
1114f4a2713aSLionel Sambuc #endif
1115f4a2713aSLionel Sambuc   if (E->hadArrayRangeDesignator())
1116f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "GNU array range designator extension");
1117f4a2713aSLionel Sambuc 
1118f4a2713aSLionel Sambuc   AggValueSlot Dest = EnsureSlot(E->getType());
1119f4a2713aSLionel Sambuc 
1120f4a2713aSLionel Sambuc   LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),
1121f4a2713aSLionel Sambuc                                      Dest.getAlignment());
1122f4a2713aSLionel Sambuc 
1123f4a2713aSLionel Sambuc   // Handle initialization of an array.
1124f4a2713aSLionel Sambuc   if (E->getType()->isArrayType()) {
1125f4a2713aSLionel Sambuc     if (E->isStringLiteralInit())
1126f4a2713aSLionel Sambuc       return Visit(E->getInit(0));
1127f4a2713aSLionel Sambuc 
1128f4a2713aSLionel Sambuc     QualType elementType =
1129f4a2713aSLionel Sambuc         CGF.getContext().getAsArrayType(E->getType())->getElementType();
1130f4a2713aSLionel Sambuc 
1131f4a2713aSLionel Sambuc     llvm::PointerType *APType =
1132f4a2713aSLionel Sambuc       cast<llvm::PointerType>(Dest.getAddr()->getType());
1133f4a2713aSLionel Sambuc     llvm::ArrayType *AType =
1134f4a2713aSLionel Sambuc       cast<llvm::ArrayType>(APType->getElementType());
1135f4a2713aSLionel Sambuc 
1136f4a2713aSLionel Sambuc     EmitArrayInit(Dest.getAddr(), AType, elementType, E);
1137f4a2713aSLionel Sambuc     return;
1138f4a2713aSLionel Sambuc   }
1139f4a2713aSLionel Sambuc 
1140*0a6a1f1dSLionel Sambuc   if (E->getType()->isAtomicType()) {
1141*0a6a1f1dSLionel Sambuc     // An _Atomic(T) object can be list-initialized from an expression
1142*0a6a1f1dSLionel Sambuc     // of the same type.
1143*0a6a1f1dSLionel Sambuc     assert(E->getNumInits() == 1 &&
1144*0a6a1f1dSLionel Sambuc            CGF.getContext().hasSameUnqualifiedType(E->getInit(0)->getType(),
1145*0a6a1f1dSLionel Sambuc                                                    E->getType()) &&
1146*0a6a1f1dSLionel Sambuc            "unexpected list initialization for atomic object");
1147*0a6a1f1dSLionel Sambuc     return Visit(E->getInit(0));
1148*0a6a1f1dSLionel Sambuc   }
1149*0a6a1f1dSLionel Sambuc 
1150f4a2713aSLionel Sambuc   assert(E->getType()->isRecordType() && "Only support structs/unions here!");
1151f4a2713aSLionel Sambuc 
1152f4a2713aSLionel Sambuc   // Do struct initialization; this code just sets each individual member
1153f4a2713aSLionel Sambuc   // to the approprate value.  This makes bitfield support automatic;
1154f4a2713aSLionel Sambuc   // the disadvantage is that the generated code is more difficult for
1155f4a2713aSLionel Sambuc   // the optimizer, especially with bitfields.
1156f4a2713aSLionel Sambuc   unsigned NumInitElements = E->getNumInits();
1157f4a2713aSLionel Sambuc   RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl();
1158f4a2713aSLionel Sambuc 
1159f4a2713aSLionel Sambuc   // Prepare a 'this' for CXXDefaultInitExprs.
1160f4a2713aSLionel Sambuc   CodeGenFunction::FieldConstructionScope FCS(CGF, Dest.getAddr());
1161f4a2713aSLionel Sambuc 
1162f4a2713aSLionel Sambuc   if (record->isUnion()) {
1163f4a2713aSLionel Sambuc     // Only initialize one field of a union. The field itself is
1164f4a2713aSLionel Sambuc     // specified by the initializer list.
1165f4a2713aSLionel Sambuc     if (!E->getInitializedFieldInUnion()) {
1166f4a2713aSLionel Sambuc       // Empty union; we have nothing to do.
1167f4a2713aSLionel Sambuc 
1168f4a2713aSLionel Sambuc #ifndef NDEBUG
1169f4a2713aSLionel Sambuc       // Make sure that it's really an empty and not a failure of
1170f4a2713aSLionel Sambuc       // semantic analysis.
1171*0a6a1f1dSLionel Sambuc       for (const auto *Field : record->fields())
1172f4a2713aSLionel Sambuc         assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
1173f4a2713aSLionel Sambuc #endif
1174f4a2713aSLionel Sambuc       return;
1175f4a2713aSLionel Sambuc     }
1176f4a2713aSLionel Sambuc 
1177f4a2713aSLionel Sambuc     // FIXME: volatility
1178f4a2713aSLionel Sambuc     FieldDecl *Field = E->getInitializedFieldInUnion();
1179f4a2713aSLionel Sambuc 
1180f4a2713aSLionel Sambuc     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestLV, Field);
1181f4a2713aSLionel Sambuc     if (NumInitElements) {
1182f4a2713aSLionel Sambuc       // Store the initializer into the field
1183f4a2713aSLionel Sambuc       EmitInitializationToLValue(E->getInit(0), FieldLoc);
1184f4a2713aSLionel Sambuc     } else {
1185f4a2713aSLionel Sambuc       // Default-initialize to null.
1186f4a2713aSLionel Sambuc       EmitNullInitializationToLValue(FieldLoc);
1187f4a2713aSLionel Sambuc     }
1188f4a2713aSLionel Sambuc 
1189f4a2713aSLionel Sambuc     return;
1190f4a2713aSLionel Sambuc   }
1191f4a2713aSLionel Sambuc 
1192f4a2713aSLionel Sambuc   // We'll need to enter cleanup scopes in case any of the member
1193f4a2713aSLionel Sambuc   // initializers throw an exception.
1194f4a2713aSLionel Sambuc   SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
1195*0a6a1f1dSLionel Sambuc   llvm::Instruction *cleanupDominator = nullptr;
1196f4a2713aSLionel Sambuc 
1197f4a2713aSLionel Sambuc   // Here we iterate over the fields; this makes it simpler to both
1198f4a2713aSLionel Sambuc   // default-initialize fields and skip over unnamed fields.
1199f4a2713aSLionel Sambuc   unsigned curInitIndex = 0;
1200*0a6a1f1dSLionel Sambuc   for (const auto *field : record->fields()) {
1201f4a2713aSLionel Sambuc     // We're done once we hit the flexible array member.
1202f4a2713aSLionel Sambuc     if (field->getType()->isIncompleteArrayType())
1203f4a2713aSLionel Sambuc       break;
1204f4a2713aSLionel Sambuc 
1205f4a2713aSLionel Sambuc     // Always skip anonymous bitfields.
1206f4a2713aSLionel Sambuc     if (field->isUnnamedBitfield())
1207f4a2713aSLionel Sambuc       continue;
1208f4a2713aSLionel Sambuc 
1209f4a2713aSLionel Sambuc     // We're done if we reach the end of the explicit initializers, we
1210f4a2713aSLionel Sambuc     // have a zeroed object, and the rest of the fields are
1211f4a2713aSLionel Sambuc     // zero-initializable.
1212f4a2713aSLionel Sambuc     if (curInitIndex == NumInitElements && Dest.isZeroed() &&
1213f4a2713aSLionel Sambuc         CGF.getTypes().isZeroInitializable(E->getType()))
1214f4a2713aSLionel Sambuc       break;
1215f4a2713aSLionel Sambuc 
1216f4a2713aSLionel Sambuc 
1217*0a6a1f1dSLionel Sambuc     LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, field);
1218f4a2713aSLionel Sambuc     // We never generate write-barries for initialized fields.
1219f4a2713aSLionel Sambuc     LV.setNonGC(true);
1220f4a2713aSLionel Sambuc 
1221f4a2713aSLionel Sambuc     if (curInitIndex < NumInitElements) {
1222f4a2713aSLionel Sambuc       // Store the initializer into the field.
1223f4a2713aSLionel Sambuc       EmitInitializationToLValue(E->getInit(curInitIndex++), LV);
1224f4a2713aSLionel Sambuc     } else {
1225f4a2713aSLionel Sambuc       // We're out of initalizers; default-initialize to null
1226f4a2713aSLionel Sambuc       EmitNullInitializationToLValue(LV);
1227f4a2713aSLionel Sambuc     }
1228f4a2713aSLionel Sambuc 
1229f4a2713aSLionel Sambuc     // Push a destructor if necessary.
1230f4a2713aSLionel Sambuc     // FIXME: if we have an array of structures, all explicitly
1231f4a2713aSLionel Sambuc     // initialized, we can end up pushing a linear number of cleanups.
1232f4a2713aSLionel Sambuc     bool pushedCleanup = false;
1233f4a2713aSLionel Sambuc     if (QualType::DestructionKind dtorKind
1234f4a2713aSLionel Sambuc           = field->getType().isDestructedType()) {
1235f4a2713aSLionel Sambuc       assert(LV.isSimple());
1236f4a2713aSLionel Sambuc       if (CGF.needsEHCleanup(dtorKind)) {
1237f4a2713aSLionel Sambuc         if (!cleanupDominator)
1238f4a2713aSLionel Sambuc           cleanupDominator = CGF.Builder.CreateUnreachable(); // placeholder
1239f4a2713aSLionel Sambuc 
1240f4a2713aSLionel Sambuc         CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(),
1241f4a2713aSLionel Sambuc                         CGF.getDestroyer(dtorKind), false);
1242f4a2713aSLionel Sambuc         cleanups.push_back(CGF.EHStack.stable_begin());
1243f4a2713aSLionel Sambuc         pushedCleanup = true;
1244f4a2713aSLionel Sambuc       }
1245f4a2713aSLionel Sambuc     }
1246f4a2713aSLionel Sambuc 
1247f4a2713aSLionel Sambuc     // If the GEP didn't get used because of a dead zero init or something
1248f4a2713aSLionel Sambuc     // else, clean it up for -O0 builds and general tidiness.
1249f4a2713aSLionel Sambuc     if (!pushedCleanup && LV.isSimple())
1250f4a2713aSLionel Sambuc       if (llvm::GetElementPtrInst *GEP =
1251f4a2713aSLionel Sambuc             dyn_cast<llvm::GetElementPtrInst>(LV.getAddress()))
1252f4a2713aSLionel Sambuc         if (GEP->use_empty())
1253f4a2713aSLionel Sambuc           GEP->eraseFromParent();
1254f4a2713aSLionel Sambuc   }
1255f4a2713aSLionel Sambuc 
1256f4a2713aSLionel Sambuc   // Deactivate all the partial cleanups in reverse order, which
1257f4a2713aSLionel Sambuc   // generally means popping them.
1258f4a2713aSLionel Sambuc   for (unsigned i = cleanups.size(); i != 0; --i)
1259f4a2713aSLionel Sambuc     CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator);
1260f4a2713aSLionel Sambuc 
1261f4a2713aSLionel Sambuc   // Destroy the placeholder if we made one.
1262f4a2713aSLionel Sambuc   if (cleanupDominator)
1263f4a2713aSLionel Sambuc     cleanupDominator->eraseFromParent();
1264f4a2713aSLionel Sambuc }
1265f4a2713aSLionel Sambuc 
1266f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1267f4a2713aSLionel Sambuc //                        Entry Points into this File
1268f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc /// GetNumNonZeroBytesInInit - Get an approximate count of the number of
1271f4a2713aSLionel Sambuc /// non-zero bytes that will be stored when outputting the initializer for the
1272f4a2713aSLionel Sambuc /// specified initializer expression.
GetNumNonZeroBytesInInit(const Expr * E,CodeGenFunction & CGF)1273f4a2713aSLionel Sambuc static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
1274f4a2713aSLionel Sambuc   E = E->IgnoreParens();
1275f4a2713aSLionel Sambuc 
1276f4a2713aSLionel Sambuc   // 0 and 0.0 won't require any non-zero stores!
1277f4a2713aSLionel Sambuc   if (isSimpleZero(E, CGF)) return CharUnits::Zero();
1278f4a2713aSLionel Sambuc 
1279f4a2713aSLionel Sambuc   // If this is an initlist expr, sum up the size of sizes of the (present)
1280f4a2713aSLionel Sambuc   // elements.  If this is something weird, assume the whole thing is non-zero.
1281f4a2713aSLionel Sambuc   const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
1282*0a6a1f1dSLionel Sambuc   if (!ILE || !CGF.getTypes().isZeroInitializable(ILE->getType()))
1283f4a2713aSLionel Sambuc     return CGF.getContext().getTypeSizeInChars(E->getType());
1284f4a2713aSLionel Sambuc 
1285f4a2713aSLionel Sambuc   // InitListExprs for structs have to be handled carefully.  If there are
1286f4a2713aSLionel Sambuc   // reference members, we need to consider the size of the reference, not the
1287f4a2713aSLionel Sambuc   // referencee.  InitListExprs for unions and arrays can't have references.
1288f4a2713aSLionel Sambuc   if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
1289f4a2713aSLionel Sambuc     if (!RT->isUnionType()) {
1290f4a2713aSLionel Sambuc       RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
1291f4a2713aSLionel Sambuc       CharUnits NumNonZeroBytes = CharUnits::Zero();
1292f4a2713aSLionel Sambuc 
1293f4a2713aSLionel Sambuc       unsigned ILEElement = 0;
1294*0a6a1f1dSLionel Sambuc       for (const auto *Field : SD->fields()) {
1295f4a2713aSLionel Sambuc         // We're done once we hit the flexible array member or run out of
1296f4a2713aSLionel Sambuc         // InitListExpr elements.
1297f4a2713aSLionel Sambuc         if (Field->getType()->isIncompleteArrayType() ||
1298f4a2713aSLionel Sambuc             ILEElement == ILE->getNumInits())
1299f4a2713aSLionel Sambuc           break;
1300f4a2713aSLionel Sambuc         if (Field->isUnnamedBitfield())
1301f4a2713aSLionel Sambuc           continue;
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc         const Expr *E = ILE->getInit(ILEElement++);
1304f4a2713aSLionel Sambuc 
1305f4a2713aSLionel Sambuc         // Reference values are always non-null and have the width of a pointer.
1306f4a2713aSLionel Sambuc         if (Field->getType()->isReferenceType())
1307f4a2713aSLionel Sambuc           NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits(
1308f4a2713aSLionel Sambuc               CGF.getTarget().getPointerWidth(0));
1309f4a2713aSLionel Sambuc         else
1310f4a2713aSLionel Sambuc           NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF);
1311f4a2713aSLionel Sambuc       }
1312f4a2713aSLionel Sambuc 
1313f4a2713aSLionel Sambuc       return NumNonZeroBytes;
1314f4a2713aSLionel Sambuc     }
1315f4a2713aSLionel Sambuc   }
1316f4a2713aSLionel Sambuc 
1317f4a2713aSLionel Sambuc 
1318f4a2713aSLionel Sambuc   CharUnits NumNonZeroBytes = CharUnits::Zero();
1319f4a2713aSLionel Sambuc   for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
1320f4a2713aSLionel Sambuc     NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF);
1321f4a2713aSLionel Sambuc   return NumNonZeroBytes;
1322f4a2713aSLionel Sambuc }
1323f4a2713aSLionel Sambuc 
1324f4a2713aSLionel Sambuc /// CheckAggExprForMemSetUse - If the initializer is large and has a lot of
1325f4a2713aSLionel Sambuc /// zeros in it, emit a memset and avoid storing the individual zeros.
1326f4a2713aSLionel Sambuc ///
CheckAggExprForMemSetUse(AggValueSlot & Slot,const Expr * E,CodeGenFunction & CGF)1327f4a2713aSLionel Sambuc static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
1328f4a2713aSLionel Sambuc                                      CodeGenFunction &CGF) {
1329f4a2713aSLionel Sambuc   // If the slot is already known to be zeroed, nothing to do.  Don't mess with
1330f4a2713aSLionel Sambuc   // volatile stores.
1331*0a6a1f1dSLionel Sambuc   if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == nullptr)
1332*0a6a1f1dSLionel Sambuc     return;
1333f4a2713aSLionel Sambuc 
1334f4a2713aSLionel Sambuc   // C++ objects with a user-declared constructor don't need zero'ing.
1335f4a2713aSLionel Sambuc   if (CGF.getLangOpts().CPlusPlus)
1336f4a2713aSLionel Sambuc     if (const RecordType *RT = CGF.getContext()
1337f4a2713aSLionel Sambuc                        .getBaseElementType(E->getType())->getAs<RecordType>()) {
1338f4a2713aSLionel Sambuc       const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1339f4a2713aSLionel Sambuc       if (RD->hasUserDeclaredConstructor())
1340f4a2713aSLionel Sambuc         return;
1341f4a2713aSLionel Sambuc     }
1342f4a2713aSLionel Sambuc 
1343f4a2713aSLionel Sambuc   // If the type is 16-bytes or smaller, prefer individual stores over memset.
1344f4a2713aSLionel Sambuc   std::pair<CharUnits, CharUnits> TypeInfo =
1345f4a2713aSLionel Sambuc     CGF.getContext().getTypeInfoInChars(E->getType());
1346f4a2713aSLionel Sambuc   if (TypeInfo.first <= CharUnits::fromQuantity(16))
1347f4a2713aSLionel Sambuc     return;
1348f4a2713aSLionel Sambuc 
1349f4a2713aSLionel Sambuc   // Check to see if over 3/4 of the initializer are known to be zero.  If so,
1350f4a2713aSLionel Sambuc   // we prefer to emit memset + individual stores for the rest.
1351f4a2713aSLionel Sambuc   CharUnits NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF);
1352f4a2713aSLionel Sambuc   if (NumNonZeroBytes*4 > TypeInfo.first)
1353f4a2713aSLionel Sambuc     return;
1354f4a2713aSLionel Sambuc 
1355f4a2713aSLionel Sambuc   // Okay, it seems like a good idea to use an initial memset, emit the call.
1356f4a2713aSLionel Sambuc   llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first.getQuantity());
1357f4a2713aSLionel Sambuc   CharUnits Align = TypeInfo.second;
1358f4a2713aSLionel Sambuc 
1359f4a2713aSLionel Sambuc   llvm::Value *Loc = Slot.getAddr();
1360f4a2713aSLionel Sambuc 
1361f4a2713aSLionel Sambuc   Loc = CGF.Builder.CreateBitCast(Loc, CGF.Int8PtrTy);
1362f4a2713aSLionel Sambuc   CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal,
1363f4a2713aSLionel Sambuc                            Align.getQuantity(), false);
1364f4a2713aSLionel Sambuc 
1365f4a2713aSLionel Sambuc   // Tell the AggExprEmitter that the slot is known zero.
1366f4a2713aSLionel Sambuc   Slot.setZeroed();
1367f4a2713aSLionel Sambuc }
1368f4a2713aSLionel Sambuc 
1369f4a2713aSLionel Sambuc 
1370f4a2713aSLionel Sambuc 
1371f4a2713aSLionel Sambuc 
1372f4a2713aSLionel Sambuc /// EmitAggExpr - Emit the computation of the specified expression of aggregate
1373f4a2713aSLionel Sambuc /// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
1374f4a2713aSLionel Sambuc /// the value of the aggregate expression is not needed.  If VolatileDest is
1375f4a2713aSLionel Sambuc /// true, DestPtr cannot be 0.
EmitAggExpr(const Expr * E,AggValueSlot Slot)1376f4a2713aSLionel Sambuc void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) {
1377f4a2713aSLionel Sambuc   assert(E && hasAggregateEvaluationKind(E->getType()) &&
1378f4a2713aSLionel Sambuc          "Invalid aggregate expression to emit");
1379*0a6a1f1dSLionel Sambuc   assert((Slot.getAddr() != nullptr || Slot.isIgnored()) &&
1380f4a2713aSLionel Sambuc          "slot has bits but no address");
1381f4a2713aSLionel Sambuc 
1382f4a2713aSLionel Sambuc   // Optimize the slot if possible.
1383f4a2713aSLionel Sambuc   CheckAggExprForMemSetUse(Slot, E, *this);
1384f4a2713aSLionel Sambuc 
1385f4a2713aSLionel Sambuc   AggExprEmitter(*this, Slot).Visit(const_cast<Expr*>(E));
1386f4a2713aSLionel Sambuc }
1387f4a2713aSLionel Sambuc 
EmitAggExprToLValue(const Expr * E)1388f4a2713aSLionel Sambuc LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
1389f4a2713aSLionel Sambuc   assert(hasAggregateEvaluationKind(E->getType()) && "Invalid argument!");
1390f4a2713aSLionel Sambuc   llvm::Value *Temp = CreateMemTemp(E->getType());
1391f4a2713aSLionel Sambuc   LValue LV = MakeAddrLValue(Temp, E->getType());
1392f4a2713aSLionel Sambuc   EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed,
1393f4a2713aSLionel Sambuc                                          AggValueSlot::DoesNotNeedGCBarriers,
1394f4a2713aSLionel Sambuc                                          AggValueSlot::IsNotAliased));
1395f4a2713aSLionel Sambuc   return LV;
1396f4a2713aSLionel Sambuc }
1397f4a2713aSLionel Sambuc 
EmitAggregateCopy(llvm::Value * DestPtr,llvm::Value * SrcPtr,QualType Ty,bool isVolatile,CharUnits alignment,bool isAssignment)1398f4a2713aSLionel Sambuc void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
1399f4a2713aSLionel Sambuc                                         llvm::Value *SrcPtr, QualType Ty,
1400f4a2713aSLionel Sambuc                                         bool isVolatile,
1401f4a2713aSLionel Sambuc                                         CharUnits alignment,
1402f4a2713aSLionel Sambuc                                         bool isAssignment) {
1403f4a2713aSLionel Sambuc   assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
1404f4a2713aSLionel Sambuc 
1405f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus) {
1406f4a2713aSLionel Sambuc     if (const RecordType *RT = Ty->getAs<RecordType>()) {
1407f4a2713aSLionel Sambuc       CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
1408f4a2713aSLionel Sambuc       assert((Record->hasTrivialCopyConstructor() ||
1409f4a2713aSLionel Sambuc               Record->hasTrivialCopyAssignment() ||
1410f4a2713aSLionel Sambuc               Record->hasTrivialMoveConstructor() ||
1411f4a2713aSLionel Sambuc               Record->hasTrivialMoveAssignment()) &&
1412f4a2713aSLionel Sambuc              "Trying to aggregate-copy a type without a trivial copy/move "
1413f4a2713aSLionel Sambuc              "constructor or assignment operator");
1414f4a2713aSLionel Sambuc       // Ignore empty classes in C++.
1415f4a2713aSLionel Sambuc       if (Record->isEmpty())
1416f4a2713aSLionel Sambuc         return;
1417f4a2713aSLionel Sambuc     }
1418f4a2713aSLionel Sambuc   }
1419f4a2713aSLionel Sambuc 
1420f4a2713aSLionel Sambuc   // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
1421f4a2713aSLionel Sambuc   // C99 6.5.16.1p3, which states "If the value being stored in an object is
1422f4a2713aSLionel Sambuc   // read from another object that overlaps in anyway the storage of the first
1423f4a2713aSLionel Sambuc   // object, then the overlap shall be exact and the two objects shall have
1424f4a2713aSLionel Sambuc   // qualified or unqualified versions of a compatible type."
1425f4a2713aSLionel Sambuc   //
1426f4a2713aSLionel Sambuc   // memcpy is not defined if the source and destination pointers are exactly
1427f4a2713aSLionel Sambuc   // equal, but other compilers do this optimization, and almost every memcpy
1428f4a2713aSLionel Sambuc   // implementation handles this case safely.  If there is a libc that does not
1429f4a2713aSLionel Sambuc   // safely handle this, we can add a target hook.
1430f4a2713aSLionel Sambuc 
1431f4a2713aSLionel Sambuc   // Get data size and alignment info for this aggregate. If this is an
1432f4a2713aSLionel Sambuc   // assignment don't copy the tail padding. Otherwise copying it is fine.
1433f4a2713aSLionel Sambuc   std::pair<CharUnits, CharUnits> TypeInfo;
1434f4a2713aSLionel Sambuc   if (isAssignment)
1435f4a2713aSLionel Sambuc     TypeInfo = getContext().getTypeInfoDataSizeInChars(Ty);
1436f4a2713aSLionel Sambuc   else
1437f4a2713aSLionel Sambuc     TypeInfo = getContext().getTypeInfoInChars(Ty);
1438f4a2713aSLionel Sambuc 
1439f4a2713aSLionel Sambuc   if (alignment.isZero())
1440f4a2713aSLionel Sambuc     alignment = TypeInfo.second;
1441f4a2713aSLionel Sambuc 
1442f4a2713aSLionel Sambuc   // FIXME: Handle variable sized types.
1443f4a2713aSLionel Sambuc 
1444f4a2713aSLionel Sambuc   // FIXME: If we have a volatile struct, the optimizer can remove what might
1445f4a2713aSLionel Sambuc   // appear to be `extra' memory ops:
1446f4a2713aSLionel Sambuc   //
1447f4a2713aSLionel Sambuc   // volatile struct { int i; } a, b;
1448f4a2713aSLionel Sambuc   //
1449f4a2713aSLionel Sambuc   // int main() {
1450f4a2713aSLionel Sambuc   //   a = b;
1451f4a2713aSLionel Sambuc   //   a = b;
1452f4a2713aSLionel Sambuc   // }
1453f4a2713aSLionel Sambuc   //
1454f4a2713aSLionel Sambuc   // we need to use a different call here.  We use isVolatile to indicate when
1455f4a2713aSLionel Sambuc   // either the source or the destination is volatile.
1456f4a2713aSLionel Sambuc 
1457f4a2713aSLionel Sambuc   llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
1458f4a2713aSLionel Sambuc   llvm::Type *DBP =
1459f4a2713aSLionel Sambuc     llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace());
1460f4a2713aSLionel Sambuc   DestPtr = Builder.CreateBitCast(DestPtr, DBP);
1461f4a2713aSLionel Sambuc 
1462f4a2713aSLionel Sambuc   llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
1463f4a2713aSLionel Sambuc   llvm::Type *SBP =
1464f4a2713aSLionel Sambuc     llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace());
1465f4a2713aSLionel Sambuc   SrcPtr = Builder.CreateBitCast(SrcPtr, SBP);
1466f4a2713aSLionel Sambuc 
1467f4a2713aSLionel Sambuc   // Don't do any of the memmove_collectable tests if GC isn't set.
1468f4a2713aSLionel Sambuc   if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
1469f4a2713aSLionel Sambuc     // fall through
1470f4a2713aSLionel Sambuc   } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
1471f4a2713aSLionel Sambuc     RecordDecl *Record = RecordTy->getDecl();
1472f4a2713aSLionel Sambuc     if (Record->hasObjectMember()) {
1473f4a2713aSLionel Sambuc       CharUnits size = TypeInfo.first;
1474f4a2713aSLionel Sambuc       llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
1475f4a2713aSLionel Sambuc       llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
1476f4a2713aSLionel Sambuc       CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
1477f4a2713aSLionel Sambuc                                                     SizeVal);
1478f4a2713aSLionel Sambuc       return;
1479f4a2713aSLionel Sambuc     }
1480f4a2713aSLionel Sambuc   } else if (Ty->isArrayType()) {
1481f4a2713aSLionel Sambuc     QualType BaseType = getContext().getBaseElementType(Ty);
1482f4a2713aSLionel Sambuc     if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
1483f4a2713aSLionel Sambuc       if (RecordTy->getDecl()->hasObjectMember()) {
1484f4a2713aSLionel Sambuc         CharUnits size = TypeInfo.first;
1485f4a2713aSLionel Sambuc         llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
1486f4a2713aSLionel Sambuc         llvm::Value *SizeVal =
1487f4a2713aSLionel Sambuc           llvm::ConstantInt::get(SizeTy, size.getQuantity());
1488f4a2713aSLionel Sambuc         CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
1489f4a2713aSLionel Sambuc                                                       SizeVal);
1490f4a2713aSLionel Sambuc         return;
1491f4a2713aSLionel Sambuc       }
1492f4a2713aSLionel Sambuc     }
1493f4a2713aSLionel Sambuc   }
1494f4a2713aSLionel Sambuc 
1495f4a2713aSLionel Sambuc   // Determine the metadata to describe the position of any padding in this
1496f4a2713aSLionel Sambuc   // memcpy, as well as the TBAA tags for the members of the struct, in case
1497f4a2713aSLionel Sambuc   // the optimizer wishes to expand it in to scalar memory operations.
1498f4a2713aSLionel Sambuc   llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty);
1499f4a2713aSLionel Sambuc 
1500f4a2713aSLionel Sambuc   Builder.CreateMemCpy(DestPtr, SrcPtr,
1501f4a2713aSLionel Sambuc                        llvm::ConstantInt::get(IntPtrTy,
1502f4a2713aSLionel Sambuc                                               TypeInfo.first.getQuantity()),
1503f4a2713aSLionel Sambuc                        alignment.getQuantity(), isVolatile,
1504*0a6a1f1dSLionel Sambuc                        /*TBAATag=*/nullptr, TBAAStructTag);
1505f4a2713aSLionel Sambuc }
1506