CGCXX.cpp revision 5f4307b7ba164b03c853c8d3eb4674d33f8967a6
1//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code dealing with C++ code generation.
11//
12//===----------------------------------------------------------------------===//
13
14// We might split this into multiple files if it gets too unwieldy
15
16#include "CodeGenFunction.h"
17#include "CodeGenModule.h"
18#include "Mangle.h"
19#include "clang/AST/ASTContext.h"
20#include "clang/AST/Decl.h"
21#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclObjC.h"
23#include "llvm/ADT/StringExtras.h"
24using namespace clang;
25using namespace CodeGen;
26
27void
28CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
29                                                   llvm::GlobalVariable *GV) {
30  // FIXME: This should use __cxa_guard_{acquire,release}?
31
32  assert(!getContext().getLangOptions().ThreadsafeStatics &&
33         "thread safe statics are currently not supported!");
34
35  llvm::SmallString<256> GuardVName;
36  llvm::raw_svector_ostream GuardVOut(GuardVName);
37  mangleGuardVariable(&D, getContext(), GuardVOut);
38
39  // Create the guard variable.
40  llvm::GlobalValue *GuardV =
41    new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
42                             GV->getLinkage(),
43                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
44                             GuardVName.c_str(),
45                             &CGM.getModule());
46
47  // Load the first byte of the guard variable.
48  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
49  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
50                                      "tmp");
51
52  // Compare it against 0.
53  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
54  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
55
56  llvm::BasicBlock *InitBlock = createBasicBlock("init");
57  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
58
59  // If the guard variable is 0, jump to the initializer code.
60  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
61
62  EmitBlock(InitBlock);
63
64  const Expr *Init = D.getInit();
65  if (!hasAggregateLLVMType(Init->getType())) {
66    llvm::Value *V = EmitScalarExpr(Init);
67    Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
68  } else if (Init->getType()->isAnyComplexType()) {
69    EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
70  } else {
71    EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
72  }
73
74  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
75                      Builder.CreateBitCast(GuardV, PtrTy));
76
77  EmitBlock(EndBlock);
78}
79
80RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
81  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
82  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
83  assert(MD->isInstance() &&
84         "Trying to emit a member call expr on a static method!");
85
86  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
87  const llvm::Type *Ty =
88    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
89                                   FPT->isVariadic());
90  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
91
92  llvm::Value *BaseValue = 0;
93
94  // There's a deref operator node added in Sema::BuildCallToMemberFunction
95  // that's giving the wrong type for -> call exprs so we just ignore them
96  // for now.
97  if (ME->isArrow())
98    return EmitUnsupportedRValue(CE, "C++ member call expr");
99  else {
100    LValue BaseLV = EmitLValue(ME->getBase());
101    BaseValue = BaseLV.getAddress();
102  }
103
104  CallArgList Args;
105
106  // Push the 'this' pointer.
107  Args.push_back(std::make_pair(RValue::get(BaseValue),
108                                MD->getThisType(getContext())));
109
110  EmitCallArgs(Args, FPT, CE->arg_begin(), CE->arg_end());
111
112  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
113  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
114                  Callee, Args, MD);
115}
116
117
118llvm::Value *CodeGenFunction::LoadCXXThis() {
119  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
120         "Must be in a C++ member function decl to load 'this'");
121  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
122         "Must be in a C++ member function decl to load 'this'");
123
124  // FIXME: What if we're inside a block?
125  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
126}
127