| Chris Lattner | 566b6ce | 2007-08-24 02:22:53 +0000 | [diff] [blame] | 1 | //===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===// | 
| Chris Lattner | af6f528 | 2007-08-10 20:13:28 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Chris Lattner | af6f528 | 2007-08-10 20:13:28 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This contains code to emit Aggregate Expr nodes as LLVM code. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "CodeGenFunction.h" | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 15 | #include "CodeGenModule.h" | 
| Fariborz Jahanian | 082b02e | 2009-07-08 01:18:33 +0000 | [diff] [blame] | 16 | #include "CGObjCRuntime.h" | 
| Daniel Dunbar | de7fb84 | 2008-08-11 05:00:27 +0000 | [diff] [blame] | 17 | #include "clang/AST/ASTContext.h" | 
| Anders Carlsson | b14095a | 2009-04-17 00:06:03 +0000 | [diff] [blame] | 18 | #include "clang/AST/DeclCXX.h" | 
| Daniel Dunbar | de7fb84 | 2008-08-11 05:00:27 +0000 | [diff] [blame] | 19 | #include "clang/AST/StmtVisitor.h" | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 20 | #include "llvm/Constants.h" | 
 | 21 | #include "llvm/Function.h" | 
| Devang Patel | 636c3d0 | 2007-10-26 17:44:44 +0000 | [diff] [blame] | 22 | #include "llvm/GlobalVariable.h" | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 23 | #include "llvm/Intrinsics.h" | 
| Chris Lattner | af6f528 | 2007-08-10 20:13:28 +0000 | [diff] [blame] | 24 | using namespace clang; | 
 | 25 | using namespace CodeGen; | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 26 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 27 | //===----------------------------------------------------------------------===// | 
 | 28 | //                        Aggregate Expression Emitter | 
 | 29 | //===----------------------------------------------------------------------===// | 
 | 30 |  | 
 | 31 | namespace  { | 
| Benjamin Kramer | 85b4521 | 2009-11-28 19:45:26 +0000 | [diff] [blame] | 32 | class AggExprEmitter : public StmtVisitor<AggExprEmitter> { | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 33 |   CodeGenFunction &CGF; | 
| Daniel Dunbar | 45d196b | 2008-11-01 01:53:16 +0000 | [diff] [blame] | 34 |   CGBuilderTy &Builder; | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 35 |   AggValueSlot Dest; | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 36 |   bool IgnoreResult; | 
| John McCall | ef072fd | 2010-05-22 01:48:05 +0000 | [diff] [blame] | 37 |  | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 38 |   /// We want to use 'dest' as the return slot except under two | 
 | 39 |   /// conditions: | 
 | 40 |   ///   - The destination slot requires garbage collection, so we | 
 | 41 |   ///     need to use the GC API. | 
 | 42 |   ///   - The destination slot is potentially aliased. | 
 | 43 |   bool shouldUseDestForReturnSlot() const { | 
 | 44 |     return !(Dest.requiresGCollection() || Dest.isPotentiallyAliased()); | 
 | 45 |   } | 
 | 46 |  | 
| John McCall | ef072fd | 2010-05-22 01:48:05 +0000 | [diff] [blame] | 47 |   ReturnValueSlot getReturnValueSlot() const { | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 48 |     if (!shouldUseDestForReturnSlot()) | 
 | 49 |       return ReturnValueSlot(); | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 50 |  | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 51 |     return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile()); | 
 | 52 |   } | 
 | 53 |  | 
 | 54 |   AggValueSlot EnsureSlot(QualType T) { | 
 | 55 |     if (!Dest.isIgnored()) return Dest; | 
 | 56 |     return CGF.CreateAggTemp(T, "agg.tmp.ensured"); | 
| John McCall | ef072fd | 2010-05-22 01:48:05 +0000 | [diff] [blame] | 57 |   } | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 58 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 59 | public: | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 60 |   AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest, | 
| Fariborz Jahanian | 474e2fe | 2010-09-16 00:20:07 +0000 | [diff] [blame] | 61 |                  bool ignore) | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 62 |     : CGF(cgf), Builder(CGF.Builder), Dest(Dest), | 
| Fariborz Jahanian | 474e2fe | 2010-09-16 00:20:07 +0000 | [diff] [blame] | 63 |       IgnoreResult(ignore) { | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 64 |   } | 
 | 65 |  | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 66 |   //===--------------------------------------------------------------------===// | 
 | 67 |   //                               Utilities | 
 | 68 |   //===--------------------------------------------------------------------===// | 
 | 69 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 70 |   /// EmitAggLoadOfLValue - Given an expression with aggregate type that | 
 | 71 |   /// represents a value lvalue, this method emits the address of the lvalue, | 
 | 72 |   /// then loads the result into DestPtr. | 
 | 73 |   void EmitAggLoadOfLValue(const Expr *E); | 
| Eli Friedman | 922696f | 2008-05-19 17:51:16 +0000 | [diff] [blame] | 74 |  | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 75 |   /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 76 |   void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false); | 
 | 77 |   void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false); | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 78 |  | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 79 |   void EmitMoveFromReturnSlot(const Expr *E, RValue Src); | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 80 |  | 
| John McCall | 7c2349b | 2011-08-25 20:40:09 +0000 | [diff] [blame] | 81 |   AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { | 
 | 82 |     if (CGF.getLangOptions().getGCMode() && TypeRequiresGCollection(T)) | 
 | 83 |       return AggValueSlot::NeedsGCBarriers; | 
 | 84 |     return AggValueSlot::DoesNotNeedGCBarriers; | 
 | 85 |   } | 
 | 86 |  | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 87 |   bool TypeRequiresGCollection(QualType T); | 
 | 88 |  | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 89 |   //===--------------------------------------------------------------------===// | 
 | 90 |   //                            Visitor Methods | 
 | 91 |   //===--------------------------------------------------------------------===// | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 92 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 93 |   void VisitStmt(Stmt *S) { | 
| Daniel Dunbar | 488e993 | 2008-08-16 00:56:44 +0000 | [diff] [blame] | 94 |     CGF.ErrorUnsupported(S, "aggregate expression"); | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 95 |   } | 
 | 96 |   void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); } | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 97 |   void VisitGenericSelectionExpr(GenericSelectionExpr *GE) { | 
 | 98 |     Visit(GE->getResultExpr()); | 
 | 99 |   } | 
| Eli Friedman | 12444a2 | 2009-01-27 09:03:41 +0000 | [diff] [blame] | 100 |   void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); } | 
| John McCall | 91a5755 | 2011-07-15 05:09:51 +0000 | [diff] [blame] | 101 |   void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) { | 
 | 102 |     return Visit(E->getReplacement()); | 
 | 103 |   } | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 104 |  | 
 | 105 |   // l-values. | 
| Seo Sanghyeon | 9b73b39 | 2007-12-14 02:04:12 +0000 | [diff] [blame] | 106 |   void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); } | 
 | 107 |   void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } | 
 | 108 |   void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); } | 
| Daniel Dunbar | 5be028f | 2010-01-04 18:47:06 +0000 | [diff] [blame] | 109 |   void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); } | 
| Douglas Gregor | 751ec9b | 2011-06-17 04:59:12 +0000 | [diff] [blame] | 110 |   void VisitCompoundLiteralExpr(CompoundLiteralExpr *E); | 
| Seo Sanghyeon | 9b73b39 | 2007-12-14 02:04:12 +0000 | [diff] [blame] | 111 |   void VisitArraySubscriptExpr(ArraySubscriptExpr *E) { | 
 | 112 |     EmitAggLoadOfLValue(E); | 
 | 113 |   } | 
| Chris Lattner | f0a990c | 2009-04-21 23:00:09 +0000 | [diff] [blame] | 114 |   void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 115 |     EmitAggLoadOfLValue(E); | 
| Chris Lattner | f0a990c | 2009-04-21 23:00:09 +0000 | [diff] [blame] | 116 |   } | 
 | 117 |   void VisitPredefinedExpr(const PredefinedExpr *E) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 118 |     EmitAggLoadOfLValue(E); | 
| Chris Lattner | f0a990c | 2009-04-21 23:00:09 +0000 | [diff] [blame] | 119 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 120 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 121 |   // Operators. | 
| Anders Carlsson | 4d8673b | 2009-08-07 23:22:37 +0000 | [diff] [blame] | 122 |   void VisitCastExpr(CastExpr *E); | 
| Anders Carlsson | 148fe67 | 2007-10-31 22:04:46 +0000 | [diff] [blame] | 123 |   void VisitCallExpr(const CallExpr *E); | 
| Chris Lattner | b2d963f | 2007-08-31 22:54:14 +0000 | [diff] [blame] | 124 |   void VisitStmtExpr(const StmtExpr *E); | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 125 |   void VisitBinaryOperator(const BinaryOperator *BO); | 
| Fariborz Jahanian | 8bfd31f | 2009-10-22 22:57:31 +0000 | [diff] [blame] | 126 |   void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO); | 
| Chris Lattner | 03d6fb9 | 2007-08-21 04:43:17 +0000 | [diff] [blame] | 127 |   void VisitBinAssign(const BinaryOperator *E); | 
| Eli Friedman | 07fa52a | 2008-05-20 07:56:31 +0000 | [diff] [blame] | 128 |   void VisitBinComma(const BinaryOperator *E); | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 129 |  | 
| Chris Lattner | 8fdf328 | 2008-06-24 17:04:18 +0000 | [diff] [blame] | 130 |   void VisitObjCMessageExpr(ObjCMessageExpr *E); | 
| Daniel Dunbar | 0a04d77 | 2008-08-23 10:51:21 +0000 | [diff] [blame] | 131 |   void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { | 
 | 132 |     EmitAggLoadOfLValue(E); | 
 | 133 |   } | 
| Daniel Dunbar | 9c3fc70 | 2008-08-27 06:57:25 +0000 | [diff] [blame] | 134 |   void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 135 |  | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 136 |   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); | 
| Anders Carlsson | a294ca8 | 2009-07-08 18:33:14 +0000 | [diff] [blame] | 137 |   void VisitChooseExpr(const ChooseExpr *CE); | 
| Devang Patel | 636c3d0 | 2007-10-26 17:44:44 +0000 | [diff] [blame] | 138 |   void VisitInitListExpr(InitListExpr *E); | 
| Anders Carlsson | 30311fa | 2009-12-16 06:57:54 +0000 | [diff] [blame] | 139 |   void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); | 
| Chris Lattner | 0442108 | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 140 |   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { | 
 | 141 |     Visit(DAE->getExpr()); | 
 | 142 |   } | 
