CGCXX.cpp revision 193326
1191783Srmacklem//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2191783Srmacklem//
3191783Srmacklem//                     The LLVM Compiler Infrastructure
4191783Srmacklem//
5191783Srmacklem// This file is distributed under the University of Illinois Open Source
6191783Srmacklem// License. See LICENSE.TXT for details.
7191783Srmacklem//
8191783Srmacklem//===----------------------------------------------------------------------===//
9191783Srmacklem//
10191783Srmacklem// This contains code dealing with C++ code generation.
11191783Srmacklem//
12191783Srmacklem//===----------------------------------------------------------------------===//
13191783Srmacklem
14191783Srmacklem// We might split this into multiple files if it gets too unwieldy
15191783Srmacklem
16191783Srmacklem#include "CodeGenFunction.h"
17191783Srmacklem#include "CodeGenModule.h"
18191783Srmacklem#include "Mangle.h"
19191783Srmacklem#include "clang/AST/ASTContext.h"
20191783Srmacklem#include "clang/AST/Decl.h"
21191783Srmacklem#include "clang/AST/DeclCXX.h"
22191783Srmacklem#include "clang/AST/DeclObjC.h"
23191783Srmacklem#include "llvm/ADT/StringExtras.h"
24191783Srmacklemusing namespace clang;
25191783Srmacklemusing namespace CodeGen;
26191783Srmacklem
27191783Srmacklemvoid
28191783SrmacklemCodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
29191783Srmacklem                                                   llvm::GlobalVariable *GV) {
30191783Srmacklem  // FIXME: This should use __cxa_guard_{acquire,release}?
31191783Srmacklem
32191783Srmacklem  assert(!getContext().getLangOptions().ThreadsafeStatics &&
33191783Srmacklem         "thread safe statics are currently not supported!");
34191783Srmacklem
35191783Srmacklem  llvm::SmallString<256> GuardVName;
36191783Srmacklem  llvm::raw_svector_ostream GuardVOut(GuardVName);
37191783Srmacklem  mangleGuardVariable(&D, getContext(), GuardVOut);
38191783Srmacklem
39191783Srmacklem  // Create the guard variable.
40191783Srmacklem  llvm::GlobalValue *GuardV =
41191783Srmacklem    new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
42191783Srmacklem                             GV->getLinkage(),
43191783Srmacklem                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
44191783Srmacklem                             GuardVName.c_str(),
45191783Srmacklem                             &CGM.getModule());
46191783Srmacklem
47191783Srmacklem  // Load the first byte of the guard variable.
48191783Srmacklem  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
49191783Srmacklem  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
50191783Srmacklem                                      "tmp");
51191783Srmacklem
52191783Srmacklem  // Compare it against 0.
53191783Srmacklem  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
54191783Srmacklem  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
55191783Srmacklem
56191783Srmacklem  llvm::BasicBlock *InitBlock = createBasicBlock("init");
57191783Srmacklem  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
58191783Srmacklem
59191783Srmacklem  // If the guard variable is 0, jump to the initializer code.
60191783Srmacklem  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
61191783Srmacklem
62191783Srmacklem  EmitBlock(InitBlock);
63191783Srmacklem
64191783Srmacklem  const Expr *Init = D.getInit();
65191783Srmacklem  if (!hasAggregateLLVMType(Init->getType())) {
66191783Srmacklem    llvm::Value *V = EmitScalarExpr(Init);
67191783Srmacklem    Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
68191783Srmacklem  } else if (Init->getType()->isAnyComplexType()) {
69191783Srmacklem    EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
70191783Srmacklem  } else {
71191783Srmacklem    EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
72244042Srmacklem  }
73191783Srmacklem
74191783Srmacklem  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
75191783Srmacklem                      Builder.CreateBitCast(GuardV, PtrTy));
76244042Srmacklem
77244042Srmacklem  EmitBlock(EndBlock);
78191783Srmacklem}
79191783Srmacklem
80191783SrmacklemRValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
81191783Srmacklem                                          llvm::Value *Callee,
82191783Srmacklem                                          llvm::Value *This,
83191783Srmacklem                                          CallExpr::const_arg_iterator ArgBeg,
84191783Srmacklem                                          CallExpr::const_arg_iterator ArgEnd) {
85191783Srmacklem  assert(MD->isInstance() &&
86191783Srmacklem         "Trying to emit a member call expr on a static method!");
87191783Srmacklem
88191783Srmacklem  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
89191783Srmacklem
90192115Srmacklem  CallArgList Args;
91191783Srmacklem
92191783Srmacklem  // Push the this ptr.
93191783Srmacklem  Args.push_back(std::make_pair(RValue::get(This),
94191783Srmacklem                                MD->getThisType(getContext())));
95191783Srmacklem
96191783Srmacklem  // And the rest of the call args
97191783Srmacklem  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
98191783Srmacklem
99191783Srmacklem  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
100191783Srmacklem  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
101191783Srmacklem                  Callee, Args, MD);
102191783Srmacklem}
103191783Srmacklem
104191783SrmacklemRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
105191783Srmacklem  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
106191783Srmacklem  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
107191783Srmacklem
108191783Srmacklem  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
109191783Srmacklem  const llvm::Type *Ty =
110191783Srmacklem    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
111191783Srmacklem                                   FPT->isVariadic());
112191783Srmacklem  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
113191783Srmacklem
114191783Srmacklem  llvm::Value *This;
115191783Srmacklem
116191783Srmacklem  if (ME->isArrow())
117191783Srmacklem    This = EmitScalarExpr(ME->getBase());
118191783Srmacklem  else {
119191783Srmacklem    LValue BaseLV = EmitLValue(ME->getBase());
120191783Srmacklem    This = BaseLV.getAddress();
121191783Srmacklem  }
122191783Srmacklem
123191783Srmacklem  return EmitCXXMemberCall(MD, Callee, This,
124191783Srmacklem                           CE->arg_begin(), CE->arg_end());
125191783Srmacklem}
126191783Srmacklem
127191783SrmacklemRValue
128191783SrmacklemCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
129220530Srmacklem                                               const CXXMethodDecl *MD) {
130191783Srmacklem  assert(MD->isInstance() &&
131192115Srmacklem         "Trying to emit a member call expr on a static method!");
132191783Srmacklem
133191783Srmacklem
134191783Srmacklem  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
135191783Srmacklem  const llvm::Type *Ty =
136191783Srmacklem  CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
137191783Srmacklem                                 FPT->isVariadic());
138191783Srmacklem  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
139191783Srmacklem
140191783Srmacklem  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
141191783Srmacklem
142191783Srmacklem  return EmitCXXMemberCall(MD, Callee, This,
143191783Srmacklem                           E->arg_begin() + 1, E->arg_end());
144191783Srmacklem}
145191783Srmacklem
146191783Srmacklemllvm::Value *CodeGenFunction::LoadCXXThis() {
147191783Srmacklem  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
148191783Srmacklem         "Must be in a C++ member function decl to load 'this'");
149191783Srmacklem  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
150191783Srmacklem         "Must be in a C++ member function decl to load 'this'");
151191783Srmacklem
152191783Srmacklem  // FIXME: What if we're inside a block?
153191783Srmacklem  // ans: See how CodeGenFunction::LoadObjCSelf() uses
154191783Srmacklem  // CodeGenFunction::BlockForwardSelf() for how to do this.
155191783Srmacklem  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
156191783Srmacklem}
157191783Srmacklem
158191783Srmacklemvoid
159191783SrmacklemCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
160191783Srmacklem                                        CXXCtorType Type,
161191783Srmacklem                                        llvm::Value *This,
162191783Srmacklem                                        CallExpr::const_arg_iterator ArgBeg,
163191783Srmacklem                                        CallExpr::const_arg_iterator ArgEnd) {
164191783Srmacklem  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
165191783Srmacklem
166191783Srmacklem  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
167191783Srmacklem}
168191783Srmacklem
169191783Srmacklemvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
170191783Srmacklem                                            CXXDtorType Type,
171191783Srmacklem                                            llvm::Value *This) {
172191783Srmacklem  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
173191783Srmacklem
174191783Srmacklem  EmitCXXMemberCall(D, Callee, This, 0, 0);
175191783Srmacklem}
176191783Srmacklem
177191783Srmacklemvoid
178191783SrmacklemCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
179191783Srmacklem                                      const CXXConstructExpr *E) {
180191783Srmacklem  assert(Dest && "Must have a destination!");
181191783Srmacklem
182191783Srmacklem  const CXXRecordDecl *RD =
183191783Srmacklem  cast<CXXRecordDecl>(E->getType()->getAsRecordType()->getDecl());
184191783Srmacklem  if (RD->hasTrivialConstructor())
185191783Srmacklem    return;
186191783Srmacklem
187191783Srmacklem  // Call the constructor.
188191783Srmacklem  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
189191783Srmacklem                         E->arg_begin(), E->arg_end());
190191783Srmacklem}
191191783Srmacklem
192191783Srmacklemvoid CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
193191783Srmacklem                                       llvm::Value *Ptr) {
194191783Srmacklem  LiveTemporaries.push_back(Temporary);
195191783Srmacklem
196191783Srmacklem  // Make a cleanup scope and emit the destructor.
197191783Srmacklem  {
198191783Srmacklem    CleanupScope Scope(*this);
199191783Srmacklem
200191783Srmacklem    EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr);
201191783Srmacklem  }
202191783Srmacklem}
203191783Srmacklem
204191783SrmacklemRValue
205191783SrmacklemCodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
206191783Srmacklem                                            llvm::Value *AggLoc,
207191783Srmacklem                                            bool isAggLocVolatile) {
208191783Srmacklem  // Keep track of the current cleanup stack depth.
209191783Srmacklem  size_t CleanupStackDepth = CleanupEntries.size();
210191783Srmacklem
211191783Srmacklem  unsigned OldNumLiveTemporaries = LiveTemporaries.size();
212191783Srmacklem
213191783Srmacklem  RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
214191783Srmacklem
215192115Srmacklem  // Go through the temporaries backwards.
216191783Srmacklem  for (unsigned i = E->getNumTemporaries(); i != 0; --i) {
217191783Srmacklem    assert(LiveTemporaries.back() == E->getTemporary(i - 1));
218191783Srmacklem    LiveTemporaries.pop_back();
219192115Srmacklem  }
220191783Srmacklem
221191783Srmacklem  assert(OldNumLiveTemporaries == LiveTemporaries.size() &&
222191783Srmacklem         "Live temporary stack mismatch!");
223191783Srmacklem
224191783Srmacklem  EmitCleanupBlocks(CleanupStackDepth);
225191783Srmacklem
226191783Srmacklem  return RV;
227191783Srmacklem}
228191783Srmacklem
229191783Srmacklemllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
230192115Srmacklem  if (E->isArray()) {
231191783Srmacklem    ErrorUnsupported(E, "new[] expression");
232191783Srmacklem    return llvm::UndefValue::get(ConvertType(E->getType()));
233191783Srmacklem  }
234191783Srmacklem
235191783Srmacklem  QualType AllocType = E->getAllocatedType();
236191783Srmacklem  FunctionDecl *NewFD = E->getOperatorNew();
237191783Srmacklem  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
238249592Sken
239191783Srmacklem  CallArgList NewArgs;
240191783Srmacklem
241191783Srmacklem  // The allocation size is the first argument.
242191783Srmacklem  QualType SizeTy = getContext().getSizeType();
243191783Srmacklem  llvm::Value *AllocSize =
244191783Srmacklem    llvm::ConstantInt::get(ConvertType(SizeTy),
245191783Srmacklem                           getContext().getTypeSize(AllocType) / 8);
246191783Srmacklem
247191783Srmacklem  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
248191783Srmacklem
249191783Srmacklem  // Emit the rest of the arguments.
250191783Srmacklem  // FIXME: Ideally, this should just use EmitCallArgs.
251191783Srmacklem  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
252191783Srmacklem
253222389Srmacklem  // First, use the types from the function type.
254191783Srmacklem  // We start at 1 here because the first argument (the allocation size)
255191783Srmacklem  // has already been emitted.
256222389Srmacklem  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
257211951Srmacklem    QualType ArgType = NewFTy->getArgType(i);
258205941Srmacklem
259191783Srmacklem    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
260191783Srmacklem           getTypePtr() ==
261192115Srmacklem           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
262192115Srmacklem           "type mismatch in call argument!");
263244042Srmacklem
264244042Srmacklem    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
265244042Srmacklem                                     ArgType));
266244042Srmacklem
267244042Srmacklem  }
268259238Srmacklem
269259238Srmacklem  // Either we've emitted all the call args, or we have a call to a
270244042Srmacklem  // variadic function.
271191783Srmacklem  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
272192115Srmacklem         "Extra arguments in non-variadic function!");
273191783Srmacklem
274191783Srmacklem  // If we still have any arguments, emit them using the type of the argument.
275244042Srmacklem  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
276191783Srmacklem       NewArg != NewArgEnd; ++NewArg) {
277191783Srmacklem    QualType ArgType = NewArg->getType();
278191783Srmacklem    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
279191783Srmacklem                                     ArgType));
280191783Srmacklem  }
281191783Srmacklem
282191783Srmacklem  // Emit the call to new.
283191783Srmacklem  RValue RV =
284191783Srmacklem    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
285191783Srmacklem             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
286191783Srmacklem             NewArgs, NewFD);
287191783Srmacklem
288191783Srmacklem  // If an allocation function is declared with an empty exception specification
289191783Srmacklem  // it returns null to indicate failure to allocate storage. [expr.new]p13.
290191783Srmacklem  // (We don't need to check for null when there's no new initializer and
291191783Srmacklem  // we're allocating a POD type).
292192115Srmacklem  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
293216700Srmacklem    !(AllocType->isPODType() && !E->hasInitializer());
294191783Srmacklem
295191783Srmacklem  llvm::BasicBlock *NewNull = 0;
296191783Srmacklem  llvm::BasicBlock *NewNotNull = 0;
297191783Srmacklem  llvm::BasicBlock *NewEnd = 0;
298191783Srmacklem
299191783Srmacklem  llvm::Value *NewPtr = RV.getScalarVal();
300191783Srmacklem
301220645Srmacklem  if (NullCheckResult) {
302191783Srmacklem    NewNull = createBasicBlock("new.null");
303220648Srmacklem    NewNotNull = createBasicBlock("new.notnull");
304191783Srmacklem    NewEnd = createBasicBlock("new.end");
305191783Srmacklem
306191783Srmacklem    llvm::Value *IsNull =
307191783Srmacklem      Builder.CreateICmpEQ(NewPtr,
308191783Srmacklem                           llvm::Constant::getNullValue(NewPtr->getType()),
309240720Srmacklem                           "isnull");
310240720Srmacklem
311191783Srmacklem    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
312240720Srmacklem    EmitBlock(NewNotNull);
313240720Srmacklem  }
314191783Srmacklem
315191783Srmacklem  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
316191783Srmacklem
317191783Srmacklem  if (AllocType->isPODType()) {
318191783Srmacklem    if (E->getNumConstructorArgs() > 0) {
319191783Srmacklem      assert(E->getNumConstructorArgs() == 1 &&
320191783Srmacklem             "Can only have one argument to initializer of POD type.");
321191783Srmacklem
322191783Srmacklem      const Expr *Init = E->getConstructorArg(0);
323191783Srmacklem
324192121Srmacklem      if (!hasAggregateLLVMType(AllocType))
325191783Srmacklem        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
326192115Srmacklem      else if (AllocType->isAnyComplexType())
327243782Srmacklem        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
328191783Srmacklem      else
329192115Srmacklem        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
330191783Srmacklem    }
331191783Srmacklem  } else {
332191783Srmacklem    // Call the constructor.
333191783Srmacklem    CXXConstructorDecl *Ctor = E->getConstructor();
334191783Srmacklem
335191783Srmacklem    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
336191783Srmacklem                           E->constructor_arg_begin(),
337191783Srmacklem                           E->constructor_arg_end());
338191783Srmacklem  }
339191783Srmacklem
340207170Srmacklem  if (NullCheckResult) {
341191783Srmacklem    Builder.CreateBr(NewEnd);
342224078Szack    EmitBlock(NewNull);
343224078Szack    Builder.CreateBr(NewEnd);
344191783Srmacklem    EmitBlock(NewEnd);
345192115Srmacklem
346220648Srmacklem    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
347191783Srmacklem    PHI->reserveOperandSpace(2);
348192115Srmacklem    PHI->addIncoming(NewPtr, NewNotNull);
349191783Srmacklem    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
350191783Srmacklem
351191783Srmacklem    NewPtr = PHI;
352191783Srmacklem  }
353191783Srmacklem
354191783Srmacklem  return NewPtr;
355191783Srmacklem}
356191783Srmacklem
357192115Srmacklemstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
358191783Srmacklem                                   ASTContext &Context) {
359191783Srmacklem  // The class has base classes - we don't support that right now.
360191783Srmacklem  if (RD->getNumBases() > 0)
361191783Srmacklem    return false;
362191783Srmacklem
363191783Srmacklem  for (CXXRecordDecl::field_iterator I = RD->field_begin(Context),
364191783Srmacklem       E = RD->field_end(Context); I != E; ++I) {
365191783Srmacklem    // We don't support ctors for fields that aren't POD.
366191783Srmacklem    if (!I->getType()->isPODType())
367191783Srmacklem      return false;
368191783Srmacklem  }
369192337Srmacklem
370191783Srmacklem  return true;
371191783Srmacklem}
372191783Srmacklem
373191783Srmacklemvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
374244042Srmacklem  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
375191783Srmacklem    ErrorUnsupported(D, "C++ constructor", true);
376191783Srmacklem    return;
377191783Srmacklem  }
378191783Srmacklem
379244042Srmacklem  EmitGlobal(GlobalDecl(D, Ctor_Complete));
380191783Srmacklem  EmitGlobal(GlobalDecl(D, Ctor_Base));
381191783Srmacklem}
382191783Srmacklem
383191783Srmacklemvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
384191783Srmacklem                                       CXXCtorType Type) {
385191783Srmacklem
386191783Srmacklem  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
387191783Srmacklem
388191783Srmacklem  CodeGenFunction(*this).GenerateCode(D, Fn);
389222289Srmacklem
390207082Srmacklem  SetFunctionDefinitionAttributes(D, Fn);
391191783Srmacklem  SetLLVMFunctionAttributesForDefinition(D, Fn);
392191783Srmacklem}
393191783Srmacklem
394191783Srmacklemllvm::Function *
395191783SrmacklemCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
396191783Srmacklem                                       CXXCtorType Type) {
397191783Srmacklem  const llvm::FunctionType *FTy =
398191783Srmacklem    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
399191783Srmacklem
400191783Srmacklem  const char *Name = getMangledCXXCtorName(D, Type);
401191783Srmacklem  return cast<llvm::Function>(
402191783Srmacklem                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
403191783Srmacklem}
404191783Srmacklem
405191783Srmacklemconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
406191783Srmacklem                                                 CXXCtorType Type) {
407191783Srmacklem  llvm::SmallString<256> Name;
408191783Srmacklem  llvm::raw_svector_ostream Out(Name);
409191783Srmacklem  mangleCXXCtor(D, Type, Context, Out);
410191783Srmacklem
411191783Srmacklem  Name += '\0';
412191783Srmacklem  return UniqueMangledName(Name.begin(), Name.end());
413191783Srmacklem}
414191783Srmacklem
415191783Srmacklemvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
416191783Srmacklem  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
417191783Srmacklem    ErrorUnsupported(D, "C++ destructor", true);
418244042Srmacklem    return;
419191783Srmacklem  }
420222719Srmacklem
421191783Srmacklem  EmitCXXDestructor(D, Dtor_Complete);
422191783Srmacklem  EmitCXXDestructor(D, Dtor_Base);
423222719Srmacklem}
424191783Srmacklem
425191783Srmacklemvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
426191783Srmacklem                                      CXXDtorType Type) {
427191783Srmacklem  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
428191783Srmacklem
429191783Srmacklem  CodeGenFunction(*this).GenerateCode(D, Fn);
430191783Srmacklem
431191783Srmacklem  SetFunctionDefinitionAttributes(D, Fn);
432191783Srmacklem  SetLLVMFunctionAttributesForDefinition(D, Fn);
433244042Srmacklem}
434191783Srmacklem
435227760Srmacklemllvm::Function *
436227760SrmacklemCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
437191783Srmacklem                                      CXXDtorType Type) {
438191783Srmacklem  const llvm::FunctionType *FTy =
439191783Srmacklem    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
440191783Srmacklem
441191783Srmacklem  const char *Name = getMangledCXXDtorName(D, Type);
442191783Srmacklem  return cast<llvm::Function>(
443244042Srmacklem                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
444244042Srmacklem}
445244042Srmacklem
446244042Srmacklemconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
447244042Srmacklem                                                 CXXDtorType Type) {
448244042Srmacklem  llvm::SmallString<256> Name;
449244042Srmacklem  llvm::raw_svector_ostream Out(Name);
450244042Srmacklem  mangleCXXDtor(D, Type, Context, Out);
451244042Srmacklem
452244042Srmacklem  Name += '\0';
453244042Srmacklem  return UniqueMangledName(Name.begin(), Name.end());
454244042Srmacklem}
455244042Srmacklem