CGCXX.cpp revision cb1b5d32fd227cd791fbd0614f75b32f291a5cca
1e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
3e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//                     The LLVM Compiler Infrastructure
4e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
5e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This file is distributed under the University of Illinois Open Source
6e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// License. See LICENSE.TXT for details.
7e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
8e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
9e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
10e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This contains code dealing with C++ code generation.
11e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
12e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
13e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
14e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// We might split this into multiple files if it gets too unwieldy
15e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
16e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenFunction.h"
17e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenModule.h"
18283a062a633d6e868aa2be319da812341fe73728Anders Carlsson#include "Mangle.h"
19e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/ASTContext.h"
20742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian#include "clang/AST/RecordLayout.h"
21e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h"
22774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson#include "clang/AST/DeclCXX.h"
2386e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h"
24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
27e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
280096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbarvoid
290096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel DunbarCodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
300096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                                                   llvm::GlobalVariable *GV) {
310096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar  // FIXME: This should use __cxa_guard_{acquire,release}?
320096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar
33e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(!getContext().getLangOptions().ThreadsafeStatics &&
34e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "thread safe statics are currently not supported!");
35e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
36283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::SmallString<256> GuardVName;
37283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::raw_svector_ostream GuardVOut(GuardVName);
38283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  mangleGuardVariable(&D, getContext(), GuardVOut);
39283a062a633d6e868aa2be319da812341fe73728Anders Carlsson
40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GuardV =
421c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), llvm::Type::Int64Ty, false,
430096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                             GV->getLinkage(),
44c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             GuardVName.c_str());
46e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
47e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
4896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
49e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
50e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
51e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
52e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Compare it against 0.
53c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
54e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
55e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
5655e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *InitBlock = createBasicBlock("init");
579615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
58e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
59e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // If the guard variable is 0, jump to the initializer code.
60e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
61e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
62e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(InitBlock);
63e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
64e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const Expr *Init = D.getInit();
65e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  if (!hasAggregateLLVMType(Init->getType())) {
66e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    llvm::Value *V = EmitScalarExpr(Init);
67e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
68e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else if (Init->getType()->isAnyComplexType()) {
69e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
70e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else {
71e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
72e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  }
73e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
744a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
75e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                      Builder.CreateBitCast(GuardV, PtrTy));
76e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
77e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(EndBlock);
78e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
79e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
80b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
81b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          llvm::Value *Callee,
82b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          llvm::Value *This,
83b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
84b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
85774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  assert(MD->isInstance() &&
86774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson         "Trying to emit a member call expr on a static method!");
87b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
88b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
89b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
90b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  CallArgList Args;
91b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
92b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // Push the this ptr.
93b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  Args.push_back(std::make_pair(RValue::get(This),
94b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                MD->getThisType(getContext())));
95b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
96b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // And the rest of the call args
97b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
98774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
99b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
100b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
101b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                  Callee, Args, MD);
102b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson}
103b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
104b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
105b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
106b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
107b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
108e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1097116da1efe23f90eb22524ac9aa036153b74f482Mike Stump
110f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  if (MD->isVirtual()) {
1117116da1efe23f90eb22524ac9aa036153b74f482Mike Stump    ErrorUnsupported(CE, "virtual dispatch");
1127116da1efe23f90eb22524ac9aa036153b74f482Mike Stump  }
1137116da1efe23f90eb22524ac9aa036153b74f482Mike Stump
114774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const llvm::Type *Ty =
115e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
116e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                                   FPT->isVariadic());
117b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
118774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
119b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *This;
120774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
121774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  if (ME->isArrow())
122b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = EmitScalarExpr(ME->getBase());
123774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  else {
124774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    LValue BaseLV = EmitLValue(ME->getBase());
125b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = BaseLV.getAddress();
126774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  }
127774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
128b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
129b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                           CE->arg_begin(), CE->arg_end());
130774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson}
1315f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
1320f294632f36459174199b77699e339715244b5abAnders CarlssonRValue
1330f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
1340f294632f36459174199b77699e339715244b5abAnders Carlsson                                               const CXXMethodDecl *MD) {
1350f294632f36459174199b77699e339715244b5abAnders Carlsson  assert(MD->isInstance() &&
1360f294632f36459174199b77699e339715244b5abAnders Carlsson         "Trying to emit a member call expr on a static method!");
1370f294632f36459174199b77699e339715244b5abAnders Carlsson
1380f294632f36459174199b77699e339715244b5abAnders Carlsson
1390f294632f36459174199b77699e339715244b5abAnders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1400f294632f36459174199b77699e339715244b5abAnders Carlsson  const llvm::Type *Ty =
1410f294632f36459174199b77699e339715244b5abAnders Carlsson  CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1420f294632f36459174199b77699e339715244b5abAnders Carlsson                                 FPT->isVariadic());
1430f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
1440f294632f36459174199b77699e339715244b5abAnders Carlsson
1450f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
1460f294632f36459174199b77699e339715244b5abAnders Carlsson
1470f294632f36459174199b77699e339715244b5abAnders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
1480f294632f36459174199b77699e339715244b5abAnders Carlsson                           E->arg_begin() + 1, E->arg_end());
1490f294632f36459174199b77699e339715244b5abAnders Carlsson}
1500f294632f36459174199b77699e339715244b5abAnders Carlsson
1515f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
1525f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
1535f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
1545f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
1555f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
1565f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
1575f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
158f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ans: See how CodeGenFunction::LoadObjCSelf() uses
159f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // CodeGenFunction::BlockForwardSelf() for how to do this.
1605f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
1615f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
16295d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
163c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool
164c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths,
165c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *ClassDecl,
166c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *BaseClassDecl) {
167c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
168c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      e = ClassDecl->bases_end(); i != e; ++i) {
169c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
170c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
171c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
172c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
173c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (Base == BaseClassDecl) {
174c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(BaseClassDecl);
175c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
176c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
177c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
178c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  // BaseClassDecl not an immediate base of ClassDecl.
179c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
180c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian       e = ClassDecl->bases_end(); i != e; ++i) {
181c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
182c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
183c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
184c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
185c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
186c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(Base);
187c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
188c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
189c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
190c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  return false;
191c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian}
192c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
1939e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
1946d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *ClassDecl,
1956d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *BaseClassDecl) {
1969e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  if (ClassDecl == BaseClassDecl)
1979e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    return BaseValue;
1989e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
199c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
200c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
201c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
202c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  assert(NestedBasePaths.size() > 0 &&
203c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "AddressCXXOfBaseClass - inheritence path failed");
204c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  NestedBasePaths.push_back(ClassDecl);
205c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  uint64_t Offset = 0;
206c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
2079e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // Accessing a member of the base class. Must add delata to
2089e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // the load of 'this'.
209c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
210c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
211c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
212c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const ASTRecordLayout &Layout =
213c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      getContext().getASTRecordLayout(DerivedClass);
214c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
215c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
2165a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian  llvm::Value *OffsetVal =
2175a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian    llvm::ConstantInt::get(
2185a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian                  CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
2199e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
2209e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
2219e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  QualType BTy =
2229e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    getContext().getCanonicalType(
2236d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
2249e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  const llvm::Type *BasePtr = ConvertType(BTy);
22596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
2269e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
2279e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  return BaseValue;
2289e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian}
2299e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
230b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
231b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
232b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
233b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
234b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
235b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
236b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
237b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
238b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
239b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
240b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
2417267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
2427267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
2437267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
2447267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
2457267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
2467267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
2477267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
2487267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
249b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
25031ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
25131ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
252b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
253b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
254b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
2556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
256b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
257b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
258b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
259b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
260b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
261b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
262b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
263b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
264a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
265ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
266ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
26703e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
268ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
269ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
270ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
271ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
272ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
273ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
274ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
275ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
276ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
277ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
278ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
2794a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
280ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
281ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
282ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
283ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
284ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
285ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
286ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
287ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
288ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
289ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
290ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
291ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
292ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
293ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
294ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
295ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
296ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
297ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
298ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
299ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
300ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
301ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
302ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
303ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
304ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
305ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
306ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
307ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
308ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
309ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
310ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
311ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
312ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
313ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
314ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
315ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
316ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
317ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
318ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
319ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
320ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
321ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
322ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
323d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
324d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
325d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
326d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
327d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
328d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
329ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
330f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
331f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
332f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
333f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
334f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
335f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
336d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
337f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
338f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
339f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
340f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
341f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
342f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
343c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
344f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
345f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
346f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
347f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
348d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
349d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
350f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
351d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
3526d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
353215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
3546d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
3556d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
3566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
3576d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
3586d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
3593923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
3606d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
3613923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
3623923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
363627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
364627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
3656d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
366d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
367d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
368d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
3696d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
370d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
371d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
372d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
373ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
374d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
375f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
376f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
377f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
378f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
379f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
380f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
381f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
382f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
383f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
384c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
385f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
386f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
387f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
388f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
389d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
390a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
391a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
39227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
39327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
39459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
39559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
39659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
39759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
39817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
39917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
40059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
40159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
40259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
40359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
40459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
40559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
40659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
40759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
40895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
40927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
41059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
41159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
41259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
41395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
4142a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
4152a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
41695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
417363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
41827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
41927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
42027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
42227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
42427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
42627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
42727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
42827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
429363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
430363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
431363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
432363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
433363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
434363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
435363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
436b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
437b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
438363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
43927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
44027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
44127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
44227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
44327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
44427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
44527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
44627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
44727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
44827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
44927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
45027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
45127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
45227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
45327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
45427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
45527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
45627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
45727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
45827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
45927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
46127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
46227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
46327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
46527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
46727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
46827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
46927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
47027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
47127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
47227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
47327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
47427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
47527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
47627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
477b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
478b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
47927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
48027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
48127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
48227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
48327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
48427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
48527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
48627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
48727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
48827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
48927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
490e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
491738f8c278da5950d0d4607de2debe0bdfad64185Mike Stumpllvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) {
492738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
493738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
494cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
495738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
496738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
497cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
498738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
499738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
500738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
501738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
502738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: What is the design on getTagDeclType when it requires casting
503738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // away const?  mutable?
504738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD));
505738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
506738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  const char *Name = OutName.c_str();
507738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
508738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
509738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
510738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  assert (0 && "FIXME: implement rtti descriptor");
511738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
512738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
513738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  assert (0 && "FIXME: implement rtti ts");
514738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
515738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
516738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
517738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
518738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
519738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
520cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C,
521738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump                                  Name);
522cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
523cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
524738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
525738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
526f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
527f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
528f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
529f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
530f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // FIXME: What is the design on getTagDeclType when it requires casting
531f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // away const?  mutable?
532f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD));
533f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
534f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  const char *Name = OutName.c_str();
53582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
53682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
53782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
538f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  typedef CXXRecordDecl::method_iterator meth_iter;
53982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *m;
54082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Type *Ptr8Ty;
54182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
54282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  m = llvm::Constant::getNullValue(Ptr8Ty);
54382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  int64_t offset = 0;
54482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  methods.push_back(m); offset += LLVMPointerWidth;
545738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  methods.push_back(GenerateRtti(RD)); offset += LLVMPointerWidth;
546f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
547f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump       ++mi) {
54882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump    if (mi->isVirtual()) {
54982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump      m = CGM.GetAddrOfFunction(GlobalDecl(*mi));
55082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump      m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
55182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump      methods.push_back(m);
55282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump    }
553f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
55482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
55582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
55682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
55782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
55882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump                                                 linktype, C, Name);
559f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
56082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  // FIXME: finish layout for virtual bases
561f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
562f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump                             llvm::ConstantInt::get(llvm::Type::Int64Ty,
56382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump                                                    offset/8));
564f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
565f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
566f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
567e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
568e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
569e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
570742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
5717116da1efe23f90eb22524ac9aa036153b74f482Mike Stump  assert(ClassDecl->getNumVBases() == 0
5727116da1efe23f90eb22524ac9aa036153b74f482Mike Stump         && "FIXME: virtual base initialization unsupported");
573f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
574f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
5756d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
576742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
577e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
578e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
579e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
580e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
581f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
5826d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
5836d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
5846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
5856d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
5866d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
587742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
588742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
589742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
590742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
591b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
592e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
593e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
594e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
595e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
596e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian             && "FIXME. Field arrays initialization unsupported");
59750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
598f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
599e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
6006217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
60150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
60250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
60350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
60450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          EmitCXXConstructorCall(Member->getConstructor(),
60550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Ctor_Complete, LHS.getAddress(),
60650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_begin(),
60750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_end());
60850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian        continue;
60950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
610e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
611e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
61250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
613e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
614e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      if (LHS.isBitfield())
615e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0);
616e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      else
617e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
618e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
619e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
620f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
621f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
622f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  if (ClassDecl->isPolymorphic() || ClassDecl->getNumVBases()) {
623f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
624f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
625f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
626f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
627f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
628f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
629f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
630f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
631f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
632f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
633e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
634426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
635426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
636426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
637426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
638426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
639426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
640426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
641426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
642426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
643426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
644426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
645426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
646426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
647426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
648426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
649426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
650426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
651426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian             && "FIXME. Field arrays destruction unsupported");
652426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
653426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
654426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
655426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
656426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
657426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
658426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
659426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, LHS.getAddress());
660b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
661426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
662426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
663426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
664426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
665426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
666426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
667426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
668426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
669426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
670426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
671426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
672426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
673