| Anders Carlsson | b58d017 | 2009-05-30 23:23:33 +0000 | [diff] [blame] | 143 |   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); | 
| Anders Carlsson | 31ccf37 | 2009-05-03 17:47:16 +0000 | [diff] [blame] | 144 |   void VisitCXXConstructExpr(const CXXConstructExpr *E); | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 145 |   void VisitExprWithCleanups(ExprWithCleanups *E); | 
| Douglas Gregor | ed8abf1 | 2010-07-08 06:14:04 +0000 | [diff] [blame] | 146 |   void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); | 
| Mike Stump | 2710c41 | 2009-11-18 00:40:12 +0000 | [diff] [blame] | 147 |   void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } | 
| Douglas Gregor | 03e8003 | 2011-06-21 17:03:29 +0000 | [diff] [blame] | 148 |   void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 149 |   void VisitOpaqueValueExpr(OpaqueValueExpr *E); | 
 | 150 |  | 
| Eli Friedman | b185124 | 2008-05-27 15:51:49 +0000 | [diff] [blame] | 151 |   void VisitVAArgExpr(VAArgExpr *E); | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 152 |  | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 153 |   void EmitInitializationToLValue(Expr *E, LValue Address); | 
 | 154 |   void EmitNullInitializationToLValue(LValue Address); | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 155 |   //  case Expr::ChooseExprClass: | 
| Mike Stump | 39406b1 | 2009-12-09 19:24:08 +0000 | [diff] [blame] | 156 |   void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); } | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 157 | }; | 
 | 158 | }  // end anonymous namespace. | 
 | 159 |  | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 160 | //===----------------------------------------------------------------------===// | 
 | 161 | //                                Utilities | 
 | 162 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 163 |  | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 164 | /// EmitAggLoadOfLValue - Given an expression with aggregate type that | 
 | 165 | /// represents a value lvalue, this method emits the address of the lvalue, | 
 | 166 | /// then loads the result into DestPtr. | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 167 | void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) { | 
 | 168 |   LValue LV = CGF.EmitLValue(E); | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 169 |   EmitFinalDestCopy(E, LV); | 
 | 170 | } | 
 | 171 |  | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 172 | /// \brief True if the given aggregate type requires special GC API calls. | 
 | 173 | bool AggExprEmitter::TypeRequiresGCollection(QualType T) { | 
 | 174 |   // Only record types have members that might require garbage collection. | 
 | 175 |   const RecordType *RecordTy = T->getAs<RecordType>(); | 
 | 176 |   if (!RecordTy) return false; | 
 | 177 |  | 
 | 178 |   // Don't mess with non-trivial C++ types. | 
 | 179 |   RecordDecl *Record = RecordTy->getDecl(); | 
 | 180 |   if (isa<CXXRecordDecl>(Record) && | 
 | 181 |       (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() || | 
 | 182 |        !cast<CXXRecordDecl>(Record)->hasTrivialDestructor())) | 
 | 183 |     return false; | 
 | 184 |  | 
 | 185 |   // Check whether the type has an object member. | 
 | 186 |   return Record->hasObjectMember(); | 
 | 187 | } | 
 | 188 |  | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 189 | /// \brief Perform the final move to DestPtr if for some reason | 
 | 190 | /// getReturnValueSlot() didn't use it directly. | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 191 | /// | 
 | 192 | /// The idea is that you do something like this: | 
 | 193 | ///   RValue Result = EmitSomething(..., getReturnValueSlot()); | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 194 | ///   EmitMoveFromReturnSlot(E, Result); | 
 | 195 | /// | 
 | 196 | /// If nothing interferes, this will cause the result to be emitted | 
 | 197 | /// directly into the return value slot.  Otherwise, a final move | 
 | 198 | /// will be performed. | 
 | 199 | void AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue Src) { | 
 | 200 |   if (shouldUseDestForReturnSlot()) { | 
 | 201 |     // Logically, Dest.getAddr() should equal Src.getAggregateAddr(). | 
 | 202 |     // The possibility of undef rvalues complicates that a lot, | 
 | 203 |     // though, so we can't really assert. | 
 | 204 |     return; | 
| Fariborz Jahanian | 55bcace | 2010-06-15 22:44:06 +0000 | [diff] [blame] | 205 |   } | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 206 |  | 
 | 207 |   // Otherwise, do a final copy,  | 
 | 208 |   assert(Dest.getAddr() != Src.getAggregateAddr()); | 
 | 209 |   EmitFinalDestCopy(E, Src, /*Ignore*/ true); | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 210 | } | 
 | 211 |  | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 212 | /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 213 | void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) { | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 214 |   assert(Src.isAggregate() && "value must be aggregate value!"); | 
 | 215 |  | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 216 |   // If Dest is ignored, then we're evaluating an aggregate expression | 
| John McCall | a8f28da | 2010-08-25 02:50:31 +0000 | [diff] [blame] | 217 |   // in a context (like an expression statement) that doesn't care | 
 | 218 |   // about the result.  C says that an lvalue-to-rvalue conversion is | 
 | 219 |   // performed in these cases; C++ says that it is not.  In either | 
 | 220 |   // case, we don't actually need to do anything unless the value is | 
 | 221 |   // volatile. | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 222 |   if (Dest.isIgnored()) { | 
| John McCall | a8f28da | 2010-08-25 02:50:31 +0000 | [diff] [blame] | 223 |     if (!Src.isVolatileQualified() || | 
 | 224 |         CGF.CGM.getLangOptions().CPlusPlus || | 
 | 225 |         (IgnoreResult && Ignore)) | 
| Mike Stump | 9ccb103 | 2009-05-23 22:01:27 +0000 | [diff] [blame] | 226 |       return; | 
| Fariborz Jahanian | 8a97005 | 2010-10-22 22:05:03 +0000 | [diff] [blame] | 227 |  | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 228 |     // If the source is volatile, we must read from it; to do that, we need | 
 | 229 |     // some place to put it. | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 230 |     Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp"); | 
| Mike Stump | 9ccb103 | 2009-05-23 22:01:27 +0000 | [diff] [blame] | 231 |   } | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 232 |  | 
| John McCall | d1a5f13 | 2010-09-16 03:13:23 +0000 | [diff] [blame] | 233 |   if (Dest.requiresGCollection()) { | 
| Ken Dyck | 479b61c | 2011-04-24 17:08:00 +0000 | [diff] [blame] | 234 |     CharUnits size = CGF.getContext().getTypeSizeInChars(E->getType()); | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 235 |     llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); | 
| Ken Dyck | 479b61c | 2011-04-24 17:08:00 +0000 | [diff] [blame] | 236 |     llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity()); | 
| Fariborz Jahanian | 08c3213 | 2009-08-31 19:33:16 +0000 | [diff] [blame] | 237 |     CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 238 |                                                       Dest.getAddr(), | 
 | 239 |                                                       Src.getAggregateAddr(), | 
 | 240 |                                                       SizeVal); | 
| Fariborz Jahanian | 08c3213 | 2009-08-31 19:33:16 +0000 | [diff] [blame] | 241 |     return; | 
 | 242 |   } | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 243 |   // If the result of the assignment is used, copy the LHS there also. | 
 | 244 |   // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile | 
 | 245 |   // from the source as well, as we can't eliminate it if either operand | 
 | 246 |   // is volatile, unless copy has volatile for both source and destination.. | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 247 |   CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(), | 
 | 248 |                         Dest.isVolatile()|Src.isVolatileQualified()); | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 249 | } | 
 | 250 |  | 
 | 251 | /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 252 | void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { | 
| Mike Stump | 4ac20dd | 2009-05-23 20:28:01 +0000 | [diff] [blame] | 253 |   assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc"); | 
 | 254 |  | 
 | 255 |   EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(), | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 256 |                                             Src.isVolatileQualified()), | 
 | 257 |                     Ignore); | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 258 | } | 
 | 259 |  | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 260 | //===----------------------------------------------------------------------===// | 
 | 261 | //                            Visitor Methods | 
 | 262 | //===----------------------------------------------------------------------===// | 
 | 263 |  | 
| Douglas Gregor | 03e8003 | 2011-06-21 17:03:29 +0000 | [diff] [blame] | 264 | void AggExprEmitter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E){ | 
 | 265 |   Visit(E->GetTemporaryExpr()); | 
 | 266 | } | 
 | 267 |  | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 268 | void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) { | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 269 |   EmitFinalDestCopy(e, CGF.getOpaqueLValueMapping(e)); | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 270 | } | 
 | 271 |  | 
| Douglas Gregor | 751ec9b | 2011-06-17 04:59:12 +0000 | [diff] [blame] | 272 | void | 
 | 273 | AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { | 
| Douglas Gregor | 673e98b | 2011-06-17 16:37:20 +0000 | [diff] [blame] | 274 |   if (E->getType().isPODType(CGF.getContext())) { | 
 | 275 |     // For a POD type, just emit a load of the lvalue + a copy, because our | 
 | 276 |     // compound literal might alias the destination. | 
 | 277 |     // FIXME: This is a band-aid; the real problem appears to be in our handling | 
 | 278 |     // of assignments, where we store directly into the LHS without checking | 
 | 279 |     // whether anything in the RHS aliases. | 
 | 280 |     EmitAggLoadOfLValue(E); | 
 | 281 |     return; | 
 | 282 |   } | 
 | 283 |    | 
| Douglas Gregor | 751ec9b | 2011-06-17 04:59:12 +0000 | [diff] [blame] | 284 |   AggValueSlot Slot = EnsureSlot(E->getType()); | 
 | 285 |   CGF.EmitAggExpr(E->getInitializer(), Slot); | 
 | 286 | } | 
 | 287 |  | 
 | 288 |  | 
