CGCXX.cpp revision f121677b6bbbf4e4a51ee7a1120b77adf187bad4
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(),
44a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson                             VMContext.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.
53a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  llvm::Value *nullValue = VMContext.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  assert(!ClassDecl->isPolymorphic() &&
168c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "FIXME: We don't support polymorphic classes yet!");
169c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
170c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      e = ClassDecl->bases_end(); i != e; ++i) {
171c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
172c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
173c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
174c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
175c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (Base == BaseClassDecl) {
176c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(BaseClassDecl);
177c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
178c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
179c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
180c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  // BaseClassDecl not an immediate base of ClassDecl.
181c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
182c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian       e = ClassDecl->bases_end(); i != e; ++i) {
183c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
184c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
185c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
186c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
187c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
188c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(Base);
189c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
190c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
191c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
192c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  return false;
193c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian}
194c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
1959e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
1966d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *ClassDecl,
1976d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *BaseClassDecl) {
1989e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  if (ClassDecl == BaseClassDecl)
1999e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    return BaseValue;
2009e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
201c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
202c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
203c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
204c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  assert(NestedBasePaths.size() > 0 &&
205c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "AddressCXXOfBaseClass - inheritence path failed");
206c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  NestedBasePaths.push_back(ClassDecl);
207c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  uint64_t Offset = 0;
208c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
2099e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // Accessing a member of the base class. Must add delata to
2109e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // the load of 'this'.
211c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
212c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
213c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
214c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const ASTRecordLayout &Layout =
215c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      getContext().getASTRecordLayout(DerivedClass);
216c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
217c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
2185a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian  llvm::Value *OffsetVal =
2195a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian    llvm::ConstantInt::get(
2205a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian                  CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
2219e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
2229e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
2239e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  QualType BTy =
2249e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    getContext().getCanonicalType(
2256d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
2269e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  const llvm::Type *BasePtr = ConvertType(BTy);
22796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
2289e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
2299e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  return BaseValue;
2309e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian}
2319e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
232b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
233b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
234b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
235b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
236b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
237b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
238b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
239b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
240b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
241b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
242b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
2437267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
2447267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
2457267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
2467267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
2477267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
2487267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
2497267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
2507267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
251b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
25231ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
25331ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
254b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
255b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
256b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
2576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
258b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
259b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
260b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
261b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
262b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
263b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
264b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
265b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
266a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
267ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
268ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
26903e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
270ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
271ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
272ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
273ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
274ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
275ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
276ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
277ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
278ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
279ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
280ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
2814a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
282ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
283ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
284ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
285ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
286ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
287ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
288ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
289ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
290ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
291ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
292ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
293ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
294ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
295ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
296ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
297ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
298ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
299ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
300ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
301ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
302ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
303ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
304ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
305ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
306ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
307ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
308ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
309ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
310ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
311ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
312ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
313ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
314ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
315ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
316ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
317ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
318ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
319ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
320ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
321ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
322ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
323ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
324ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
325d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
326d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
327d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
328d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
329d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
330d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
331ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
332f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
333f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
334f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
335f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
336f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
337f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
338d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
339f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
340f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
341f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
342f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
343f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
344f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
345a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson                           VMContext.getNullValue(NewPtr->getType()),
346f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
347f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
348f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
349f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
350d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
351d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
352f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
353d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
3546d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
355215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
3566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
3576d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
3586d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
3596d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
3606d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
3613923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
3626d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
3633923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
3643923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
365627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
366627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
3676d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
368d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
369d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
370d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
3716d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
372d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
373d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
374d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
375ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
376d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
377f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
378f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
379f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
380f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
381f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
382f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
383f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
384f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
385f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
386a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    PHI->addIncoming(VMContext.getNullValue(NewPtr->getType()), NewNull);
387f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
388f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
389f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
390f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
391d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
392a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
393a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
39427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
39527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
39659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
39759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
39859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
39959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
40017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
40117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
40259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
40359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
40459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
40559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
40659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
40759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
40859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
40959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
41095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
41127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
41259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
41359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
41459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
41595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
4162a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
4172a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
41895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
419363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
42027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
42127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
42227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
42427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
42627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
42727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
42827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
42927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
43027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
431363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
432363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
433363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
434363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
435363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
436363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
437363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
438b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
439b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
440363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
44127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
44227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
44327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
44427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
44527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
44627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
44727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
44827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
44927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
45027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
45127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
45227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
45327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
45427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
45527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
45627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
45727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
45827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
45927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
46027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
46127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
46327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
46427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
46527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
46727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
46827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
46927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
47027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
47127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
47227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
47327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
47427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
47527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
47627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
47727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
47827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
479b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
480b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
48127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
48227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
48327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
48427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
48527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
48627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
48727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
48827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
48927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
49027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
49127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
492e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
493f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
494f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  const llvm::FunctionType *FTy;
495f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  FTy = llvm::FunctionType::get(llvm::Type::VoidTy,
496f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump                                std::vector<const llvm::Type*>(), false);
497f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
498f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
499f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
500f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
501f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // FIXME: What is the design on getTagDeclType when it requires casting
502f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // away const?  mutable?
503f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD));
504f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
505f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  const char *Name = OutName.c_str();
506f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *vtable = CGM.CreateRuntimeFunction(FTy, Name);
507f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallVector<CXXMethodDecl *,32> methods;
508f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  typedef CXXRecordDecl::method_iterator meth_iter;
509f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
510f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump       ++mi) {
511f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (mi->isVirtual())
512f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      methods.push_back(*mi);
513f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
514f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
515f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Type *Ptr8Ty;
516f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
517f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
518f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // FIXME: finish layout for virtual bases and fix for 32-bit
519f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  int64_t offset = 16;
520f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
521f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump                             llvm::ConstantInt::get(llvm::Type::Int64Ty,
522f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump                                                    offset));
523f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
524f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
525f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
526e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
527e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
528e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
529742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
5307116da1efe23f90eb22524ac9aa036153b74f482Mike Stump  assert(ClassDecl->getNumVBases() == 0
5317116da1efe23f90eb22524ac9aa036153b74f482Mike Stump         && "FIXME: virtual base initialization unsupported");
532f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
533f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
5346d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
535742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
536e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
537e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
538e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
539e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
540f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
5416d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
5426d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
5436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
5446d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
5456d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
546742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
547742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
548742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
549742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
550b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
551e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
552e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
553e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
554e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
555e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian             && "FIXME. Field arrays initialization unsupported");
55650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
557f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
558e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
5596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
56050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
56150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
56250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
56350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          EmitCXXConstructorCall(Member->getConstructor(),
56450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Ctor_Complete, LHS.getAddress(),
56550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_begin(),
56650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_end());
56750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian        continue;
56850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
569e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
570e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
57150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
572e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
573e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      if (LHS.isBitfield())
574e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0);
575e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      else
576e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
577e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
578e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
579f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
580f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
581f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  if (ClassDecl->isPolymorphic() || ClassDecl->getNumVBases()) {
582f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
583f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
584f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
585f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
586f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
587f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
588f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
589f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
590f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
591f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
592e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
593426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
594426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
595426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
596426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
597426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
598426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
599426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
600426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
601426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
602426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
603426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
604426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
605426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
606426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
607426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
608426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
609426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
610426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian             && "FIXME. Field arrays destruction unsupported");
611426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
612426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
613426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
614426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
615426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
616426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
617426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
618426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, LHS.getAddress());
619b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
620426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
621426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
622426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
623426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
624426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
625426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
626426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
627426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
628426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
629426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
630426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
631426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
632