CGCXX.cpp revision e9918d2443ad524e0f488e8f15d9bce4e7373cd1
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 "clang/AST/ASTContext.h" 19#include "clang/AST/Decl.h" 20#include "clang/AST/DeclCXX.h" 21#include "clang/AST/DeclObjC.h" 22#include "llvm/ADT/StringExtras.h" 23using namespace clang; 24using namespace CodeGen; 25 26 27// FIXME: Name mangling should be moved to a separate class. 28 29static void mangleDeclContextInternal(const DeclContext *D, std::string &S) 30{ 31 // FIXME: Should ObjcMethodDecl have the TranslationUnitDecl as its parent? 32 assert((!D->getParent() || isa<TranslationUnitDecl>(D->getParent())) && 33 "Only one level of decl context mangling is currently supported!"); 34 35 if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) { 36 S += llvm::utostr(FD->getIdentifier()->getLength()); 37 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!"); 43 } else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) { 44 45 // FIXME: This should really use GetNameForMethod from CGObjCMac. 46 std::string Name; 47 Name += MD->isInstanceMethod() ? '-' : '+'; 48 Name += '['; 49 Name += MD->getClassInterface()->getNameAsString(); 50 Name += ' '; 51 Name += MD->getSelector().getAsString(); 52 Name += ']'; 53 S += llvm::utostr(Name.length()); 54 S += Name; 55 } 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 65 S += llvm::utostr(D.getIdentifier()->getLength()); 66 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 87void 88CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, 89 llvm::GlobalVariable *GV) { 90 // FIXME: This should use __cxa_guard_{acquire,release}? 91 92 assert(!getContext().getLangOptions().ThreadsafeStatics && 93 "thread safe statics are currently not supported!"); 94 95 // Create the guard variable. 96 llvm::GlobalValue *GuardV = 97 new llvm::GlobalVariable(llvm::Type::Int64Ty, false, 98 GV->getLinkage(), 99 llvm::Constant::getNullValue(llvm::Type::Int64Ty), 100 mangleGuardVariable(D), 101 &CGM.getModule()); 102 103 // Load the first byte of the guard variable. 104 const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 105 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 112 llvm::BasicBlock *InitBlock = createBasicBlock("init"); 113 llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 114 115 // If the guard variable is 0, jump to the initializer code. 116 Builder.CreateCondBr(ICmp, InitBlock, EndBlock); 117 118 EmitBlock(InitBlock); 119 120 // Patch the name. FIXME: We shouldn't need to do this. 121 GV->setName(mangleVarDecl(D)); 122 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); 137} 138 139RValue 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 145 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 146 const llvm::Type *Ty = 147 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 148 FPT->isVariadic()); 149 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 169 for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end(); 170 I != E; ++I) 171 Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); 172 173 QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); 174 return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), 175 Callee, Args, MD); 176} 177