| Anders Carlsson | 4d8673b | 2009-08-07 23:22:37 +0000 | [diff] [blame] | 289 | void AggExprEmitter::VisitCastExpr(CastExpr *E) { | 
| Anders Carlsson | 3016842 | 2009-09-29 01:23:39 +0000 | [diff] [blame] | 290 |   switch (E->getCastKind()) { | 
| Anders Carlsson | 575b374 | 2011-04-11 02:03:26 +0000 | [diff] [blame] | 291 |   case CK_Dynamic: { | 
| Douglas Gregor | 69cfeb1 | 2010-05-14 21:31:02 +0000 | [diff] [blame] | 292 |     assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?"); | 
 | 293 |     LValue LV = CGF.EmitCheckedLValue(E->getSubExpr()); | 
 | 294 |     // FIXME: Do we also need to handle property references here? | 
 | 295 |     if (LV.isSimple()) | 
 | 296 |       CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E)); | 
 | 297 |     else | 
 | 298 |       CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast"); | 
 | 299 |      | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 300 |     if (!Dest.isIgnored()) | 
 | 301 |       CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination"); | 
| Douglas Gregor | 69cfeb1 | 2010-05-14 21:31:02 +0000 | [diff] [blame] | 302 |     break; | 
 | 303 |   } | 
 | 304 |        | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 305 |   case CK_ToUnion: { | 
| John McCall | 6591271 | 2011-04-12 22:02:02 +0000 | [diff] [blame] | 306 |     if (Dest.isIgnored()) break; | 
 | 307 |  | 
| Anders Carlsson | 4d8673b | 2009-08-07 23:22:37 +0000 | [diff] [blame] | 308 |     // GCC union extension | 
| Daniel Dunbar | 79c3928 | 2010-08-21 03:15:20 +0000 | [diff] [blame] | 309 |     QualType Ty = E->getSubExpr()->getType(); | 
 | 310 |     QualType PtrTy = CGF.getContext().getPointerType(Ty); | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 311 |     llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(), | 
| Eli Friedman | 34ebf4d | 2009-06-03 20:45:06 +0000 | [diff] [blame] | 312 |                                                  CGF.ConvertType(PtrTy)); | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 313 |     EmitInitializationToLValue(E->getSubExpr(), | 
 | 314 |                                CGF.MakeAddrLValue(CastPtr, Ty)); | 
| Anders Carlsson | 3016842 | 2009-09-29 01:23:39 +0000 | [diff] [blame] | 315 |     break; | 
| Nuno Lopes | 7e91627 | 2009-01-15 20:14:33 +0000 | [diff] [blame] | 316 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 317 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 318 |   case CK_DerivedToBase: | 
 | 319 |   case CK_BaseToDerived: | 
 | 320 |   case CK_UncheckedDerivedToBase: { | 
| Douglas Gregor | 2d6b0e9 | 2010-05-22 05:17:18 +0000 | [diff] [blame] | 321 |     assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: " | 
 | 322 |                 "should have been unpacked before we got here"); | 
 | 323 |     break; | 
 | 324 |   } | 
 | 325 |  | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 326 |   case CK_GetObjCProperty: { | 
 | 327 |     LValue LV = CGF.EmitLValue(E->getSubExpr()); | 
 | 328 |     assert(LV.isPropertyRef()); | 
 | 329 |     RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot()); | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 330 |     EmitMoveFromReturnSlot(E, RV); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 331 |     break; | 
 | 332 |   } | 
 | 333 |  | 
 | 334 |   case CK_LValueToRValue: // hope for downstream optimization | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 335 |   case CK_NoOp: | 
 | 336 |   case CK_UserDefinedConversion: | 
 | 337 |   case CK_ConstructorConversion: | 
| Anders Carlsson | 3016842 | 2009-09-29 01:23:39 +0000 | [diff] [blame] | 338 |     assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(), | 
 | 339 |                                                    E->getType()) && | 
 | 340 |            "Implicit cast types must be compatible"); | 
 | 341 |     Visit(E->getSubExpr()); | 
 | 342 |     break; | 
| John McCall | 0ae287a | 2010-12-01 04:43:34 +0000 | [diff] [blame] | 343 |        | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 344 |   case CK_LValueBitCast: | 
| John McCall | 0ae287a | 2010-12-01 04:43:34 +0000 | [diff] [blame] | 345 |     llvm_unreachable("should not be emitting lvalue bitcast as rvalue"); | 
| Douglas Gregor | e39a389 | 2010-07-13 23:17:26 +0000 | [diff] [blame] | 346 |     break; | 
| John McCall | 1de4d4e | 2011-04-07 08:22:57 +0000 | [diff] [blame] | 347 |  | 
| John McCall | 0ae287a | 2010-12-01 04:43:34 +0000 | [diff] [blame] | 348 |   case CK_Dependent: | 
 | 349 |   case CK_BitCast: | 
 | 350 |   case CK_ArrayToPointerDecay: | 
 | 351 |   case CK_FunctionToPointerDecay: | 
 | 352 |   case CK_NullToPointer: | 
 | 353 |   case CK_NullToMemberPointer: | 
 | 354 |   case CK_BaseToDerivedMemberPointer: | 
 | 355 |   case CK_DerivedToBaseMemberPointer: | 
 | 356 |   case CK_MemberPointerToBoolean: | 
 | 357 |   case CK_IntegralToPointer: | 
 | 358 |   case CK_PointerToIntegral: | 
 | 359 |   case CK_PointerToBoolean: | 
 | 360 |   case CK_ToVoid: | 
 | 361 |   case CK_VectorSplat: | 
 | 362 |   case CK_IntegralCast: | 
 | 363 |   case CK_IntegralToBoolean: | 
 | 364 |   case CK_IntegralToFloating: | 
 | 365 |   case CK_FloatingToIntegral: | 
 | 366 |   case CK_FloatingToBoolean: | 
 | 367 |   case CK_FloatingCast: | 
 | 368 |   case CK_AnyPointerToObjCPointerCast: | 
 | 369 |   case CK_AnyPointerToBlockPointerCast: | 
 | 370 |   case CK_ObjCObjectLValueCast: | 
 | 371 |   case CK_FloatingRealToComplex: | 
 | 372 |   case CK_FloatingComplexToReal: | 
 | 373 |   case CK_FloatingComplexToBoolean: | 
 | 374 |   case CK_FloatingComplexCast: | 
 | 375 |   case CK_FloatingComplexToIntegralComplex: | 
 | 376 |   case CK_IntegralRealToComplex: | 
 | 377 |   case CK_IntegralComplexToReal: | 
 | 378 |   case CK_IntegralComplexToBoolean: | 
 | 379 |   case CK_IntegralComplexCast: | 
 | 380 |   case CK_IntegralComplexToFloatingComplex: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 381 |   case CK_ObjCProduceObject: | 
 | 382 |   case CK_ObjCConsumeObject: | 
| John McCall | 7e5e5f4 | 2011-07-07 06:58:02 +0000 | [diff] [blame] | 383 |   case CK_ObjCReclaimReturnedObject: | 
| John McCall | 0ae287a | 2010-12-01 04:43:34 +0000 | [diff] [blame] | 384 |     llvm_unreachable("cast kind invalid for aggregate types"); | 
| Anders Carlsson | 3016842 | 2009-09-29 01:23:39 +0000 | [diff] [blame] | 385 |   } | 
| Anders Carlsson | e4707ff | 2008-01-14 06:28:57 +0000 | [diff] [blame] | 386 | } | 
 | 387 |  | 
| Chris Lattner | 9619662 | 2008-07-26 22:37:01 +0000 | [diff] [blame] | 388 | void AggExprEmitter::VisitCallExpr(const CallExpr *E) { | 
| Anders Carlsson | e70e8f7 | 2009-05-27 16:45:02 +0000 | [diff] [blame] | 389 |   if (E->getCallReturnType()->isReferenceType()) { | 
 | 390 |     EmitAggLoadOfLValue(E); | 
 | 391 |     return; | 
 | 392 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 393 |  | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 394 |   RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot()); | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 395 |   EmitMoveFromReturnSlot(E, RV); | 
| Anders Carlsson | 148fe67 | 2007-10-31 22:04:46 +0000 | [diff] [blame] | 396 | } | 
| Chris Lattner | 9619662 | 2008-07-26 22:37:01 +0000 | [diff] [blame] | 397 |  | 
 | 398 | void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { | 
| John McCall | fa037bd | 2010-05-22 22:13:32 +0000 | [diff] [blame] | 399 |   RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot()); | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 400 |   EmitMoveFromReturnSlot(E, RV); | 
| Chris Lattner | 8fdf328 | 2008-06-24 17:04:18 +0000 | [diff] [blame] | 401 | } | 
| Anders Carlsson | 148fe67 | 2007-10-31 22:04:46 +0000 | [diff] [blame] | 402 |  | 
| Daniel Dunbar | 9c3fc70 | 2008-08-27 06:57:25 +0000 | [diff] [blame] | 403 | void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 404 |   llvm_unreachable("direct property access not surrounded by " | 
 | 405 |                    "lvalue-to-rvalue cast"); | 
| Daniel Dunbar | 9c3fc70 | 2008-08-27 06:57:25 +0000 | [diff] [blame] | 406 | } | 
 | 407 |  | 
| Chris Lattner | 9619662 | 2008-07-26 22:37:01 +0000 | [diff] [blame] | 408 | void AggExprEmitter::VisitBinComma(const BinaryOperator *E) { | 
| John McCall | 2a41637 | 2010-12-05 02:00:02 +0000 | [diff] [blame] | 409 |   CGF.EmitIgnoredExpr(E->getLHS()); | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 410 |   Visit(E->getRHS()); | 
| Eli Friedman | 07fa52a | 2008-05-20 07:56:31 +0000 | [diff] [blame] | 411 | } | 
 | 412 |  | 
| Chris Lattner | b2d963f | 2007-08-31 22:54:14 +0000 | [diff] [blame] | 413 | void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) { | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 414 |   CodeGenFunction::StmtExprEvaluation eval(CGF); | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 415 |   CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest); | 
| Chris Lattner | b2d963f | 2007-08-31 22:54:14 +0000 | [diff] [blame] | 416 | } | 
 | 417 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 418 | void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 419 |   if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI) | 
| Fariborz Jahanian | 8bfd31f | 2009-10-22 22:57:31 +0000 | [diff] [blame] | 420 |     VisitPointerToDataMemberBinaryOperator(E); | 
 | 421 |   else | 
 | 422 |     CGF.ErrorUnsupported(E, "aggregate binary expression"); | 
 | 423 | } | 
 | 424 |  | 
 | 425 | void AggExprEmitter::VisitPointerToDataMemberBinaryOperator( | 
 | 426 |                                                     const BinaryOperator *E) { | 
 | 427 |   LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E); | 
 | 428 |   EmitFinalDestCopy(E, LV); | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 429 | } | 
 | 430 |  | 
