CGCXX.cpp revision d3fd6bad1249d3f34d71b73e2333fab0db51cce4
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::EmitCXXMemberCall(const CXXMethodDecl *MD, 81 llvm::Value *Callee, 82 llvm::Value *This, 83 CallExpr::const_arg_iterator ArgBeg, 84 CallExpr::const_arg_iterator ArgEnd) { 85 assert(MD->isInstance() && 86 "Trying to emit a member call expr on a static method!"); 87 88 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 89 90 CallArgList Args; 91 92 // Push the this ptr. 93 Args.push_back(std::make_pair(RValue::get(This), 94 MD->getThisType(getContext()))); 95 96 // And the rest of the call args 97 EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); 98 99 QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); 100 return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), 101 Callee, Args, MD); 102} 103 104RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { 105 const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()); 106 const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); 107 108 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 109 const llvm::Type *Ty = 110 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 111 FPT->isVariadic()); 112 llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 113 114 llvm::Value *This; 115 116 if (ME->isArrow()) 117 This = EmitScalarExpr(ME->getBase()); 118 else { 119 LValue BaseLV = EmitLValue(ME->getBase()); 120 This = BaseLV.getAddress(); 121 } 122 123 return EmitCXXMemberCall(MD, Callee, This, 124 CE->arg_begin(), CE->arg_end()); 125} 126 127RValue 128CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 129 const CXXMethodDecl *MD) { 130 assert(MD->isInstance() && 131 "Trying to emit a member call expr on a static method!"); 132 133 134 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 135 const llvm::Type *Ty = 136 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 137 FPT->isVariadic()); 138 llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 139 140 llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 141 142 return EmitCXXMemberCall(MD, Callee, This, 143 E->arg_begin() + 1, E->arg_end()); 144} 145 146llvm::Value *CodeGenFunction::LoadCXXThis() { 147 assert(isa<CXXMethodDecl>(CurFuncDecl) && 148 "Must be in a C++ member function decl to load 'this'"); 149 assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && 150 "Must be in a C++ member function decl to load 'this'"); 151 152 // FIXME: What if we're inside a block? 153 // ans: See how CodeGenFunction::LoadObjCSelf() uses 154 // CodeGenFunction::BlockForwardSelf() for how to do this. 155 return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 156} 157 158void 159CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 160 CXXCtorType Type, 161 llvm::Value *This, 162 CallExpr::const_arg_iterator ArgBeg, 163 CallExpr::const_arg_iterator ArgEnd) { 164 llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 165 166 EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 167} 168 169void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 170 CXXDtorType Type, 171 llvm::Value *This) { 172 llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 173 174 EmitCXXMemberCall(D, Callee, This, 0, 0); 175} 176 177void 178CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 179 const CXXConstructExpr *E) { 180 assert(Dest && "Must have a destination!"); 181 182 const CXXRecordDecl *RD = 183 cast<CXXRecordDecl>(E->getType()->getAsRecordType()->getDecl()); 184 if (RD->hasTrivialConstructor()) 185 return; 186 187 // Call the constructor. 188 EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 189 E->arg_begin(), E->arg_end()); 190} 191 192void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, 193 llvm::Value *Ptr) { 194 LiveTemporaries.push_back(Temporary); 195 196 // Make a cleanup scope and emit the destructor. 197 { 198 CleanupScope Scope(*this); 199 200 EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr); 201 } 202} 203 204RValue 205CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, 206 llvm::Value *AggLoc, 207 bool isAggLocVolatile) { 208 // Keep track of the current cleanup stack depth. 209 size_t CleanupStackDepth = CleanupEntries.size(); 210 211 unsigned OldNumLiveTemporaries = LiveTemporaries.size(); 212 213 RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); 214 215 // Go through the temporaries backwards. 216 for (unsigned i = E->getNumTemporaries(); i != 0; --i) { 217 assert(LiveTemporaries.back() == E->getTemporary(i - 1)); 218 LiveTemporaries.pop_back(); 219 } 220 221 assert(OldNumLiveTemporaries == LiveTemporaries.size() && 222 "Live temporary stack mismatch!"); 223 224 EmitCleanupBlocks(CleanupStackDepth); 225 226 return RV; 227} 228 229llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 230 if (E->isArray()) { 231 ErrorUnsupported(E, "new[] expression"); 232 return llvm::UndefValue::get(ConvertType(E->getType())); 233 } 234 235 QualType AllocType = E->getAllocatedType(); 236 FunctionDecl *NewFD = E->getOperatorNew(); 237 const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 238 239 CallArgList NewArgs; 240 241 // The allocation size is the first argument. 242 QualType SizeTy = getContext().getSizeType(); 243 llvm::Value *AllocSize = 244 llvm::ConstantInt::get(ConvertType(SizeTy), 245 getContext().getTypeSize(AllocType) / 8); 246 247 NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 248 249 // Emit the rest of the arguments. 250 // FIXME: Ideally, this should just use EmitCallArgs. 251 CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 252 253 // First, use the types from the function type. 254 // We start at 1 here because the first argument (the allocation size) 255 // has already been emitted. 256 for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 257 QualType ArgType = NewFTy->getArgType(i); 258 259 assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 260 getTypePtr() == 261 getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 262 "type mismatch in call argument!"); 263 264 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 265 ArgType)); 266 267 } 268 269 // Either we've emitted all the call args, or we have a call to a 270 // variadic function. 271 assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 272 "Extra arguments in non-variadic function!"); 273 274 // If we still have any arguments, emit them using the type of the argument. 275 for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 276 NewArg != NewArgEnd; ++NewArg) { 277 QualType ArgType = NewArg->getType(); 278 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 279 ArgType)); 280 } 281 282 // Emit the call to new. 283 RValue RV = 284 EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 285 CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 286 NewArgs, NewFD); 287 288 // If an allocation function is declared with an empty exception specification 289 // it returns null to indicate failure to allocate storage. [expr.new]p13. 290 // (We don't need to check for null when there's no new initializer and 291 // we're allocating a POD type). 292 bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 293 !(AllocType->isPODType() && !E->hasInitializer()); 294 295 if (NullCheckResult) { 296 ErrorUnsupported(E, "new expr that needs to be null checked"); 297 return llvm::UndefValue::get(ConvertType(E->getType())); 298 } 299 300 llvm::Value *NewPtr = 301 Builder.CreateBitCast(RV.getScalarVal(), ConvertType(E->getType())); 302 303 if (AllocType->isPODType()) { 304 if (E->hasInitializer()) { 305 assert(E->getNumConstructorArgs() == 1 && 306 "Can only have one argument to initializer of POD type."); 307 308 const Expr *Init = E->getConstructorArg(0); 309 310 if (!hasAggregateLLVMType(AllocType)) 311 Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 312 else if (AllocType->isAnyComplexType()) 313 EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 314 else 315 EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 316 } 317 } else { 318 // Call the constructor. 319 CXXConstructorDecl *Ctor = E->getConstructor(); 320 321 EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 322 E->constructor_arg_begin(), 323 E->constructor_arg_end()); 324 } 325 326 return NewPtr; 327} 328 329static bool canGenerateCXXstructor(const CXXRecordDecl *RD, 330 ASTContext &Context) { 331 // The class has base classes - we don't support that right now. 332 if (RD->getNumBases() > 0) 333 return false; 334 335 for (CXXRecordDecl::field_iterator I = RD->field_begin(Context), 336 E = RD->field_end(Context); I != E; ++I) { 337 // We don't support ctors for fields that aren't POD. 338 if (!I->getType()->isPODType()) 339 return false; 340 } 341 342 return true; 343} 344 345void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 346 if (!canGenerateCXXstructor(D->getParent(), getContext())) { 347 ErrorUnsupported(D, "C++ constructor", true); 348 return; 349 } 350 351 EmitGlobal(GlobalDecl(D, Ctor_Complete)); 352 EmitGlobal(GlobalDecl(D, Ctor_Base)); 353} 354 355void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 356 CXXCtorType Type) { 357 358 llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 359 360 CodeGenFunction(*this).GenerateCode(D, Fn); 361 362 SetFunctionDefinitionAttributes(D, Fn); 363 SetLLVMFunctionAttributesForDefinition(D, Fn); 364} 365 366llvm::Function * 367CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 368 CXXCtorType Type) { 369 const llvm::FunctionType *FTy = 370 getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 371 372 const char *Name = getMangledCXXCtorName(D, Type); 373 return cast<llvm::Function>( 374 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 375} 376 377const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 378 CXXCtorType Type) { 379 llvm::SmallString<256> Name; 380 llvm::raw_svector_ostream Out(Name); 381 mangleCXXCtor(D, Type, Context, Out); 382 383 Name += '\0'; 384 return UniqueMangledName(Name.begin(), Name.end()); 385} 386 387void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 388 if (!canGenerateCXXstructor(D->getParent(), getContext())) { 389 ErrorUnsupported(D, "C++ destructor", true); 390 return; 391 } 392 393 EmitCXXDestructor(D, Dtor_Complete); 394 EmitCXXDestructor(D, Dtor_Base); 395} 396 397void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 398 CXXDtorType Type) { 399 llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 400 401 CodeGenFunction(*this).GenerateCode(D, Fn); 402 403 SetFunctionDefinitionAttributes(D, Fn); 404 SetLLVMFunctionAttributesForDefinition(D, Fn); 405} 406 407llvm::Function * 408CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 409 CXXDtorType Type) { 410 const llvm::FunctionType *FTy = 411 getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 412 413 const char *Name = getMangledCXXDtorName(D, Type); 414 return cast<llvm::Function>( 415 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 416} 417 418const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 419 CXXDtorType Type) { 420 llvm::SmallString<256> Name; 421 llvm::raw_svector_ostream Out(Name); 422 mangleCXXDtor(D, Type, Context, Out); 423 424 Name += '\0'; 425 return UniqueMangledName(Name.begin(), Name.end()); 426} 427