CGCXX.cpp revision 95d4e5d2f87a0f07fb143ccb824dfc4c5c595c78
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"
20e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h"
21774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson#include "clang/AST/DeclCXX.h"
2286e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h"
23e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
270096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbarvoid
280096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel DunbarCodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
290096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                                                   llvm::GlobalVariable *GV) {
300096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar  // FIXME: This should use __cxa_guard_{acquire,release}?
310096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar
32e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(!getContext().getLangOptions().ThreadsafeStatics &&
33e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "thread safe statics are currently not supported!");
34e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
35283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::SmallString<256> GuardVName;
36283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::raw_svector_ostream GuardVOut(GuardVName);
37283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  mangleGuardVariable(&D, getContext(), GuardVOut);
38283a062a633d6e868aa2be319da812341fe73728Anders Carlsson
39e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GuardV =
41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
420096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                             GV->getLinkage(),
43e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
44283a062a633d6e868aa2be319da812341fe73728Anders Carlsson                             GuardVName.c_str(),
45e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             &CGM.getModule());
46e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
47e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
480096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar  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.
53e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  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
74e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  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
80774e7c6881ee6cb970cd42239d700dce87ed402aAnders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
81774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
82774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
83774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  assert(MD->isInstance() &&
84774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson         "Trying to emit a member call expr on a static method!");
85774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
86e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
87774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const llvm::Type *Ty =
88e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
89e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                                   FPT->isVariadic());
90774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
91774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
92774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  llvm::Value *BaseValue = 0;
93774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
94774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  // There's a deref operator node added in Sema::BuildCallToMemberFunction
95774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  // that's giving the wrong type for -> call exprs so we just ignore them
96774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  // for now.
97774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  if (ME->isArrow())
98774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    return EmitUnsupportedRValue(CE, "C++ member call expr");
99774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  else {
100774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    LValue BaseLV = EmitLValue(ME->getBase());
101774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    BaseValue = BaseLV.getAddress();
102774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  }
103774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
104774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  CallArgList Args;
105774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
106774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  // Push the 'this' pointer.
107774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  Args.push_back(std::make_pair(RValue::get(BaseValue),
108774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson                                MD->getThisType(getContext())));
109774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
110782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson  EmitCallArgs(Args, FPT, CE->arg_begin(), CE->arg_end());
111774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
112774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
113e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
114e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                  Callee, Args, MD);
115774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson}
1165f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
1175f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
1185f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
1195f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
1205f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
1215f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
1225f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
1235f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
1245f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
1255f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
12695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
12795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
12895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson                                                 CXXCtorType Type) {
12995d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  llvm::SmallString<256> Name;
13095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  llvm::raw_svector_ostream Out(Name);
13195d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
13295d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
13395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  Name += '\0';
13495d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
13595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
13695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
13795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
13895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson                                       CXXCtorType Type) {
13995d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  const llvm::FunctionType *Ty =
14095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
14195d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
14295d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
14395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  llvm::Function *Fn =
14495d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson    cast<llvm::Function>(GetOrCreateLLVMFunction(Name, Ty, D));
14595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
14695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
14795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
14895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
14995d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
15095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
15195d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
15295d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
15395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  ErrorUnsupported(D, "C++ constructor", true);
15495d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
15595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  EmitCXXConstructor(D, Ctor_Complete);
15695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson  EmitCXXConstructor(D, Ctor_Base);
15795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
158