| Chris Lattner | 03d6fb9 | 2007-08-21 04:43:17 +0000 | [diff] [blame] | 431 | void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { | 
| Eli Friedman | ff6e2b7 | 2008-02-11 01:09:17 +0000 | [diff] [blame] | 432 |   // For an assignment to work, the value on the right has | 
 | 433 |   // to be compatible with the value on the left. | 
| Eli Friedman | 2dce5f8 | 2009-05-28 23:04:00 +0000 | [diff] [blame] | 434 |   assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), | 
 | 435 |                                                  E->getRHS()->getType()) | 
| Eli Friedman | ff6e2b7 | 2008-02-11 01:09:17 +0000 | [diff] [blame] | 436 |          && "Invalid assignment"); | 
| John McCall | cd940a1 | 2010-12-06 06:10:02 +0000 | [diff] [blame] | 437 |  | 
| Fariborz Jahanian | 2c7168c | 2011-04-29 21:53:21 +0000 | [diff] [blame] | 438 |   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS())) | 
| Fariborz Jahanian | 73a6f8e | 2011-04-29 22:11:28 +0000 | [diff] [blame] | 439 |     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) | 
| Fariborz Jahanian | 2c7168c | 2011-04-29 21:53:21 +0000 | [diff] [blame] | 440 |       if (VD->hasAttr<BlocksAttr>() && | 
 | 441 |           E->getRHS()->HasSideEffects(CGF.getContext())) { | 
 | 442 |         // When __block variable on LHS, the RHS must be evaluated first  | 
 | 443 |         // as it may change the 'forwarding' field via call to Block_copy. | 
 | 444 |         LValue RHS = CGF.EmitLValue(E->getRHS()); | 
 | 445 |         LValue LHS = CGF.EmitLValue(E->getLHS()); | 
| John McCall | 7c2349b | 2011-08-25 20:40:09 +0000 | [diff] [blame] | 446 |         Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, | 
 | 447 |                                        needsGC(E->getLHS()->getType())); | 
| Fariborz Jahanian | 2c7168c | 2011-04-29 21:53:21 +0000 | [diff] [blame] | 448 |         EmitFinalDestCopy(E, RHS, true); | 
 | 449 |         return; | 
 | 450 |       } | 
| Fariborz Jahanian | 2c7168c | 2011-04-29 21:53:21 +0000 | [diff] [blame] | 451 |    | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 452 |   LValue LHS = CGF.EmitLValue(E->getLHS()); | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 453 |  | 
| Daniel Dunbar | 7f8ea5c | 2008-08-30 05:35:15 +0000 | [diff] [blame] | 454 |   // We have to special case property setters, otherwise we must have | 
 | 455 |   // a simple lvalue (no aggregates inside vectors, bitfields). | 
 | 456 |   if (LHS.isPropertyRef()) { | 
| Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 457 |     const ObjCPropertyRefExpr *RE = LHS.getPropertyRefExpr(); | 
 | 458 |     QualType ArgType = RE->getSetterArgType(); | 
 | 459 |     RValue Src; | 
 | 460 |     if (ArgType->isReferenceType()) | 
 | 461 |       Src = CGF.EmitReferenceBindingToExpr(E->getRHS(), 0); | 
 | 462 |     else { | 
 | 463 |       AggValueSlot Slot = EnsureSlot(E->getRHS()->getType()); | 
 | 464 |       CGF.EmitAggExpr(E->getRHS(), Slot); | 
 | 465 |       Src = Slot.asRValue(); | 
 | 466 |     } | 
 | 467 |     CGF.EmitStoreThroughPropertyRefLValue(Src, LHS); | 
| Daniel Dunbar | 7f8ea5c | 2008-08-30 05:35:15 +0000 | [diff] [blame] | 468 |   } else { | 
 | 469 |     // Codegen the RHS so that it stores directly into the LHS. | 
| John McCall | 7c2349b | 2011-08-25 20:40:09 +0000 | [diff] [blame] | 470 |     AggValueSlot LHSSlot = | 
 | 471 |       AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,  | 
 | 472 |                               needsGC(E->getLHS()->getType())); | 
| Fariborz Jahanian | 474e2fe | 2010-09-16 00:20:07 +0000 | [diff] [blame] | 473 |     CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 474 |     EmitFinalDestCopy(E, LHS, true); | 
| Daniel Dunbar | 7f8ea5c | 2008-08-30 05:35:15 +0000 | [diff] [blame] | 475 |   } | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 476 | } | 
 | 477 |  | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 478 | void AggExprEmitter:: | 
 | 479 | VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { | 
| Daniel Dunbar | 9615ecb | 2008-11-13 01:38:36 +0000 | [diff] [blame] | 480 |   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); | 
 | 481 |   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); | 
 | 482 |   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 483 |  | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 484 |   // Bind the common expression if necessary. | 
 | 485 |   CodeGenFunction::OpaqueValueMapping binding(CGF, E); | 
 | 486 |  | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 487 |   CodeGenFunction::ConditionalEvaluation eval(CGF); | 
| Eli Friedman | 8e274bd | 2009-12-25 06:17:05 +0000 | [diff] [blame] | 488 |   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 489 |  | 
| John McCall | 74fb0ed | 2010-11-17 00:07:33 +0000 | [diff] [blame] | 490 |   // Save whether the destination's lifetime is externally managed. | 
 | 491 |   bool DestLifetimeManaged = Dest.isLifetimeExternallyManaged(); | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 492 |  | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 493 |   eval.begin(CGF); | 
 | 494 |   CGF.EmitBlock(LHSBlock); | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 495 |   Visit(E->getTrueExpr()); | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 496 |   eval.end(CGF); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 497 |  | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 498 |   assert(CGF.HaveInsertPoint() && "expression evaluation ended with no IP!"); | 
 | 499 |   CGF.Builder.CreateBr(ContBlock); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 500 |  | 
| John McCall | 74fb0ed | 2010-11-17 00:07:33 +0000 | [diff] [blame] | 501 |   // If the result of an agg expression is unused, then the emission | 
 | 502 |   // of the LHS might need to create a destination slot.  That's fine | 
 | 503 |   // with us, and we can safely emit the RHS into the same slot, but | 
 | 504 |   // we shouldn't claim that its lifetime is externally managed. | 
 | 505 |   Dest.setLifetimeExternallyManaged(DestLifetimeManaged); | 
 | 506 |  | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 507 |   eval.begin(CGF); | 
 | 508 |   CGF.EmitBlock(RHSBlock); | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 509 |   Visit(E->getFalseExpr()); | 
| John McCall | 150b462 | 2011-01-26 04:00:11 +0000 | [diff] [blame] | 510 |   eval.end(CGF); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 511 |  | 
| Chris Lattner | 9c03356 | 2007-08-21 04:25:47 +0000 | [diff] [blame] | 512 |   CGF.EmitBlock(ContBlock); | 
| Chris Lattner | 883f6a7 | 2007-08-11 00:04:45 +0000 | [diff] [blame] | 513 | } | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 514 |  | 
| Anders Carlsson | a294ca8 | 2009-07-08 18:33:14 +0000 | [diff] [blame] | 515 | void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { | 
 | 516 |   Visit(CE->getChosenSubExpr(CGF.getContext())); | 
 | 517 | } | 
 | 518 |  | 
| Eli Friedman | b185124 | 2008-05-27 15:51:49 +0000 | [diff] [blame] | 519 | void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { | 
| Daniel Dunbar | 0785570 | 2009-02-11 22:25:55 +0000 | [diff] [blame] | 520 |   llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr()); | 
| Anders Carlsson | ddf7cac | 2008-11-04 05:30:00 +0000 | [diff] [blame] | 521 |   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType()); | 
 | 522 |  | 
| Sebastian Redl | 0262f02 | 2009-01-09 21:09:38 +0000 | [diff] [blame] | 523 |   if (!ArgPtr) { | 
| Anders Carlsson | ddf7cac | 2008-11-04 05:30:00 +0000 | [diff] [blame] | 524 |     CGF.ErrorUnsupported(VE, "aggregate va_arg expression"); | 
| Sebastian Redl | 0262f02 | 2009-01-09 21:09:38 +0000 | [diff] [blame] | 525 |     return; | 
 | 526 |   } | 
 | 527 |  | 
| Daniel Dunbar | 79c3928 | 2010-08-21 03:15:20 +0000 | [diff] [blame] | 528 |   EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType())); | 
| Eli Friedman | b185124 | 2008-05-27 15:51:49 +0000 | [diff] [blame] | 529 | } | 
 | 530 |  | 
| Anders Carlsson | b58d017 | 2009-05-30 23:23:33 +0000 | [diff] [blame] | 531 | void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 532 |   // Ensure that we have a slot, but if we already do, remember | 
 | 533 |   // whether its lifetime was externally managed. | 
 | 534 |   bool WasManaged = Dest.isLifetimeExternallyManaged(); | 
 | 535 |   Dest = EnsureSlot(E->getType()); | 
 | 536 |   Dest.setLifetimeExternallyManaged(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 537 |  | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 538 |   Visit(E->getSubExpr()); | 
| Anders Carlsson | b58d017 | 2009-05-30 23:23:33 +0000 | [diff] [blame] | 539 |  | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 540 |   // Set up the temporary's destructor if its lifetime wasn't already | 
 | 541 |   // being managed. | 
 | 542 |   if (!WasManaged) | 
 | 543 |     CGF.EmitCXXTemporary(E->getTemporary(), Dest.getAddr()); | 
| Anders Carlsson | b58d017 | 2009-05-30 23:23:33 +0000 | [diff] [blame] | 544 | } | 
 | 545 |  | 
| Anders Carlsson | b14095a | 2009-04-17 00:06:03 +0000 | [diff] [blame] | 546 | void | 
| Anders Carlsson | 31ccf37 | 2009-05-03 17:47:16 +0000 | [diff] [blame] | 547 | AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) { | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 548 |   AggValueSlot Slot = EnsureSlot(E->getType()); | 
 | 549 |   CGF.EmitCXXConstructExpr(E, Slot); | 
| Anders Carlsson | 7f6ad15 | 2009-05-19 04:48:36 +0000 | [diff] [blame] | 550 | } | 
 | 551 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 552 | void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { | 
 | 553 |   CGF.EmitExprWithCleanups(E, Dest); | 
| Anders Carlsson | b14095a | 2009-04-17 00:06:03 +0000 | [diff] [blame] | 554 | } | 
 | 555 |  | 
