CGExprAgg.cpp revision 2d6b0e94db30c0e2754d270753c6f75478e451bf
12240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
92240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner//
107152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner// This contains code to emit Aggregate Expr nodes as LLVM code.
117152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner//
127152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner//===----------------------------------------------------------------------===//
137152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
142240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner#include "CodeGenFunction.h"
157152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner#include "CodeGenModule.h"
167152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner#include "CGObjCRuntime.h"
177152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner#include "clang/AST/ASTContext.h"
18543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner#include "clang/AST/DeclCXX.h"
19543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner#include "clang/AST/StmtVisitor.h"
20543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner#include "llvm/Constants.h"
21543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner#include "llvm/Function.h"
22d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner#include "llvm/GlobalVariable.h"
23d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner#include "llvm/Intrinsics.h"
24d64152a70842b2f4186aa912938e69ca09c1434cChris Lattnerusing namespace clang;
25d64152a70842b2f4186aa912938e69ca09c1434cChris Lattnerusing namespace CodeGen;
26d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
27d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner//===----------------------------------------------------------------------===//
280cade261322242132905914f613d25d16e1a9ff6Nick Lewycky//                        Aggregate Expression Emitter
297f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner//===----------------------------------------------------------------------===//
307f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner
312240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattnernamespace  {
327152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnerclass AggExprEmitter : public StmtVisitor<AggExprEmitter> {
337152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  CodeGenFunction &CGF;
347152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  CGBuilderTy &Builder;
357152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  llvm::Value *DestPtr;
367152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  bool VolatileDest;
377152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  bool IgnoreResult;
387152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  bool IsInitializer;
392240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  bool RequiresGCollection;
407152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
417152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  ReturnValueSlot getReturnValueSlot() const {
42d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    return ReturnValueSlot(DestPtr, VolatileDest);
437152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  }
447152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnerpublic:
457152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
467152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                 bool ignore, bool isinit, bool requiresGCollection)
477152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    : CGF(cgf), Builder(CGF.Builder),
487f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner      DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
497f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner      IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
502240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  }
512240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
522240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  //===--------------------------------------------------------------------===//
530e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner  //                               Utilities
543fc6ef1bb96d9a3194cef667a2d3cbc94e3fb189Chris Lattner  //===--------------------------------------------------------------------===//
556a35b40250735a50efe66c88414cdd3b79185019Chris Lattner
56ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  /// EmitAggLoadOfLValue - Given an expression with aggregate type that
572240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  /// represents a value lvalue, this method emits the address of the lvalue,
582240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  /// then loads the result into DestPtr.
592240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void EmitAggLoadOfLValue(const Expr *E);
602240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
610cade261322242132905914f613d25d16e1a9ff6Nick Lewycky  /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
62543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
63551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer  void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
64f8485c643412dbff46fe87ea2867445169a5c28eChris Lattner
65d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  //===--------------------------------------------------------------------===//
660e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner  //                            Visitor Methods
670e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner  //===--------------------------------------------------------------------===//
682240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
690e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner  void VisitStmt(Stmt *S) {
703e8b6631e67e01e4960a7ba4668a50c596607473Chris Lattner    CGF.ErrorUnsupported(S, "aggregate expression");
71ecd94c804a563f2a86572dcf1d2e81f397e19daaNick Lewycky  }
72ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman  void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
73794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel  void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
742240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
757152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // l-values.
767152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
777152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
78ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
790cade261322242132905914f613d25d16e1a9ff6Nick Lewycky  void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
80ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
817152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    EmitAggLoadOfLValue(E);
82543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
832240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
842240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner    EmitAggLoadOfLValue(E);
852240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  }
86844731a7f1909f55935e3514c9e713a62d67662eDan Gohman  void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
87844731a7f1909f55935e3514c9e713a62d67662eDan Gohman    EmitAggLoadOfLValue(E);
88844731a7f1909f55935e3514c9e713a62d67662eDan Gohman  }
89d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void VisitPredefinedExpr(const PredefinedExpr *E) {
90f8485c643412dbff46fe87ea2867445169a5c28eChris Lattner    EmitAggLoadOfLValue(E);
91f8485c643412dbff46fe87ea2867445169a5c28eChris Lattner  }
92f8485c643412dbff46fe87ea2867445169a5c28eChris Lattner
933fc6ef1bb96d9a3194cef667a2d3cbc94e3fb189Chris Lattner  // Operators.
94cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitCastExpr(CastExpr *E);
95cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitCallExpr(const CallExpr *E);
96cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitStmtExpr(const StmtExpr *E);
97cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitBinaryOperator(const BinaryOperator *BO);
98cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
99cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitBinAssign(const BinaryOperator *E);
100cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitBinComma(const BinaryOperator *E);
101cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitUnaryAddrOf(const UnaryOperator *E);
102cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky
1030cade261322242132905914f613d25d16e1a9ff6Nick Lewycky  void VisitObjCMessageExpr(ObjCMessageExpr *E);
1047f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
1057f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner    EmitAggLoadOfLValue(E);
106ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  }
107ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
108ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E);
1097f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner
110ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitConditionalOperator(const ConditionalOperator *CO);
111cb19438f63019eb557c1fbaeae8a6de78b03c584Nick Lewycky  void VisitChooseExpr(const ChooseExpr *CE);
112ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitInitListExpr(InitListExpr *E);
113ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
114ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
115ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    Visit(DAE->getExpr());
116ecb7a77885b174cf4d001a9b48533b3979e7810dDan Gohman  }
117ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
118ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCXXConstructExpr(const CXXConstructExpr *E);
119ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
120ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
1217f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
1227f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner
1232240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void VisitVAArgExpr(VAArgExpr *E);
1242240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
1252240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
1262240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void EmitNullInitializationToLValue(LValue Address, QualType T);
1272240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  //  case Expr::ChooseExprClass:
1282240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
129ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner};
1300cade261322242132905914f613d25d16e1a9ff6Nick Lewycky}  // end anonymous namespace.
1312240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
1322240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner//===----------------------------------------------------------------------===//
1337f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner//                                Utilities
1347f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner//===----------------------------------------------------------------------===//
135ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner
136ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner/// EmitAggLoadOfLValue - Given an expression with aggregate type that
137ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner/// represents a value lvalue, this method emits the address of the lvalue,
138ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner/// then loads the result into DestPtr.
139ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattnervoid AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
140ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  LValue LV = CGF.EmitLValue(E);
1417f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  EmitFinalDestCopy(E, LV);
1427f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner}
1437f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner
144ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
145ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattnervoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
14600b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen  assert(Src.isAggregate() && "value must be aggregate value!");
1474c0e4cdc40bbf94766242294fe386f4eb2d32d2eChris Lattner
148ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  // If the result is ignored, don't copy from the value.
1497f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  if (DestPtr == 0) {
15032b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner    if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
15132b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner      return;
15232b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner    // If the source is volatile, we must read from it; to do that, we need
15332b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner    // some place to put it.
15432b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner    DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
15532b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner  }
15632b1e87f111d79f3f5b0e86c8f138c02bef8aa18Chris Lattner
157fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman  if (RequiresGCollection) {
158ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
159ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner                                              DestPtr, Src.getAggregateAddr(),
160ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner                                              E->getType());
161ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    return;
162ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  }
163ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  // If the result of the assignment is used, copy the LHS there also.
164cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner  // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
165cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner  // from the source as well, as we can't eliminate it if either operand
166cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner  // is volatile, unless copy has volatile for both source and destination..
167cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner  CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(),
168cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner                        VolatileDest|Src.isVolatileQualified());
169cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner}
170cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner
171cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
172cf2f89251d45bc9783917874adb9029f71d50068Chris Lattnervoid AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
173cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner  assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
174ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner
175ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
176ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner                                            Src.isVolatileQualified()),
177cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner                    Ignore);
178cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner}
179cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner
180cf2f89251d45bc9783917874adb9029f71d50068Chris Lattner//===----------------------------------------------------------------------===//
1817f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner//                            Visitor Methods
1827f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner//===----------------------------------------------------------------------===//
1837f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner
1847f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattnervoid AggExprEmitter::VisitCastExpr(CastExpr *E) {
1857f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  if (!DestPtr && E->getCastKind() != CastExpr::CK_Dynamic) {
1867f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner    Visit(E->getSubExpr());
187c5dc660ea0b153904de601eadd40fa4962c8c71cChris Lattner    return;
1887f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  }
189c5dc660ea0b153904de601eadd40fa4962c8c71cChris Lattner
190c5dc660ea0b153904de601eadd40fa4962c8c71cChris Lattner  switch (E->getCastKind()) {
1917f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  default: assert(0 && "Unhandled cast kind!");
1922240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner
1932240d2b3f7b9f5835868c83ce78d125d1b65212bChris Lattner  case CastExpr::CK_Dynamic: {
1947152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
1957152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
196543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    // FIXME: Do we also need to handle property references here?
197543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    if (LV.isSimple())
198543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
199543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    else
2007152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner      CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
2017152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
2027152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    if (DestPtr)
2036a35b40250735a50efe66c88414cdd3b79185019Chris Lattner      CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
2047152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    break;
2056a35b40250735a50efe66c88414cdd3b79185019Chris Lattner  }
2060cade261322242132905914f613d25d16e1a9ff6Nick Lewycky
2076a35b40250735a50efe66c88414cdd3b79185019Chris Lattner  case CastExpr::CK_ToUnion: {
2086a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    // GCC union extension
2096a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    QualType PtrTy =
2106a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    CGF.getContext().getPointerType(E->getSubExpr()->getType());
2116a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
2126a35b40250735a50efe66c88414cdd3b79185019Chris Lattner                                                 CGF.ConvertType(PtrTy));
2136a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    EmitInitializationToLValue(E->getSubExpr(),
2146a35b40250735a50efe66c88414cdd3b79185019Chris Lattner                               LValue::MakeAddr(CastPtr, Qualifiers()),
2156a35b40250735a50efe66c88414cdd3b79185019Chris Lattner                               E->getSubExpr()->getType());
2166a35b40250735a50efe66c88414cdd3b79185019Chris Lattner    break;
2176a35b40250735a50efe66c88414cdd3b79185019Chris Lattner  }
2187152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
2197152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  case CastExpr::CK_DerivedToBase:
2207152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  case CastExpr::CK_BaseToDerived:
2217152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  case CastExpr::CK_UncheckedDerivedToBase: {
2227152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: "
2237152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                "should have been unpacked before we got here");
2247152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    break;
2257152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  }
2267152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
2277152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // FIXME: Remove the CK_Unknown check here.
2287152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  case CastExpr::CK_Unknown:
2297152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  case CastExpr::CK_NoOp:
230d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_UserDefinedConversion:
231d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_ConstructorConversion:
232d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
233d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner                                                   E->getType()) &&
234d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner           "Implicit cast types must be compatible");
235d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    Visit(E->getSubExpr());
236d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    break;
237d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
238d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_NullToMemberPointer: {
239d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    // If the subexpression's type is the C++0x nullptr_t, emit the
240d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    // subexpression, which may have side effects.
241d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    if (E->getSubExpr()->getType()->isNullPtrType())
242d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner      Visit(E->getSubExpr());
243d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
244d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    const llvm::Type *PtrDiffTy =
245d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner      CGF.ConvertType(CGF.getContext().getPointerDiffType());
246e4d5c441e04bdc00ccf1804744af670655123b07Chris Lattner
247d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy);
248fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman    llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr");
249d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    Builder.CreateStore(NullValue, Ptr, VolatileDest);
250d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
251d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj");
252d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    Builder.CreateStore(NullValue, Adj, VolatileDest);
253d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
254d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    break;
255d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  }
256d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
257d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_BitCast: {
258d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    // This must be a member function pointer cast.
259d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    Visit(E->getSubExpr());
260d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    break;
261d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  }
262d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
263d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_DerivedToBaseMemberPointer:
264d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  case CastExpr::CK_BaseToDerivedMemberPointer: {
265d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    QualType SrcType = E->getSubExpr()->getType();
266d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
267d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
268d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
269d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
270d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
271d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    SrcPtr = Builder.CreateLoad(SrcPtr);
272d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
273d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
274d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    SrcAdj = Builder.CreateLoad(SrcAdj);
275d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
276d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
277d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
278d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
279d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
280d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner
281d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    // Now See if we need to update the adjustment.
282d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    const CXXRecordDecl *BaseDecl =
283d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner      cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()->
284d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner                          getClass()->getAs<RecordType>()->getDecl());
2857152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    const CXXRecordDecl *DerivedDecl =
286543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
287543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner                          getClass()->getAs<RecordType>()->getDecl());
288543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
289543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      std::swap(DerivedDecl, BaseDecl);
290543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
291543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    if (llvm::Constant *Adj =
292543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, E->getBasePath())) {
293543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
294543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner        SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
295543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      else
296543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner        SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
29707e6e56f57e8781a8d7bc601cc9034a3741d84c2Anton Korobeynikov    }
29807e6e56f57e8781a8d7bc601cc9034a3741d84c2Anton Korobeynikov
299543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
300543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    break;
301543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
302543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
303543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner}
304543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
305543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattnervoid AggExprEmitter::VisitCallExpr(const CallExpr *E) {
306543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  if (E->getCallReturnType()->isReferenceType()) {
307543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    EmitAggLoadOfLValue(E);
308d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    return;
309543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
310543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
3117152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // If the struct doesn't require GC, we can just pass the destination
312ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  // directly to EmitCall.
3130cade261322242132905914f613d25d16e1a9ff6Nick Lewycky  if (!RequiresGCollection) {
314ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    CGF.EmitCallExpr(E, getReturnValueSlot());
3157152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    return;
3167152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  }
3177152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3187152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  RValue RV = CGF.EmitCallExpr(E);
3197152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  EmitFinalDestCopy(E, RV);
3208d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner}
3218d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner
3228d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattnervoid AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
3238d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner  CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
3248d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner}
3258d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner
3268d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattnervoid AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
3278d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner  CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
3288d9455d4e4f63c368f17b74a36b472fc61685310Chris Lattner}
3297152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3307152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnervoid AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
3317152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                                   ObjCImplicitSetterGetterRefExpr *E) {
3327152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
3337152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner}
3347152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3357152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnervoid AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
3367152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
3377152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
3387152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                  /*IgnoreResult=*/false, IsInitializer);
3397152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner}
3407152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3417152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnervoid AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
3427152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // We have a member function pointer.
3437152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
344ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  (void) MPT;
345ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  assert(MPT->getPointeeType()->isFunctionProtoType() &&
346ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner         "Unexpected member pointer type!");
347ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner
348ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  // The creation of member function pointers has no side effects; if
349543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  // there is no destination pointer, we have nothing to do.
350543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  if (!DestPtr)
351543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    return;
352543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
353543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
354543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  const CXXMethodDecl *MD =
355543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    cast<CXXMethodDecl>(DRE->getDecl())->getCanonicalDecl();
356543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
3577152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  const llvm::Type *PtrDiffTy =
3587152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    CGF.ConvertType(CGF.getContext().getPointerDiffType());
3597152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3607152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3617152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
362543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  llvm::Value *FuncPtr;
363543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
364543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  if (MD->isVirtual()) {
365543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    int64_t Index = CGF.CGM.getVTables().getMethodVTableIndex(MD);
366543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
367543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    // FIXME: We shouldn't use / 8 here.
368543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    uint64_t PointerWidthInBytes =
369543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      CGF.CGM.getContext().Target.getPointerWidth(0) / 8;
370543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
371543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    // Itanium C++ ABI 2.3:
372543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    //   For a non-virtual function, this field is a simple function pointer.
373543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    //   For a virtual function, it is 1 plus the virtual table offset
374543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    //   (in bytes) of the function, represented as a ptrdiff_t.
375543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    FuncPtr = llvm::ConstantInt::get(PtrDiffTy,
3767152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                                     (Index * PointerWidthInBytes) + 1);
3777152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  } else {
378d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
379d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    const llvm::Type *Ty =
380d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner      CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD),
381826c49132a9cba1e08a5fce78d05561d9a3746ceDevang Patel                                         FPT->isVariadic());
3823b5f45042b17ad52815e3dd6c0c1df99f196dd04Chris Lattner    llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty);
383d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner    FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy);
384d64152a70842b2f4186aa912938e69ca09c1434cChris Lattner  }
3857152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
3867152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3877152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
3887152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
3897152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // The adjustment will always be 0.
3907152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr,
3911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson                      VolatileDest);
3926934a04a8c15e9971cd1ea4d5c8df2d7afdd5be5Chris Lattner}
3936934a04a8c15e9971cd1ea4d5c8df2d7afdd5be5Chris Lattner
394051a950000e21935165db56695e35bade668193bGabor Greifvoid AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
395fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman  CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
396ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner}
397ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner
398ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattnervoid AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
399ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  if (E->getOpcode() == BinaryOperator::PtrMemD ||
400ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner      E->getOpcode() == BinaryOperator::PtrMemI)
401ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    VisitPointerToDataMemberBinaryOperator(E);
402ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  else
403ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    CGF.ErrorUnsupported(E, "aggregate binary expression");
404ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner}
4054bc5f8071a28b6fc4f4c2207dd03a5f747d0d84bChris Lattner
406ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattnervoid AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
4077152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                                                    const BinaryOperator *E) {
4087152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
4097152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  EmitFinalDestCopy(E, LV);
4107152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner}
4117152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
4127f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattnervoid AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
4137f78f218fdb3515a61b995ac64f909bfd8ee84a7Chris Lattner  // For an assignment to work, the value on the right has
414b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif  // to be compatible with the value on the left.
415b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
4167152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                                                 E->getRHS()->getType())
4177152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner         && "Invalid assignment");
4187152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  LValue LHS = CGF.EmitLValue(E->getLHS());
4197152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
4207152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  // We have to special case property setters, otherwise we must have
421fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman  // a simple lvalue (no aggregates inside vectors, bitfields).
422ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  if (LHS.isPropertyRef()) {
423ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    llvm::Value *AggLoc = DestPtr;
424ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    if (!AggLoc)
425ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
426ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
427ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
428ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner                            RValue::getAggregate(AggLoc, VolatileDest));
429ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner  } else if (LHS.isKVCRef()) {
430ce869ee05bfcb9d4750a3d0919a8260a727841c3Chris Lattner    llvm::Value *AggLoc = DestPtr;
4317152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    if (!AggLoc)
4327152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner      AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
4337152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
4347152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
4357152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner                            RValue::getAggregate(AggLoc, VolatileDest));
436fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman  } else {
437543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    bool RequiresGCollection = false;
438543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    if (CGF.getContext().getLangOptions().NeXTRuntime) {
439543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      QualType LHSTy = E->getLHS()->getType();
440543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner      if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
441543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner        RequiresGCollection = FDTTy->getDecl()->hasObjectMember();
442543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    }
443543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    // Codegen the RHS so that it stores directly into the LHS.
444543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
445051a950000e21935165db56695e35bade668193bGabor Greif                    false, false, RequiresGCollection);
446051a950000e21935165db56695e35bade668193bGabor Greif    EmitFinalDestCopy(E, LHS, true);
447543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
448543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner}
449543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
450543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattnervoid AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
451543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  if (!E->getLHS()) {
452543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
453543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner    return;
454543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  }
455543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
456543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
457543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
458543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
459543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
460543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
461543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
462543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.BeginConditionalBranch();
463543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBlock(LHSBlock);
464543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
465543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  // Handle the GNU extension for missing LHS.
466543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  assert(E->getLHS() && "Must have LHS for aggregate value");
467543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
468543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  Visit(E->getLHS());
469543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EndConditionalBranch();
470543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBranch(ContBlock);
471543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
472543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.BeginConditionalBranch();
473543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBlock(RHSBlock);
474543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
475543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  Visit(E->getRHS());
476543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EndConditionalBranch();
477543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBranch(ContBlock);
478543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
479543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner  CGF.EmitBlock(ContBlock);
4807152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner}
4817152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner
482051a950000e21935165db56695e35bade668193bGabor Greifvoid AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
4837152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  Visit(CE->getChosenSubExpr(CGF.getContext()));
4847152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner}
485543d622ef7505910c1cdc09ada0ab797c3437590Chris Lattner
4867152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattnervoid AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
4877152da38ef2c1f9f8ee407dc7740dfd43cbc41a6Chris Lattner  llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
488  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
489
490  if (!ArgPtr) {
491    CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
492    return;
493  }
494
495  EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
496}
497
498void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
499  llvm::Value *Val = DestPtr;
500
501  if (!Val) {
502    // Create a temporary variable.
503    Val = CGF.CreateMemTemp(E->getType(), "tmp");
504
505    // FIXME: volatile
506    CGF.EmitAggExpr(E->getSubExpr(), Val, false);
507  } else
508    Visit(E->getSubExpr());
509
510  // Don't make this a live temporary if we're emitting an initializer expr.
511  if (!IsInitializer)
512    CGF.PushCXXTemporary(E->getTemporary(), Val);
513}
514
515void
516AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
517  llvm::Value *Val = DestPtr;
518
519  if (!Val) {
520    // Create a temporary variable.
521    Val = CGF.CreateMemTemp(E->getType(), "tmp");
522  }
523
524  if (E->requiresZeroInitialization())
525    EmitNullInitializationToLValue(LValue::MakeAddr(Val,
526                                                    // FIXME: Qualifiers()?
527                                                 E->getType().getQualifiers()),
528                                   E->getType());
529
530  CGF.EmitCXXConstructExpr(Val, E);
531}
532
533void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
534  llvm::Value *Val = DestPtr;
535
536  CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
537}
538
539void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
540  llvm::Value *Val = DestPtr;
541
542  if (!Val) {
543    // Create a temporary variable.
544    Val = CGF.CreateMemTemp(E->getType(), "tmp");
545  }
546  LValue LV = LValue::MakeAddr(Val, Qualifiers());
547  EmitNullInitializationToLValue(LV, E->getType());
548}
549
550void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
551  llvm::Value *Val = DestPtr;
552
553  if (!Val) {
554    // Create a temporary variable.
555    Val = CGF.CreateMemTemp(E->getType(), "tmp");
556  }
557  LValue LV = LValue::MakeAddr(Val, Qualifiers());
558  EmitNullInitializationToLValue(LV, E->getType());
559}
560
561void
562AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
563  // FIXME: Ignore result?
564  // FIXME: Are initializers affected by volatile?
565  if (isa<ImplicitValueInitExpr>(E)) {
566    EmitNullInitializationToLValue(LV, T);
567  } else if (T->isReferenceType()) {
568    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
569    CGF.EmitStoreThroughLValue(RV, LV, T);
570  } else if (T->isAnyComplexType()) {
571    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
572  } else if (CGF.hasAggregateLLVMType(T)) {
573    CGF.EmitAnyExpr(E, LV.getAddress(), false);
574  } else {
575    CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
576  }
577}
578
579void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
580  if (!CGF.hasAggregateLLVMType(T)) {
581    // For non-aggregates, we can store zero
582    llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
583    CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
584  } else {
585    // Otherwise, just memset the whole thing to zero.  This is legal
586    // because in LLVM, all default initializers are guaranteed to have a
587    // bit pattern of all zeros.
588    // FIXME: That isn't true for member pointers!
589    // There's a potential optimization opportunity in combining
590    // memsets; that would be easy for arrays, but relatively
591    // difficult for structures with the current code.
592    CGF.EmitMemSetToZero(LV.getAddress(), T);
593  }
594}
595
596void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
597#if 0
598  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
599  // (Length of globals? Chunks of zeroed-out space?).
600  //
601  // If we can, prefer a copy from a global; this is a lot less code for long
602  // globals, and it's easier for the current optimizers to analyze.
603  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
604    llvm::GlobalVariable* GV =
605    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
606                             llvm::GlobalValue::InternalLinkage, C, "");
607    EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers()));
608    return;
609  }
610#endif
611  if (E->hadArrayRangeDesignator()) {
612    CGF.ErrorUnsupported(E, "GNU array range designator extension");
613  }
614
615  // Handle initialization of an array.
616  if (E->getType()->isArrayType()) {
617    const llvm::PointerType *APType =
618      cast<llvm::PointerType>(DestPtr->getType());
619    const llvm::ArrayType *AType =
620      cast<llvm::ArrayType>(APType->getElementType());
621
622    uint64_t NumInitElements = E->getNumInits();
623
624    if (E->getNumInits() > 0) {
625      QualType T1 = E->getType();
626      QualType T2 = E->getInit(0)->getType();
627      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
628        EmitAggLoadOfLValue(E->getInit(0));
629        return;
630      }
631    }
632
633    uint64_t NumArrayElements = AType->getNumElements();
634    QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
635    ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
636
637    // FIXME: were we intentionally ignoring address spaces and GC attributes?
638    Qualifiers Quals = CGF.MakeQualifiers(ElementType);
639
640    for (uint64_t i = 0; i != NumArrayElements; ++i) {
641      llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
642      if (i < NumInitElements)
643        EmitInitializationToLValue(E->getInit(i),
644                                   LValue::MakeAddr(NextVal, Quals),
645                                   ElementType);
646      else
647        EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
648                                       ElementType);
649    }
650    return;
651  }
652
653  assert(E->getType()->isRecordType() && "Only support structs/unions here!");
654
655  // Do struct initialization; this code just sets each individual member
656  // to the approprate value.  This makes bitfield support automatic;
657  // the disadvantage is that the generated code is more difficult for
658  // the optimizer, especially with bitfields.
659  unsigned NumInitElements = E->getNumInits();
660  RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
661  unsigned CurInitVal = 0;
662
663  if (E->getType()->isUnionType()) {
664    // Only initialize one field of a union. The field itself is
665    // specified by the initializer list.
666    if (!E->getInitializedFieldInUnion()) {
667      // Empty union; we have nothing to do.
668
669#ifndef NDEBUG
670      // Make sure that it's really an empty and not a failure of
671      // semantic analysis.
672      for (RecordDecl::field_iterator Field = SD->field_begin(),
673                                   FieldEnd = SD->field_end();
674           Field != FieldEnd; ++Field)
675        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
676#endif
677      return;
678    }
679
680    // FIXME: volatility
681    FieldDecl *Field = E->getInitializedFieldInUnion();
682    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
683
684    if (NumInitElements) {
685      // Store the initializer into the field
686      EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
687    } else {
688      // Default-initialize to null
689      EmitNullInitializationToLValue(FieldLoc, Field->getType());
690    }
691
692    return;
693  }
694
695  // If we're initializing the whole aggregate, just do it in place.
696  // FIXME: This is a hack around an AST bug (PR6537).
697  if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) {
698    EmitInitializationToLValue(E->getInit(0),
699                               LValue::MakeAddr(DestPtr, Qualifiers()),
700                               E->getType());
701    return;
702  }
703
704
705  // Here we iterate over the fields; this makes it simpler to both
706  // default-initialize fields and skip over unnamed fields.
707  for (RecordDecl::field_iterator Field = SD->field_begin(),
708                               FieldEnd = SD->field_end();
709       Field != FieldEnd; ++Field) {
710    // We're done once we hit the flexible array member
711    if (Field->getType()->isIncompleteArrayType())
712      break;
713
714    if (Field->isUnnamedBitfield())
715      continue;
716
717    // FIXME: volatility
718    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
719    // We never generate write-barries for initialized fields.
720    LValue::SetObjCNonGC(FieldLoc, true);
721    if (CurInitVal < NumInitElements) {
722      // Store the initializer into the field.
723      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
724                                 Field->getType());
725    } else {
726      // We're out of initalizers; default-initialize to null
727      EmitNullInitializationToLValue(FieldLoc, Field->getType());
728    }
729  }
730}
731
732//===----------------------------------------------------------------------===//
733//                        Entry Points into this File
734//===----------------------------------------------------------------------===//
735
736/// EmitAggExpr - Emit the computation of the specified expression of aggregate
737/// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
738/// the value of the aggregate expression is not needed.  If VolatileDest is
739/// true, DestPtr cannot be 0.
740//
741// FIXME: Take Qualifiers object.
742void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
743                                  bool VolatileDest, bool IgnoreResult,
744                                  bool IsInitializer,
745                                  bool RequiresGCollection) {
746  assert(E && hasAggregateLLVMType(E->getType()) &&
747         "Invalid aggregate expression to emit");
748  assert ((DestPtr != 0 || VolatileDest == false)
749          && "volatile aggregate can't be 0");
750
751  AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
752                 RequiresGCollection)
753    .Visit(const_cast<Expr*>(E));
754}
755
756LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
757  assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
758  Qualifiers Q = MakeQualifiers(E->getType());
759  llvm::Value *Temp = CreateMemTemp(E->getType());
760  EmitAggExpr(E, Temp, Q.hasVolatile());
761  return LValue::MakeAddr(Temp, Q);
762}
763
764void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
765                                        llvm::Value *SrcPtr, QualType Ty,
766                                        bool isVolatile) {
767  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
768
769  if (getContext().getLangOptions().CPlusPlus) {
770    if (const RecordType *RT = Ty->getAs<RecordType>()) {
771      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
772      assert((Record->hasTrivialCopyConstructor() ||
773              Record->hasTrivialCopyAssignment()) &&
774             "Trying to aggregate-copy a type without a trivial copy "
775             "constructor or assignment operator");
776      // Ignore empty classes in C++.
777      if (Record->isEmpty())
778        return;
779    }
780  }
781
782  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
783  // C99 6.5.16.1p3, which states "If the value being stored in an object is
784  // read from another object that overlaps in anyway the storage of the first
785  // object, then the overlap shall be exact and the two objects shall have
786  // qualified or unqualified versions of a compatible type."
787  //
788  // memcpy is not defined if the source and destination pointers are exactly
789  // equal, but other compilers do this optimization, and almost every memcpy
790  // implementation handles this case safely.  If there is a libc that does not
791  // safely handle this, we can add a target hook.
792  const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
793  if (DestPtr->getType() != BP)
794    DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
795  if (SrcPtr->getType() != BP)
796    SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
797
798  // Get size and alignment info for this aggregate.
799  std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
800
801  // FIXME: Handle variable sized types.
802  const llvm::Type *IntPtr =
803          llvm::IntegerType::get(VMContext, LLVMPointerWidth);
804
805  // FIXME: If we have a volatile struct, the optimizer can remove what might
806  // appear to be `extra' memory ops:
807  //
808  // volatile struct { int i; } a, b;
809  //
810  // int main() {
811  //   a = b;
812  //   a = b;
813  // }
814  //
815  // we need to use a different call here.  We use isVolatile to indicate when
816  // either the source or the destination is volatile.
817  const llvm::Type *I1Ty = llvm::Type::getInt1Ty(VMContext);
818  const llvm::Type *I8Ty = llvm::Type::getInt8Ty(VMContext);
819  const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext);
820
821  const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
822  const llvm::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace());
823  if (DestPtr->getType() != DBP)
824    DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
825
826  const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
827  const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace());
828  if (SrcPtr->getType() != SBP)
829    SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
830
831  Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
832                                      IntPtr),
833                      DestPtr, SrcPtr,
834                      // TypeInfo.first describes size in bits.
835                      llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
836                      llvm::ConstantInt::get(I32Ty,  TypeInfo.second/8),
837                      llvm::ConstantInt::get(I1Ty,  isVolatile));
838}
839