blob: 24b4a28299308f1eb4aea7c9e5cbb8ea230b3a27 [file] [log] [blame]
Anders Carlssone1b29ef2008-08-22 16:00:37 +00001//===--- 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 "clang/AST/ASTContext.h"
19#include "clang/AST/Decl.h"
Anders Carlsson774e7c62009-04-03 22:50:24 +000020#include "clang/AST/DeclCXX.h"
Anders Carlsson86e96442008-08-23 19:42:54 +000021#include "clang/AST/DeclObjC.h"
Anders Carlssone1b29ef2008-08-22 16:00:37 +000022#include "llvm/ADT/StringExtras.h"
Anders Carlssone1b29ef2008-08-22 16:00:37 +000023using namespace clang;
24using namespace CodeGen;
25
Anders Carlssone1b29ef2008-08-22 16:00:37 +000026
27// FIXME: Name mangling should be moved to a separate class.
28
29static void mangleDeclContextInternal(const DeclContext *D, std::string &S)
30{
Anders Carlsson86e96442008-08-23 19:42:54 +000031 // FIXME: Should ObjcMethodDecl have the TranslationUnitDecl as its parent?
Eli Friedmane8e32052008-12-16 20:06:41 +000032 assert((!D->getParent() || isa<TranslationUnitDecl>(D->getParent())) &&
Anders Carlssone1b29ef2008-08-22 16:00:37 +000033 "Only one level of decl context mangling is currently supported!");
34
Anders Carlsson86e96442008-08-23 19:42:54 +000035 if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
Chris Lattner077bf5e2008-11-24 03:33:13 +000036 S += llvm::utostr(FD->getIdentifier()->getLength());
Anders Carlssone1b29ef2008-08-22 16:00:37 +000037 S += FD->getIdentifier()->getName();
38
39 if (FD->param_size() == 0)
40 S += 'v';
41 else
42 assert(0 && "mangling of types not supported yet!");
Anders Carlsson86e96442008-08-23 19:42:54 +000043 } else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
44
45 // FIXME: This should really use GetNameForMethod from CGObjCMac.
46 std::string Name;
Douglas Gregorf8d49f62009-01-09 17:18:27 +000047 Name += MD->isInstanceMethod() ? '-' : '+';
Anders Carlsson86e96442008-08-23 19:42:54 +000048 Name += '[';
Chris Lattner077bf5e2008-11-24 03:33:13 +000049 Name += MD->getClassInterface()->getNameAsString();
Anders Carlsson86e96442008-08-23 19:42:54 +000050 Name += ' ';
Chris Lattner077bf5e2008-11-24 03:33:13 +000051 Name += MD->getSelector().getAsString();
Anders Carlsson86e96442008-08-23 19:42:54 +000052 Name += ']';
Chris Lattner077bf5e2008-11-24 03:33:13 +000053 S += llvm::utostr(Name.length());
Anders Carlsson86e96442008-08-23 19:42:54 +000054 S += Name;
Anders Carlssone1b29ef2008-08-22 16:00:37 +000055 } else
56 assert(0 && "Unsupported decl type!");
57}
58
59static void mangleVarDeclInternal(const VarDecl &D, std::string &S)
60{
61 S += 'Z';
62 mangleDeclContextInternal(D.getDeclContext(), S);
63 S += 'E';
64
Chris Lattner077bf5e2008-11-24 03:33:13 +000065 S += llvm::utostr(D.getIdentifier()->getLength());
Anders Carlssone1b29ef2008-08-22 16:00:37 +000066 S += D.getIdentifier()->getName();
67}
68
69static std::string mangleVarDecl(const VarDecl& D)
70{
71 std::string S = "_Z";
72
73 mangleVarDeclInternal(D, S);
74
75 return S;
76}
77
78static std::string mangleGuardVariable(const VarDecl& D)
79{
80 std::string S = "_ZGV";
81
82 mangleVarDeclInternal(D, S);
83
84 return S;
85}
86
Daniel Dunbar0096acf2009-02-25 19:24:29 +000087void
88CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
89 llvm::GlobalVariable *GV) {
90 // FIXME: This should use __cxa_guard_{acquire,release}?
91
Anders Carlssone1b29ef2008-08-22 16:00:37 +000092 assert(!getContext().getLangOptions().ThreadsafeStatics &&
93 "thread safe statics are currently not supported!");
Anders Carlssone1b29ef2008-08-22 16:00:37 +000094
Anders Carlssone1b29ef2008-08-22 16:00:37 +000095 // Create the guard variable.
96 llvm::GlobalValue *GuardV =
97 new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
Daniel Dunbar0096acf2009-02-25 19:24:29 +000098 GV->getLinkage(),
Anders Carlssone1b29ef2008-08-22 16:00:37 +000099 llvm::Constant::getNullValue(llvm::Type::Int64Ty),
100 mangleGuardVariable(D),
101 &CGM.getModule());
102
Anders Carlssone1b29ef2008-08-22 16:00:37 +0000103 // Load the first byte of the guard variable.
Daniel Dunbar0096acf2009-02-25 19:24:29 +0000104 const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
Anders Carlssone1b29ef2008-08-22 16:00:37 +0000105 llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
106 "tmp");
107
108 // Compare it against 0.
109 llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
110 llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
111
Daniel Dunbar55e87422008-11-11 02:29:29 +0000112 llvm::BasicBlock *InitBlock = createBasicBlock("init");
Daniel Dunbar9615ecb2008-11-13 01:38:36 +0000113 llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
Anders Carlssone1b29ef2008-08-22 16:00:37 +0000114
115 // If the guard variable is 0, jump to the initializer code.
116 Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
117
118 EmitBlock(InitBlock);
119
Daniel Dunbar0096acf2009-02-25 19:24:29 +0000120 // Patch the name. FIXME: We shouldn't need to do this.
121 GV->setName(mangleVarDecl(D));
Anders Carlssone1b29ef2008-08-22 16:00:37 +0000122
123 const Expr *Init = D.getInit();
124 if (!hasAggregateLLVMType(Init->getType())) {
125 llvm::Value *V = EmitScalarExpr(Init);
126 Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
127 } else if (Init->getType()->isAnyComplexType()) {
128 EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
129 } else {
130 EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
131 }
132
133 Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
134 Builder.CreateBitCast(GuardV, PtrTy));
135
136 EmitBlock(EndBlock);
Anders Carlssone1b29ef2008-08-22 16:00:37 +0000137}
138
Anders Carlsson774e7c62009-04-03 22:50:24 +0000139RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
140 const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
141 const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
142 assert(MD->isInstance() &&
143 "Trying to emit a member call expr on a static method!");
144
Anders Carlssone9918d22009-04-08 20:31:57 +0000145 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
Anders Carlsson774e7c62009-04-03 22:50:24 +0000146 const llvm::Type *Ty =
Anders Carlssone9918d22009-04-08 20:31:57 +0000147 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
148 FPT->isVariadic());
Anders Carlsson774e7c62009-04-03 22:50:24 +0000149 llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
150
151 llvm::Value *BaseValue = 0;
152
153 // There's a deref operator node added in Sema::BuildCallToMemberFunction
154 // that's giving the wrong type for -> call exprs so we just ignore them
155 // for now.
156 if (ME->isArrow())
157 return EmitUnsupportedRValue(CE, "C++ member call expr");
158 else {
159 LValue BaseLV = EmitLValue(ME->getBase());
160 BaseValue = BaseLV.getAddress();
161 }
162
163 CallArgList Args;
164
165 // Push the 'this' pointer.
166 Args.push_back(std::make_pair(RValue::get(BaseValue),
167 MD->getThisType(getContext())));
168
Anders Carlsson782f3972009-04-08 23:13:16 +0000169 EmitCallArgs(Args, FPT, CE->arg_begin(), CE->arg_end());
Anders Carlsson774e7c62009-04-03 22:50:24 +0000170
171 QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
Anders Carlssone9918d22009-04-08 20:31:57 +0000172 return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
173 Callee, Args, MD);
Anders Carlsson774e7c62009-04-03 22:50:24 +0000174}