| Douglas Gregor | ed8abf1 | 2010-07-08 06:14:04 +0000 | [diff] [blame] | 556 | void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 557 |   QualType T = E->getType(); | 
 | 558 |   AggValueSlot Slot = EnsureSlot(T); | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 559 |   EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T)); | 
| Anders Carlsson | 30311fa | 2009-12-16 06:57:54 +0000 | [diff] [blame] | 560 | } | 
 | 561 |  | 
 | 562 | void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 563 |   QualType T = E->getType(); | 
 | 564 |   AggValueSlot Slot = EnsureSlot(T); | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 565 |   EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T)); | 
| Nuno Lopes | 329763b | 2009-10-18 15:18:11 +0000 | [diff] [blame] | 566 | } | 
 | 567 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 568 | /// isSimpleZero - If emitting this value will obviously just cause a store of | 
 | 569 | /// zero to memory, return true.  This can return false if uncertain, so it just | 
 | 570 | /// handles simple cases. | 
 | 571 | static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) { | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 572 |   E = E->IgnoreParens(); | 
 | 573 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 574 |   // 0 | 
 | 575 |   if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) | 
 | 576 |     return IL->getValue() == 0; | 
 | 577 |   // +0.0 | 
 | 578 |   if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(E)) | 
 | 579 |     return FL->getValue().isPosZero(); | 
 | 580 |   // int() | 
 | 581 |   if ((isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) && | 
 | 582 |       CGF.getTypes().isZeroInitializable(E->getType())) | 
 | 583 |     return true; | 
 | 584 |   // (int*)0 - Null pointer expressions. | 
 | 585 |   if (const CastExpr *ICE = dyn_cast<CastExpr>(E)) | 
 | 586 |     return ICE->getCastKind() == CK_NullToPointer; | 
 | 587 |   // '\0' | 
 | 588 |   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) | 
 | 589 |     return CL->getValue() == 0; | 
 | 590 |    | 
 | 591 |   // Otherwise, hard case: conservatively return false. | 
 | 592 |   return false; | 
 | 593 | } | 
 | 594 |  | 
 | 595 |  | 
| Anders Carlsson | 78e83f8 | 2010-02-03 17:33:16 +0000 | [diff] [blame] | 596 | void  | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 597 | AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { | 
 | 598 |   QualType type = LV.getType(); | 
| Mike Stump | 7f79f9b | 2009-05-29 15:46:01 +0000 | [diff] [blame] | 599 |   // FIXME: Ignore result? | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 600 |   // FIXME: Are initializers affected by volatile? | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 601 |   if (Dest.isZeroed() && isSimpleZero(E, CGF)) { | 
 | 602 |     // Storing "i32 0" to a zero'd memory location is a noop. | 
 | 603 |   } else if (isa<ImplicitValueInitExpr>(E)) { | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 604 |     EmitNullInitializationToLValue(LV); | 
 | 605 |   } else if (type->isReferenceType()) { | 
| Anders Carlsson | 32f36ba | 2010-06-26 16:35:32 +0000 | [diff] [blame] | 606 |     RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); | 
| John McCall | 545d996 | 2011-06-25 02:11:03 +0000 | [diff] [blame] | 607 |     CGF.EmitStoreThroughLValue(RV, LV); | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 608 |   } else if (type->isAnyComplexType()) { | 
| Douglas Gregor | 3498bdb | 2009-01-29 17:44:32 +0000 | [diff] [blame] | 609 |     CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 610 |   } else if (CGF.hasAggregateLLVMType(type)) { | 
| John McCall | 7c2349b | 2011-08-25 20:40:09 +0000 | [diff] [blame] | 611 |     CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, | 
 | 612 |                                                AggValueSlot::IsDestructed, | 
 | 613 |                                       AggValueSlot::DoesNotNeedGCBarriers, | 
| John McCall | 410ffb2 | 2011-08-25 23:04:34 +0000 | [diff] [blame^] | 614 |                                                AggValueSlot::IsNotAliased, | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 615 |                                                Dest.isZeroed())); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 616 |   } else if (LV.isSimple()) { | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 617 |     CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); | 
| Eli Friedman | c8ba961 | 2008-05-12 15:06:05 +0000 | [diff] [blame] | 618 |   } else { | 
| John McCall | 545d996 | 2011-06-25 02:11:03 +0000 | [diff] [blame] | 619 |     CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV); | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 620 |   } | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 621 | } | 
 | 622 |  | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 623 | void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { | 
 | 624 |   QualType type = lv.getType(); | 
 | 625 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 626 |   // If the destination slot is already zeroed out before the aggregate is | 
 | 627 |   // copied into it, we don't have to emit any zeros here. | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 628 |   if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type)) | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 629 |     return; | 
 | 630 |    | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 631 |   if (!CGF.hasAggregateLLVMType(type)) { | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 632 |     // For non-aggregates, we can store zero | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 633 |     llvm::Value *null = llvm::Constant::getNullValue(CGF.ConvertType(type)); | 
| John McCall | 545d996 | 2011-06-25 02:11:03 +0000 | [diff] [blame] | 634 |     CGF.EmitStoreThroughLValue(RValue::get(null), lv); | 
| Lauro Ramos Venancio | 145cd89 | 2008-02-19 19:27:31 +0000 | [diff] [blame] | 635 |   } else { | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 636 |     // There's a potential optimization opportunity in combining | 
 | 637 |     // memsets; that would be easy for arrays, but relatively | 
 | 638 |     // difficult for structures with the current code. | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 639 |     CGF.EmitNullInitialization(lv.getAddress(), lv.getType()); | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 640 |   } | 
 | 641 | } | 
 | 642 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 643 | void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { | 
| Eli Friedman | a385b3c | 2008-12-02 01:17:45 +0000 | [diff] [blame] | 644 | #if 0 | 
| Eli Friedman | 13a5be1 | 2009-12-04 01:30:56 +0000 | [diff] [blame] | 645 |   // FIXME: Assess perf here?  Figure out what cases are worth optimizing here | 
 | 646 |   // (Length of globals? Chunks of zeroed-out space?). | 
| Eli Friedman | a385b3c | 2008-12-02 01:17:45 +0000 | [diff] [blame] | 647 |   // | 
| Mike Stump | f5408fe | 2009-05-16 07:57:57 +0000 | [diff] [blame] | 648 |   // If we can, prefer a copy from a global; this is a lot less code for long | 
 | 649 |   // globals, and it's easier for the current optimizers to analyze. | 
| Eli Friedman | 13a5be1 | 2009-12-04 01:30:56 +0000 | [diff] [blame] | 650 |   if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) { | 
| Eli Friedman | 994ffef | 2008-11-30 02:11:09 +0000 | [diff] [blame] | 651 |     llvm::GlobalVariable* GV = | 
| Eli Friedman | 13a5be1 | 2009-12-04 01:30:56 +0000 | [diff] [blame] | 652 |     new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true, | 
 | 653 |                              llvm::GlobalValue::InternalLinkage, C, ""); | 
| Daniel Dunbar | 79c3928 | 2010-08-21 03:15:20 +0000 | [diff] [blame] | 654 |     EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType())); | 
| Eli Friedman | 994ffef | 2008-11-30 02:11:09 +0000 | [diff] [blame] | 655 |     return; | 
 | 656 |   } | 
| Eli Friedman | a385b3c | 2008-12-02 01:17:45 +0000 | [diff] [blame] | 657 | #endif | 
| Chris Lattner | d0db03a | 2010-09-06 00:11:41 +0000 | [diff] [blame] | 658 |   if (E->hadArrayRangeDesignator()) | 
| Douglas Gregor | a9c8780 | 2009-01-29 19:42:23 +0000 | [diff] [blame] | 659 |     CGF.ErrorUnsupported(E, "GNU array range designator extension"); | 
| Douglas Gregor | a9c8780 | 2009-01-29 19:42:23 +0000 | [diff] [blame] | 660 |  | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 661 |   llvm::Value *DestPtr = Dest.getAddr(); | 
 | 662 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 663 |   // Handle initialization of an array. | 
 | 664 |   if (E->getType()->isArrayType()) { | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 665 |     llvm::PointerType *APType = | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 666 |       cast<llvm::PointerType>(DestPtr->getType()); | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 667 |     llvm::ArrayType *AType = | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 668 |       cast<llvm::ArrayType>(APType->getElementType()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 669 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 670 |     uint64_t NumInitElements = E->getNumInits(); | 
| Eli Friedman | 922696f | 2008-05-19 17:51:16 +0000 | [diff] [blame] | 671 |  | 
| Chris Lattner | 9619662 | 2008-07-26 22:37:01 +0000 | [diff] [blame] | 672 |     if (E->getNumInits() > 0) { | 
 | 673 |       QualType T1 = E->getType(); | 
 | 674 |       QualType T2 = E->getInit(0)->getType(); | 
| Eli Friedman | 2dce5f8 | 2009-05-28 23:04:00 +0000 | [diff] [blame] | 675 |       if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { | 
| Chris Lattner | 9619662 | 2008-07-26 22:37:01 +0000 | [diff] [blame] | 676 |         EmitAggLoadOfLValue(E->getInit(0)); | 
 | 677 |         return; | 
 | 678 |       } | 
| Eli Friedman | 922696f | 2008-05-19 17:51:16 +0000 | [diff] [blame] | 679 |     } | 
 | 680 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 681 |     uint64_t NumArrayElements = AType->getNumElements(); | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 682 |     assert(NumInitElements <= NumArrayElements); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 683 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 684 |     QualType elementType = E->getType().getCanonicalType(); | 
 | 685 |     elementType = CGF.getContext().getQualifiedType( | 
 | 686 |                     cast<ArrayType>(elementType)->getElementType(), | 
 | 687 |                     elementType.getQualifiers() + Dest.getQualifiers()); | 
| Argyrios Kyrtzidis | 3b4d490 | 2011-04-28 18:53:58 +0000 | [diff] [blame] | 688 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 689 |     // DestPtr is an array*.  Construct an elementType* by drilling | 
 | 690 |     // down a level. | 
 | 691 |     llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); | 
 | 692 |     llvm::Value *indices[] = { zero, zero }; | 
 | 693 |     llvm::Value *begin = | 
| Jay Foad | 0f6ac7c | 2011-07-22 08:16:57 +0000 | [diff] [blame] | 694 |       Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin"); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 695 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 696 |     // Exception safety requires us to destroy all the | 
 | 697 |     // already-constructed members if an initializer throws. | 
 | 698 |     // For that, we'll need an EH cleanup. | 
 | 699 |     QualType::DestructionKind dtorKind = elementType.isDestructedType(); | 
 | 700 |     llvm::AllocaInst *endOfInit = 0; | 
 | 701 |     EHScopeStack::stable_iterator cleanup; | 
 | 702 |     if (CGF.needsEHCleanup(dtorKind)) { | 
 | 703 |       // In principle we could tell the cleanup where we are more | 
 | 704 |       // directly, but the control flow can get so varied here that it | 
 | 705 |       // would actually be quite complex.  Therefore we go through an | 
 | 706 |       // alloca. | 
 | 707 |       endOfInit = CGF.CreateTempAlloca(begin->getType(), | 
 | 708 |                                        "arrayinit.endOfInit"); | 
 | 709 |       Builder.CreateStore(begin, endOfInit); | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 710 |       CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, | 
 | 711 |                                            CGF.getDestroyer(dtorKind)); | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 712 |       cleanup = CGF.EHStack.stable_begin(); | 
 | 713 |  | 
 | 714 |     // Otherwise, remember that we didn't need a cleanup. | 
 | 715 |     } else { | 
 | 716 |       dtorKind = QualType::DK_none; | 
| Lauro Ramos Venancio | 145cd89 | 2008-02-19 19:27:31 +0000 | [diff] [blame] | 717 |     } | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 718 |  | 
 | 719 |     llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1); | 
 | 720 |  | 
 | 721 |     // The 'current element to initialize'.  The invariants on this | 
 | 722 |     // variable are complicated.  Essentially, after each iteration of | 
 | 723 |     // the loop, it points to the last initialized element, except | 
 | 724 |     // that it points to the beginning of the array before any | 
 | 725 |     // elements have been initialized. | 
 | 726 |     llvm::Value *element = begin; | 
 | 727 |  | 
 | 728 |     // Emit the explicit initializers. | 
 | 729 |     for (uint64_t i = 0; i != NumInitElements; ++i) { | 
 | 730 |       // Advance to the next element. | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 731 |       if (i > 0) { | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 732 |         element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element"); | 
 | 733 |  | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 734 |         // Tell the cleanup that it needs to destroy up to this | 
 | 735 |         // element.  TODO: some of these stores can be trivially | 
 | 736 |         // observed to be unnecessary. | 
 | 737 |         if (endOfInit) Builder.CreateStore(element, endOfInit); | 
 | 738 |       } | 
 | 739 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 740 |       LValue elementLV = CGF.MakeAddrLValue(element, elementType); | 
 | 741 |       EmitInitializationToLValue(E->getInit(i), elementLV); | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 742 |     } | 
 | 743 |  | 
 | 744 |     // Check whether there's a non-trivial array-fill expression. | 
 | 745 |     // Note that this will be a CXXConstructExpr even if the element | 
 | 746 |     // type is an array (or array of array, etc.) of class type. | 
 | 747 |     Expr *filler = E->getArrayFiller(); | 
 | 748 |     bool hasTrivialFiller = true; | 
 | 749 |     if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) { | 
 | 750 |       assert(cons->getConstructor()->isDefaultConstructor()); | 
 | 751 |       hasTrivialFiller = cons->getConstructor()->isTrivial(); | 
 | 752 |     } | 
 | 753 |  | 
 | 754 |     // Any remaining elements need to be zero-initialized, possibly | 
 | 755 |     // using the filler expression.  We can skip this if the we're | 
 | 756 |     // emitting to zeroed memory. | 
 | 757 |     if (NumInitElements != NumArrayElements && | 
 | 758 |         !(Dest.isZeroed() && hasTrivialFiller && | 
 | 759 |           CGF.getTypes().isZeroInitializable(elementType))) { | 
 | 760 |  | 
 | 761 |       // Use an actual loop.  This is basically | 
 | 762 |       //   do { *array++ = filler; } while (array != end); | 
 | 763 |  | 
 | 764 |       // Advance to the start of the rest of the array. | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 765 |       if (NumInitElements) { | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 766 |         element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start"); | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 767 |         if (endOfInit) Builder.CreateStore(element, endOfInit); | 
 | 768 |       } | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 769 |  | 
 | 770 |       // Compute the end of the array. | 
 | 771 |       llvm::Value *end = Builder.CreateInBoundsGEP(begin, | 
 | 772 |                         llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements), | 
 | 773 |                                                    "arrayinit.end"); | 
 | 774 |  | 
 | 775 |       llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); | 
 | 776 |       llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); | 
 | 777 |  | 
 | 778 |       // Jump into the body. | 
 | 779 |       CGF.EmitBlock(bodyBB); | 
 | 780 |       llvm::PHINode *currentElement = | 
 | 781 |         Builder.CreatePHI(element->getType(), 2, "arrayinit.cur"); | 
 | 782 |       currentElement->addIncoming(element, entryBB); | 
 | 783 |  | 
 | 784 |       // Emit the actual filler expression. | 
 | 785 |       LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType); | 
 | 786 |       if (filler) | 
 | 787 |         EmitInitializationToLValue(filler, elementLV); | 
 | 788 |       else | 
 | 789 |         EmitNullInitializationToLValue(elementLV); | 
 | 790 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 791 |       // Move on to the next element. | 
 | 792 |       llvm::Value *nextElement = | 
 | 793 |         Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next"); | 
 | 794 |  | 
| John McCall | 2673c68 | 2011-07-11 08:38:19 +0000 | [diff] [blame] | 795 |       // Tell the EH cleanup that we finished with the last element. | 
 | 796 |       if (endOfInit) Builder.CreateStore(nextElement, endOfInit); | 
 | 797 |  | 
| John McCall | bdc4d80 | 2011-07-09 01:37:26 +0000 | [diff] [blame] | 798 |       // Leave the loop if we're done. | 
 | 799 |       llvm::Value *done = Builder.CreateICmpEQ(nextElement, end, | 
 | 800 |                                                "arrayinit.done"); | 
 | 801 |       llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end"); | 
 | 802 |       Builder.CreateCondBr(done, endBB, bodyBB); | 
 | 803 |       currentElement->addIncoming(nextElement, Builder.GetInsertBlock()); | 
 | 804 |  | 
 | 805 |       CGF.EmitBlock(endBB); | 
 | 806 |     } | 
 | 807 |  | 
 | 808 |     // Leave the partial-array cleanup if we entered one. | 
 | 809 |     if (dtorKind) CGF.DeactivateCleanupBlock(cleanup); | 
 | 810 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 811 |     return; | 
 | 812 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 813 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 814 |   assert(E->getType()->isRecordType() && "Only support structs/unions here!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 815 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 816 |   // Do struct initialization; this code just sets each individual member | 
 | 817 |   // to the approprate value.  This makes bitfield support automatic; | 
 | 818 |   // the disadvantage is that the generated code is more difficult for | 
 | 819 |   // the optimizer, especially with bitfields. | 
 | 820 |   unsigned NumInitElements = E->getNumInits(); | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 821 |   RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl(); | 
| Chris Lattner | bd7de38 | 2010-09-06 00:13:11 +0000 | [diff] [blame] | 822 |    | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 823 |   if (record->isUnion()) { | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 824 |     // Only initialize one field of a union. The field itself is | 
 | 825 |     // specified by the initializer list. | 
 | 826 |     if (!E->getInitializedFieldInUnion()) { | 
 | 827 |       // Empty union; we have nothing to do. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 828 |  | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 829 | #ifndef NDEBUG | 
 | 830 |       // Make sure that it's really an empty and not a failure of | 
 | 831 |       // semantic analysis. | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 832 |       for (RecordDecl::field_iterator Field = record->field_begin(), | 
 | 833 |                                    FieldEnd = record->field_end(); | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 834 |            Field != FieldEnd; ++Field) | 
 | 835 |         assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); | 
 | 836 | #endif | 
 | 837 |       return; | 
 | 838 |     } | 
 | 839 |  | 
 | 840 |     // FIXME: volatility | 
 | 841 |     FieldDecl *Field = E->getInitializedFieldInUnion(); | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 842 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 843 |     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 844 |     if (NumInitElements) { | 
 | 845 |       // Store the initializer into the field | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 846 |       EmitInitializationToLValue(E->getInit(0), FieldLoc); | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 847 |     } else { | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 848 |       // Default-initialize to null. | 
| John McCall | a07398e | 2011-06-16 04:16:24 +0000 | [diff] [blame] | 849 |       EmitNullInitializationToLValue(FieldLoc); | 
| Douglas Gregor | 0bb7689 | 2009-01-29 16:53:55 +0000 | [diff] [blame] | 850 |     } | 
 | 851 |  | 
 | 852 |     return; | 
 | 853 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 854 |  | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 855 |   // We'll need to enter cleanup scopes in case any of the member | 
 | 856 |   // initializers throw an exception. | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 857 |   SmallVector<EHScopeStack::stable_iterator, 16> cleanups; | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 858 |  | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 859 |   // Here we iterate over the fields; this makes it simpler to both | 
 | 860 |   // default-initialize fields and skip over unnamed fields. | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 861 |   unsigned curInitIndex = 0; | 
 | 862 |   for (RecordDecl::field_iterator field = record->field_begin(), | 
 | 863 |                                fieldEnd = record->field_end(); | 
 | 864 |        field != fieldEnd; ++field) { | 
 | 865 |     // We're done once we hit the flexible array member. | 
 | 866 |     if (field->getType()->isIncompleteArrayType()) | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 867 |       break; | 
 | 868 |  | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 869 |     // Always skip anonymous bitfields. | 
 | 870 |     if (field->isUnnamedBitfield()) | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 871 |       continue; | 
| Douglas Gregor | 34e7946 | 2009-01-28 23:36:17 +0000 | [diff] [blame] | 872 |  | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 873 |     // We're done if we reach the end of the explicit initializers, we | 
 | 874 |     // have a zeroed object, and the rest of the fields are | 
 | 875 |     // zero-initializable. | 
 | 876 |     if (curInitIndex == NumInitElements && Dest.isZeroed() && | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 877 |         CGF.getTypes().isZeroInitializable(E->getType())) | 
 | 878 |       break; | 
 | 879 |      | 
| Eli Friedman | 1e692ac | 2008-06-13 23:01:12 +0000 | [diff] [blame] | 880 |     // FIXME: volatility | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 881 |     LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0); | 
| Fariborz Jahanian | 14674ff | 2009-05-27 19:54:11 +0000 | [diff] [blame] | 882 |     // We never generate write-barries for initialized fields. | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 883 |     LV.setNonGC(true); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 884 |      | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 885 |     if (curInitIndex < NumInitElements) { | 
| Chris Lattner | b35baae | 2010-03-08 21:08:07 +0000 | [diff] [blame] | 886 |       // Store the initializer into the field. | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 887 |       EmitInitializationToLValue(E->getInit(curInitIndex++), LV); | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 888 |     } else { | 
 | 889 |       // We're out of initalizers; default-initialize to null | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 890 |       EmitNullInitializationToLValue(LV); | 
 | 891 |     } | 
 | 892 |  | 
 | 893 |     // Push a destructor if necessary. | 
 | 894 |     // FIXME: if we have an array of structures, all explicitly | 
 | 895 |     // initialized, we can end up pushing a linear number of cleanups. | 
 | 896 |     bool pushedCleanup = false; | 
 | 897 |     if (QualType::DestructionKind dtorKind | 
 | 898 |           = field->getType().isDestructedType()) { | 
 | 899 |       assert(LV.isSimple()); | 
 | 900 |       if (CGF.needsEHCleanup(dtorKind)) { | 
 | 901 |         CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(), | 
 | 902 |                         CGF.getDestroyer(dtorKind), false); | 
 | 903 |         cleanups.push_back(CGF.EHStack.stable_begin()); | 
 | 904 |         pushedCleanup = true; | 
 | 905 |       } | 
| Chris Lattner | f81557c | 2008-04-04 18:42:16 +0000 | [diff] [blame] | 906 |     } | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 907 |      | 
 | 908 |     // If the GEP didn't get used because of a dead zero init or something | 
 | 909 |     // else, clean it up for -O0 builds and general tidiness. | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 910 |     if (!pushedCleanup && LV.isSimple())  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 911 |       if (llvm::GetElementPtrInst *GEP = | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 912 |             dyn_cast<llvm::GetElementPtrInst>(LV.getAddress())) | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 913 |         if (GEP->use_empty()) | 
 | 914 |           GEP->eraseFromParent(); | 
| Lauro Ramos Venancio | 145cd89 | 2008-02-19 19:27:31 +0000 | [diff] [blame] | 915 |   } | 
| John McCall | 2b30dcf | 2011-07-11 19:35:02 +0000 | [diff] [blame] | 916 |  | 
 | 917 |   // Deactivate all the partial cleanups in reverse order, which | 
 | 918 |   // generally means popping them. | 
 | 919 |   for (unsigned i = cleanups.size(); i != 0; --i) | 
 | 920 |     CGF.DeactivateCleanupBlock(cleanups[i-1]); | 
| Devang Patel | 636c3d0 | 2007-10-26 17:44:44 +0000 | [diff] [blame] | 921 | } | 
 | 922 |  | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 923 | //===----------------------------------------------------------------------===// | 
 | 924 | //                        Entry Points into this File | 
 | 925 | //===----------------------------------------------------------------------===// | 
 | 926 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 927 | /// GetNumNonZeroBytesInInit - Get an approximate count of the number of | 
 | 928 | /// non-zero bytes that will be stored when outputting the initializer for the | 
 | 929 | /// specified initializer expression. | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 930 | static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 931 |   E = E->IgnoreParens(); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 932 |  | 
 | 933 |   // 0 and 0.0 won't require any non-zero stores! | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 934 |   if (isSimpleZero(E, CGF)) return CharUnits::Zero(); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 935 |  | 
 | 936 |   // If this is an initlist expr, sum up the size of sizes of the (present) | 
 | 937 |   // elements.  If this is something weird, assume the whole thing is non-zero. | 
 | 938 |   const InitListExpr *ILE = dyn_cast<InitListExpr>(E); | 
 | 939 |   if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType())) | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 940 |     return CGF.getContext().getTypeSizeInChars(E->getType()); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 941 |    | 
| Chris Lattner | d1d56df | 2010-12-02 18:29:00 +0000 | [diff] [blame] | 942 |   // InitListExprs for structs have to be handled carefully.  If there are | 
 | 943 |   // reference members, we need to consider the size of the reference, not the | 
 | 944 |   // referencee.  InitListExprs for unions and arrays can't have references. | 
| Chris Lattner | 8c00ad1 | 2010-12-02 22:52:04 +0000 | [diff] [blame] | 945 |   if (const RecordType *RT = E->getType()->getAs<RecordType>()) { | 
 | 946 |     if (!RT->isUnionType()) { | 
 | 947 |       RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 948 |       CharUnits NumNonZeroBytes = CharUnits::Zero(); | 
| Chris Lattner | 8c00ad1 | 2010-12-02 22:52:04 +0000 | [diff] [blame] | 949 |        | 
 | 950 |       unsigned ILEElement = 0; | 
 | 951 |       for (RecordDecl::field_iterator Field = SD->field_begin(), | 
 | 952 |            FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) { | 
 | 953 |         // We're done once we hit the flexible array member or run out of | 
 | 954 |         // InitListExpr elements. | 
 | 955 |         if (Field->getType()->isIncompleteArrayType() || | 
 | 956 |             ILEElement == ILE->getNumInits()) | 
 | 957 |           break; | 
 | 958 |         if (Field->isUnnamedBitfield()) | 
 | 959 |           continue; | 
| Chris Lattner | d1d56df | 2010-12-02 18:29:00 +0000 | [diff] [blame] | 960 |  | 
| Chris Lattner | 8c00ad1 | 2010-12-02 22:52:04 +0000 | [diff] [blame] | 961 |         const Expr *E = ILE->getInit(ILEElement++); | 
 | 962 |          | 
 | 963 |         // Reference values are always non-null and have the width of a pointer. | 
 | 964 |         if (Field->getType()->isReferenceType()) | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 965 |           NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits( | 
 | 966 |               CGF.getContext().Target.getPointerWidth(0)); | 
| Chris Lattner | 8c00ad1 | 2010-12-02 22:52:04 +0000 | [diff] [blame] | 967 |         else | 
 | 968 |           NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF); | 
 | 969 |       } | 
| Chris Lattner | d1d56df | 2010-12-02 18:29:00 +0000 | [diff] [blame] | 970 |        | 
| Chris Lattner | 8c00ad1 | 2010-12-02 22:52:04 +0000 | [diff] [blame] | 971 |       return NumNonZeroBytes; | 
| Chris Lattner | d1d56df | 2010-12-02 18:29:00 +0000 | [diff] [blame] | 972 |     } | 
| Chris Lattner | d1d56df | 2010-12-02 18:29:00 +0000 | [diff] [blame] | 973 |   } | 
 | 974 |    | 
 | 975 |    | 
| Ken Dyck | 02c4533 | 2011-04-24 17:17:56 +0000 | [diff] [blame] | 976 |   CharUnits NumNonZeroBytes = CharUnits::Zero(); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 977 |   for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) | 
 | 978 |     NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF); | 
 | 979 |   return NumNonZeroBytes; | 
 | 980 | } | 
 | 981 |  | 
 | 982 | /// CheckAggExprForMemSetUse - If the initializer is large and has a lot of | 
 | 983 | /// zeros in it, emit a memset and avoid storing the individual zeros. | 
 | 984 | /// | 
 | 985 | static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, | 
 | 986 |                                      CodeGenFunction &CGF) { | 
 | 987 |   // If the slot is already known to be zeroed, nothing to do.  Don't mess with | 
 | 988 |   // volatile stores. | 
 | 989 |   if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return; | 
| Argyrios Kyrtzidis | 657baf1 | 2011-04-28 22:57:55 +0000 | [diff] [blame] | 990 |  | 
 | 991 |   // C++ objects with a user-declared constructor don't need zero'ing. | 
 | 992 |   if (CGF.getContext().getLangOptions().CPlusPlus) | 
 | 993 |     if (const RecordType *RT = CGF.getContext() | 
 | 994 |                        .getBaseElementType(E->getType())->getAs<RecordType>()) { | 
 | 995 |       const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); | 
 | 996 |       if (RD->hasUserDeclaredConstructor()) | 
 | 997 |         return; | 
 | 998 |     } | 
 | 999 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1000 |   // If the type is 16-bytes or smaller, prefer individual stores over memset. | 
| Ken Dyck | 5ff1a35 | 2011-04-24 17:25:32 +0000 | [diff] [blame] | 1001 |   std::pair<CharUnits, CharUnits> TypeInfo = | 
 | 1002 |     CGF.getContext().getTypeInfoInChars(E->getType()); | 
 | 1003 |   if (TypeInfo.first <= CharUnits::fromQuantity(16)) | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1004 |     return; | 
 | 1005 |  | 
 | 1006 |   // Check to see if over 3/4 of the initializer are known to be zero.  If so, | 
 | 1007 |   // we prefer to emit memset + individual stores for the rest. | 
| Ken Dyck | 5ff1a35 | 2011-04-24 17:25:32 +0000 | [diff] [blame] | 1008 |   CharUnits NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF); | 
 | 1009 |   if (NumNonZeroBytes*4 > TypeInfo.first) | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1010 |     return; | 
 | 1011 |    | 
 | 1012 |   // Okay, it seems like a good idea to use an initial memset, emit the call. | 
| Ken Dyck | 5ff1a35 | 2011-04-24 17:25:32 +0000 | [diff] [blame] | 1013 |   llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first.getQuantity()); | 
 | 1014 |   CharUnits Align = TypeInfo.second; | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1015 |  | 
 | 1016 |   llvm::Value *Loc = Slot.getAddr(); | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 1017 |   llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1018 |    | 
 | 1019 |   Loc = CGF.Builder.CreateBitCast(Loc, BP); | 
| Ken Dyck | 5ff1a35 | 2011-04-24 17:25:32 +0000 | [diff] [blame] | 1020 |   CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal,  | 
 | 1021 |                            Align.getQuantity(), false); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1022 |    | 
 | 1023 |   // Tell the AggExprEmitter that the slot is known zero. | 
 | 1024 |   Slot.setZeroed(); | 
 | 1025 | } | 
 | 1026 |  | 
 | 1027 |  | 
 | 1028 |  | 
 | 1029 |  | 
| Mike Stump | e1129a9 | 2009-05-26 18:57:45 +0000 | [diff] [blame] | 1030 | /// EmitAggExpr - Emit the computation of the specified expression of aggregate | 
 | 1031 | /// type.  The result is computed into DestPtr.  Note that if DestPtr is null, | 
 | 1032 | /// the value of the aggregate expression is not needed.  If VolatileDest is | 
 | 1033 | /// true, DestPtr cannot be 0. | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 1034 | /// | 
 | 1035 | /// \param IsInitializer - true if this evaluation is initializing an | 
 | 1036 | /// object whose lifetime is already being managed. | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 1037 | void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot, | 
| Fariborz Jahanian | 474e2fe | 2010-09-16 00:20:07 +0000 | [diff] [blame] | 1038 |                                   bool IgnoreResult) { | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 1039 |   assert(E && hasAggregateLLVMType(E->getType()) && | 
 | 1040 |          "Invalid aggregate expression to emit"); | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1041 |   assert((Slot.getAddr() != 0 || Slot.isIgnored()) && | 
 | 1042 |          "slot has bits but no address"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1043 |  | 
| Chris Lattner | 1b72677 | 2010-12-02 07:07:26 +0000 | [diff] [blame] | 1044 |   // Optimize the slot if possible. | 
 | 1045 |   CheckAggExprForMemSetUse(Slot, E, *this); | 
 | 1046 |   | 
 | 1047 |   AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E)); | 
| Chris Lattner | ee755f9 | 2007-08-21 04:59:27 +0000 | [diff] [blame] | 1048 | } | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1049 |  | 
| Daniel Dunbar | 18aba0d | 2010-02-05 19:38:31 +0000 | [diff] [blame] | 1050 | LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { | 
 | 1051 |   assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!"); | 
| Daniel Dunbar | 195337d | 2010-02-09 02:48:28 +0000 | [diff] [blame] | 1052 |   llvm::Value *Temp = CreateMemTemp(E->getType()); | 
| Daniel Dunbar | 79c3928 | 2010-08-21 03:15:20 +0000 | [diff] [blame] | 1053 |   LValue LV = MakeAddrLValue(Temp, E->getType()); | 
| John McCall | 7c2349b | 2011-08-25 20:40:09 +0000 | [diff] [blame] | 1054 |   EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed, | 
 | 1055 |                                          AggValueSlot::DoesNotNeedGCBarriers)); | 
| Daniel Dunbar | 79c3928 | 2010-08-21 03:15:20 +0000 | [diff] [blame] | 1056 |   return LV; | 
| Daniel Dunbar | 18aba0d | 2010-02-05 19:38:31 +0000 | [diff] [blame] | 1057 | } | 
 | 1058 |  | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1059 | void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, | 
| Mike Stump | 27fe2e6 | 2009-05-23 22:29:41 +0000 | [diff] [blame] | 1060 |                                         llvm::Value *SrcPtr, QualType Ty, | 
 | 1061 |                                         bool isVolatile) { | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1062 |   assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1063 |  | 
| Anders Carlsson | 0d7c583 | 2010-05-03 01:20:20 +0000 | [diff] [blame] | 1064 |   if (getContext().getLangOptions().CPlusPlus) { | 
 | 1065 |     if (const RecordType *RT = Ty->getAs<RecordType>()) { | 
| Douglas Gregor | e997948 | 2010-05-20 15:39:01 +0000 | [diff] [blame] | 1066 |       CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); | 
 | 1067 |       assert((Record->hasTrivialCopyConstructor() ||  | 
| Fariborz Jahanian | 1d49f21 | 2010-05-20 16:46:55 +0000 | [diff] [blame] | 1068 |               Record->hasTrivialCopyAssignment()) && | 
| Douglas Gregor | e997948 | 2010-05-20 15:39:01 +0000 | [diff] [blame] | 1069 |              "Trying to aggregate-copy a type without a trivial copy " | 
 | 1070 |              "constructor or assignment operator"); | 
| Douglas Gregor | 419aa96 | 2010-05-20 15:48:29 +0000 | [diff] [blame] | 1071 |       // Ignore empty classes in C++. | 
| Douglas Gregor | e997948 | 2010-05-20 15:39:01 +0000 | [diff] [blame] | 1072 |       if (Record->isEmpty()) | 
| Anders Carlsson | 0d7c583 | 2010-05-03 01:20:20 +0000 | [diff] [blame] | 1073 |         return; | 
 | 1074 |     } | 
 | 1075 |   } | 
 | 1076 |    | 
| Chris Lattner | 83c9629 | 2009-02-28 18:31:01 +0000 | [diff] [blame] | 1077 |   // Aggregate assignment turns into llvm.memcpy.  This is almost valid per | 
| Chris Lattner | ca4fc2c | 2009-02-28 18:18:58 +0000 | [diff] [blame] | 1078 |   // C99 6.5.16.1p3, which states "If the value being stored in an object is | 
 | 1079 |   // read from another object that overlaps in anyway the storage of the first | 
 | 1080 |   // object, then the overlap shall be exact and the two objects shall have | 
 | 1081 |   // qualified or unqualified versions of a compatible type." | 
 | 1082 |   // | 
| Chris Lattner | 83c9629 | 2009-02-28 18:31:01 +0000 | [diff] [blame] | 1083 |   // memcpy is not defined if the source and destination pointers are exactly | 
| Chris Lattner | ca4fc2c | 2009-02-28 18:18:58 +0000 | [diff] [blame] | 1084 |   // equal, but other compilers do this optimization, and almost every memcpy | 
 | 1085 |   // implementation handles this case safely.  If there is a libc that does not | 
 | 1086 |   // safely handle this, we can add a target hook. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1087 |  | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1088 |   // Get size and alignment info for this aggregate. | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1089 |   std::pair<CharUnits, CharUnits> TypeInfo =  | 
 | 1090 |     getContext().getTypeInfoInChars(Ty); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1091 |  | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1092 |   // FIXME: Handle variable sized types. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1093 |  | 
| Mike Stump | fde6420 | 2009-05-23 04:13:59 +0000 | [diff] [blame] | 1094 |   // FIXME: If we have a volatile struct, the optimizer can remove what might | 
 | 1095 |   // appear to be `extra' memory ops: | 
 | 1096 |   // | 
 | 1097 |   // volatile struct { int i; } a, b; | 
 | 1098 |   // | 
 | 1099 |   // int main() { | 
 | 1100 |   //   a = b; | 
 | 1101 |   //   a = b; | 
 | 1102 |   // } | 
 | 1103 |   // | 
| Mon P Wang | 3ecd785 | 2010-04-04 03:10:52 +0000 | [diff] [blame] | 1104 |   // we need to use a different call here.  We use isVolatile to indicate when | 
| Mike Stump | 49d1cd5 | 2009-05-26 22:03:21 +0000 | [diff] [blame] | 1105 |   // either the source or the destination is volatile. | 
| Mon P Wang | 3ecd785 | 2010-04-04 03:10:52 +0000 | [diff] [blame] | 1106 |  | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 1107 |   llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); | 
 | 1108 |   llvm::Type *DBP = | 
| John McCall | d16c2cf | 2011-02-08 08:22:06 +0000 | [diff] [blame] | 1109 |     llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace()); | 
| Chris Lattner | 098432c | 2010-07-08 00:07:45 +0000 | [diff] [blame] | 1110 |   DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp"); | 
| Mon P Wang | 3ecd785 | 2010-04-04 03:10:52 +0000 | [diff] [blame] | 1111 |  | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 1112 |   llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); | 
 | 1113 |   llvm::Type *SBP = | 
| John McCall | d16c2cf | 2011-02-08 08:22:06 +0000 | [diff] [blame] | 1114 |     llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace()); | 
| Chris Lattner | 098432c | 2010-07-08 00:07:45 +0000 | [diff] [blame] | 1115 |   SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp"); | 
| Mon P Wang | 3ecd785 | 2010-04-04 03:10:52 +0000 | [diff] [blame] | 1116 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1117 |   // Don't do any of the memmove_collectable tests if GC isn't set. | 
 | 1118 |   if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) { | 
 | 1119 |     // fall through | 
 | 1120 |   } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { | 
| Fariborz Jahanian | 55bcace | 2010-06-15 22:44:06 +0000 | [diff] [blame] | 1121 |     RecordDecl *Record = RecordTy->getDecl(); | 
 | 1122 |     if (Record->hasObjectMember()) { | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1123 |       CharUnits size = TypeInfo.first; | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 1124 |       llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1125 |       llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity()); | 
| Fariborz Jahanian | 55bcace | 2010-06-15 22:44:06 +0000 | [diff] [blame] | 1126 |       CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,  | 
 | 1127 |                                                     SizeVal); | 
 | 1128 |       return; | 
 | 1129 |     } | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1130 |   } else if (Ty->isArrayType()) { | 
| Fariborz Jahanian | 55bcace | 2010-06-15 22:44:06 +0000 | [diff] [blame] | 1131 |     QualType BaseType = getContext().getBaseElementType(Ty); | 
 | 1132 |     if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) { | 
 | 1133 |       if (RecordTy->getDecl()->hasObjectMember()) { | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1134 |         CharUnits size = TypeInfo.first; | 
| Chris Lattner | 2acc6e3 | 2011-07-18 04:24:23 +0000 | [diff] [blame] | 1135 |         llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1136 |         llvm::Value *SizeVal =  | 
 | 1137 |           llvm::ConstantInt::get(SizeTy, size.getQuantity()); | 
| Fariborz Jahanian | 55bcace | 2010-06-15 22:44:06 +0000 | [diff] [blame] | 1138 |         CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,  | 
 | 1139 |                                                       SizeVal); | 
 | 1140 |         return; | 
 | 1141 |       } | 
 | 1142 |     } | 
 | 1143 |   } | 
 | 1144 |    | 
| Benjamin Kramer | 9f0c7cc | 2010-12-30 00:13:21 +0000 | [diff] [blame] | 1145 |   Builder.CreateMemCpy(DestPtr, SrcPtr, | 
| Ken Dyck | 1a8c15a | 2011-04-24 17:37:26 +0000 | [diff] [blame] | 1146 |                        llvm::ConstantInt::get(IntPtrTy,  | 
 | 1147 |                                               TypeInfo.first.getQuantity()), | 
 | 1148 |                        TypeInfo.second.getQuantity(), isVolatile); | 
| Daniel Dunbar | 7482d12 | 2008-09-09 20:49:46 +0000 | [diff] [blame] | 1149 | } |