CGCXX.cpp revision 738f8c278da5950d0d4607de2debe0bdfad64185
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/RecordLayout.h" 21#include "clang/AST/Decl.h" 22#include "clang/AST/DeclCXX.h" 23#include "clang/AST/DeclObjC.h" 24#include "llvm/ADT/StringExtras.h" 25using namespace clang; 26using namespace CodeGen; 27 28void 29CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, 30 llvm::GlobalVariable *GV) { 31 // FIXME: This should use __cxa_guard_{acquire,release}? 32 33 assert(!getContext().getLangOptions().ThreadsafeStatics && 34 "thread safe statics are currently not supported!"); 35 36 llvm::SmallString<256> GuardVName; 37 llvm::raw_svector_ostream GuardVOut(GuardVName); 38 mangleGuardVariable(&D, getContext(), GuardVOut); 39 40 // Create the guard variable. 41 llvm::GlobalValue *GuardV = 42 new llvm::GlobalVariable(CGM.getModule(), llvm::Type::Int64Ty, false, 43 GV->getLinkage(), 44 llvm::Constant::getNullValue(llvm::Type::Int64Ty), 45 GuardVName.c_str()); 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 110 if (MD->isVirtual()) { 111 ErrorUnsupported(CE, "virtual dispatch"); 112 } 113 114 const llvm::Type *Ty = 115 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 116 FPT->isVariadic()); 117 llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 118 119 llvm::Value *This; 120 121 if (ME->isArrow()) 122 This = EmitScalarExpr(ME->getBase()); 123 else { 124 LValue BaseLV = EmitLValue(ME->getBase()); 125 This = BaseLV.getAddress(); 126 } 127 128 return EmitCXXMemberCall(MD, Callee, This, 129 CE->arg_begin(), CE->arg_end()); 130} 131 132RValue 133CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 134 const CXXMethodDecl *MD) { 135 assert(MD->isInstance() && 136 "Trying to emit a member call expr on a static method!"); 137 138 139 const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 140 const llvm::Type *Ty = 141 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 142 FPT->isVariadic()); 143 llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 144 145 llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 146 147 return EmitCXXMemberCall(MD, Callee, This, 148 E->arg_begin() + 1, E->arg_end()); 149} 150 151llvm::Value *CodeGenFunction::LoadCXXThis() { 152 assert(isa<CXXMethodDecl>(CurFuncDecl) && 153 "Must be in a C++ member function decl to load 'this'"); 154 assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && 155 "Must be in a C++ member function decl to load 'this'"); 156 157 // FIXME: What if we're inside a block? 158 // ans: See how CodeGenFunction::LoadObjCSelf() uses 159 // CodeGenFunction::BlockForwardSelf() for how to do this. 160 return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 161} 162 163static bool 164GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, 165 const CXXRecordDecl *ClassDecl, 166 const CXXRecordDecl *BaseClassDecl) { 167 assert(!ClassDecl->isPolymorphic() && 168 "FIXME: We don't support polymorphic classes yet!"); 169 for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 170 e = ClassDecl->bases_end(); i != e; ++i) { 171 if (i->isVirtual()) 172 continue; 173 const CXXRecordDecl *Base = 174 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 175 if (Base == BaseClassDecl) { 176 NestedBasePaths.push_back(BaseClassDecl); 177 return true; 178 } 179 } 180 // BaseClassDecl not an immediate base of ClassDecl. 181 for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 182 e = ClassDecl->bases_end(); i != e; ++i) { 183 if (i->isVirtual()) 184 continue; 185 const CXXRecordDecl *Base = 186 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 187 if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { 188 NestedBasePaths.push_back(Base); 189 return true; 190 } 191 } 192 return false; 193} 194 195llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, 196 const CXXRecordDecl *ClassDecl, 197 const CXXRecordDecl *BaseClassDecl) { 198 if (ClassDecl == BaseClassDecl) 199 return BaseValue; 200 201 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 202 llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; 203 GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); 204 assert(NestedBasePaths.size() > 0 && 205 "AddressCXXOfBaseClass - inheritence path failed"); 206 NestedBasePaths.push_back(ClassDecl); 207 uint64_t Offset = 0; 208 209 // Accessing a member of the base class. Must add delata to 210 // the load of 'this'. 211 for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { 212 const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; 213 const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; 214 const ASTRecordLayout &Layout = 215 getContext().getASTRecordLayout(DerivedClass); 216 Offset += Layout.getBaseClassOffset(BaseClass) / 8; 217 } 218 llvm::Value *OffsetVal = 219 llvm::ConstantInt::get( 220 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); 221 BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr); 222 BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr"); 223 QualType BTy = 224 getContext().getCanonicalType( 225 getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 226 const llvm::Type *BasePtr = ConvertType(BTy); 227 BasePtr = llvm::PointerType::getUnqual(BasePtr); 228 BaseValue = Builder.CreateBitCast(BaseValue, BasePtr); 229 return BaseValue; 230} 231 232void 233CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 234 CXXCtorType Type, 235 llvm::Value *This, 236 CallExpr::const_arg_iterator ArgBeg, 237 CallExpr::const_arg_iterator ArgEnd) { 238 llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 239 240 EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 241} 242 243void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 244 CXXDtorType Type, 245 llvm::Value *This) { 246 llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 247 248 EmitCXXMemberCall(D, Callee, This, 0, 0); 249} 250 251void 252CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 253 const CXXConstructExpr *E) { 254 assert(Dest && "Must have a destination!"); 255 256 const CXXRecordDecl *RD = 257 cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); 258 if (RD->hasTrivialConstructor()) 259 return; 260 261 // Call the constructor. 262 EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 263 E->arg_begin(), E->arg_end()); 264} 265 266llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 267 if (E->isArray()) { 268 ErrorUnsupported(E, "new[] expression"); 269 return llvm::UndefValue::get(ConvertType(E->getType())); 270 } 271 272 QualType AllocType = E->getAllocatedType(); 273 FunctionDecl *NewFD = E->getOperatorNew(); 274 const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 275 276 CallArgList NewArgs; 277 278 // The allocation size is the first argument. 279 QualType SizeTy = getContext().getSizeType(); 280 llvm::Value *AllocSize = 281 llvm::ConstantInt::get(ConvertType(SizeTy), 282 getContext().getTypeSize(AllocType) / 8); 283 284 NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 285 286 // Emit the rest of the arguments. 287 // FIXME: Ideally, this should just use EmitCallArgs. 288 CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 289 290 // First, use the types from the function type. 291 // We start at 1 here because the first argument (the allocation size) 292 // has already been emitted. 293 for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 294 QualType ArgType = NewFTy->getArgType(i); 295 296 assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 297 getTypePtr() == 298 getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 299 "type mismatch in call argument!"); 300 301 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 302 ArgType)); 303 304 } 305 306 // Either we've emitted all the call args, or we have a call to a 307 // variadic function. 308 assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 309 "Extra arguments in non-variadic function!"); 310 311 // If we still have any arguments, emit them using the type of the argument. 312 for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 313 NewArg != NewArgEnd; ++NewArg) { 314 QualType ArgType = NewArg->getType(); 315 NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 316 ArgType)); 317 } 318 319 // Emit the call to new. 320 RValue RV = 321 EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 322 CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 323 NewArgs, NewFD); 324 325 // If an allocation function is declared with an empty exception specification 326 // it returns null to indicate failure to allocate storage. [expr.new]p13. 327 // (We don't need to check for null when there's no new initializer and 328 // we're allocating a POD type). 329 bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 330 !(AllocType->isPODType() && !E->hasInitializer()); 331 332 llvm::BasicBlock *NewNull = 0; 333 llvm::BasicBlock *NewNotNull = 0; 334 llvm::BasicBlock *NewEnd = 0; 335 336 llvm::Value *NewPtr = RV.getScalarVal(); 337 338 if (NullCheckResult) { 339 NewNull = createBasicBlock("new.null"); 340 NewNotNull = createBasicBlock("new.notnull"); 341 NewEnd = createBasicBlock("new.end"); 342 343 llvm::Value *IsNull = 344 Builder.CreateICmpEQ(NewPtr, 345 llvm::Constant::getNullValue(NewPtr->getType()), 346 "isnull"); 347 348 Builder.CreateCondBr(IsNull, NewNull, NewNotNull); 349 EmitBlock(NewNotNull); 350 } 351 352 NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); 353 354 if (AllocType->isPODType()) { 355 if (E->getNumConstructorArgs() > 0) { 356 assert(E->getNumConstructorArgs() == 1 && 357 "Can only have one argument to initializer of POD type."); 358 359 const Expr *Init = E->getConstructorArg(0); 360 361 if (!hasAggregateLLVMType(AllocType)) 362 Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 363 else if (AllocType->isAnyComplexType()) 364 EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 365 else 366 EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 367 } 368 } else { 369 // Call the constructor. 370 CXXConstructorDecl *Ctor = E->getConstructor(); 371 372 EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 373 E->constructor_arg_begin(), 374 E->constructor_arg_end()); 375 } 376 377 if (NullCheckResult) { 378 Builder.CreateBr(NewEnd); 379 EmitBlock(NewNull); 380 Builder.CreateBr(NewEnd); 381 EmitBlock(NewEnd); 382 383 llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); 384 PHI->reserveOperandSpace(2); 385 PHI->addIncoming(NewPtr, NewNotNull); 386 PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull); 387 388 NewPtr = PHI; 389 } 390 391 return NewPtr; 392} 393 394static bool canGenerateCXXstructor(const CXXRecordDecl *RD, 395 ASTContext &Context) { 396 // The class has base classes - we don't support that right now. 397 if (RD->getNumBases() > 0) 398 return false; 399 400 for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 401 I != E; ++I) { 402 // We don't support ctors for fields that aren't POD. 403 if (!I->getType()->isPODType()) 404 return false; 405 } 406 407 return true; 408} 409 410void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 411 if (!canGenerateCXXstructor(D->getParent(), getContext())) { 412 ErrorUnsupported(D, "C++ constructor", true); 413 return; 414 } 415 416 EmitGlobal(GlobalDecl(D, Ctor_Complete)); 417 EmitGlobal(GlobalDecl(D, Ctor_Base)); 418} 419 420void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 421 CXXCtorType Type) { 422 423 llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 424 425 CodeGenFunction(*this).GenerateCode(D, Fn); 426 427 SetFunctionDefinitionAttributes(D, Fn); 428 SetLLVMFunctionAttributesForDefinition(D, Fn); 429} 430 431llvm::Function * 432CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 433 CXXCtorType Type) { 434 const llvm::FunctionType *FTy = 435 getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 436 437 const char *Name = getMangledCXXCtorName(D, Type); 438 return cast<llvm::Function>( 439 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 440} 441 442const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 443 CXXCtorType Type) { 444 llvm::SmallString<256> Name; 445 llvm::raw_svector_ostream Out(Name); 446 mangleCXXCtor(D, Type, Context, Out); 447 448 Name += '\0'; 449 return UniqueMangledName(Name.begin(), Name.end()); 450} 451 452void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 453 if (!canGenerateCXXstructor(D->getParent(), getContext())) { 454 ErrorUnsupported(D, "C++ destructor", true); 455 return; 456 } 457 458 EmitCXXDestructor(D, Dtor_Complete); 459 EmitCXXDestructor(D, Dtor_Base); 460} 461 462void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 463 CXXDtorType Type) { 464 llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 465 466 CodeGenFunction(*this).GenerateCode(D, Fn); 467 468 SetFunctionDefinitionAttributes(D, Fn); 469 SetLLVMFunctionAttributesForDefinition(D, Fn); 470} 471 472llvm::Function * 473CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 474 CXXDtorType Type) { 475 const llvm::FunctionType *FTy = 476 getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 477 478 const char *Name = getMangledCXXDtorName(D, Type); 479 return cast<llvm::Function>( 480 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 481} 482 483const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 484 CXXDtorType Type) { 485 llvm::SmallString<256> Name; 486 llvm::raw_svector_ostream Out(Name); 487 mangleCXXDtor(D, Type, Context, Out); 488 489 Name += '\0'; 490 return UniqueMangledName(Name.begin(), Name.end()); 491} 492 493llvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { 494 llvm::Type *Ptr8Ty; 495 Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 496 llvm::Constant *rtti = llvm::Constant::getNullValue(Ptr8Ty); 497 498 if (!getContext().getLangOptions().Rtti) 499 return rtti; 500 501 llvm::SmallString<256> OutName; 502 llvm::raw_svector_ostream Out(OutName); 503 QualType ClassTy; 504 // FIXME: What is the design on getTagDeclType when it requires casting 505 // away const? mutable? 506 ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); 507 mangleCXXRtti(ClassTy, getContext(), Out); 508 const char *Name = OutName.c_str(); 509 llvm::GlobalVariable::LinkageTypes linktype; 510 linktype = llvm::GlobalValue::WeakAnyLinkage; 511 std::vector<llvm::Constant *> info; 512 assert (0 && "FIXME: implement rtti descriptor"); 513 // FIXME: descriptor 514 info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 515 assert (0 && "FIXME: implement rtti ts"); 516 // FIXME: TS 517 info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 518 519 llvm::Constant *C; 520 llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size()); 521 C = llvm::ConstantArray::get(type, info); 522 rtti = new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C, 523 Name); 524 rtti = llvm::ConstantExpr::getBitCast(rtti, Ptr8Ty); 525 return rtti; 526} 527 528llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { 529 llvm::SmallString<256> OutName; 530 llvm::raw_svector_ostream Out(OutName); 531 QualType ClassTy; 532 // FIXME: What is the design on getTagDeclType when it requires casting 533 // away const? mutable? 534 ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); 535 mangleCXXVtable(ClassTy, getContext(), Out); 536 const char *Name = OutName.c_str(); 537 llvm::GlobalVariable::LinkageTypes linktype; 538 linktype = llvm::GlobalValue::WeakAnyLinkage; 539 std::vector<llvm::Constant *> methods; 540 typedef CXXRecordDecl::method_iterator meth_iter; 541 llvm::Constant *m; 542 llvm::Type *Ptr8Ty; 543 Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 544 m = llvm::Constant::getNullValue(Ptr8Ty); 545 int64_t offset = 0; 546 methods.push_back(m); offset += LLVMPointerWidth; 547 methods.push_back(GenerateRtti(RD)); offset += LLVMPointerWidth; 548 for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 549 ++mi) { 550 if (mi->isVirtual()) { 551 m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); 552 m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); 553 methods.push_back(m); 554 } 555 } 556 llvm::Constant *C; 557 llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size()); 558 C = llvm::ConstantArray::get(type, methods); 559 llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true, 560 linktype, C, Name); 561 vtable = Builder.CreateBitCast(vtable, Ptr8Ty); 562 // FIXME: finish layout for virtual bases 563 vtable = Builder.CreateGEP(vtable, 564 llvm::ConstantInt::get(llvm::Type::Int64Ty, 565 offset/8)); 566 return vtable; 567} 568 569/// EmitCtorPrologue - This routine generates necessary code to initialize 570/// base classes and non-static data members belonging to this constructor. 571void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { 572 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 573 assert(ClassDecl->getNumVBases() == 0 574 && "FIXME: virtual base initialization unsupported"); 575 llvm::Value *LoadOfThis = 0; 576 577 578 for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 579 E = CD->init_end(); 580 B != E; ++B) { 581 CXXBaseOrMemberInitializer *Member = (*B); 582 if (Member->isBaseInitializer()) { 583 LoadOfThis = LoadCXXThis(); 584 Type *BaseType = Member->getBaseClass(); 585 CXXRecordDecl *BaseClassDecl = 586 cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 587 llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 588 BaseClassDecl); 589 EmitCXXConstructorCall(Member->getConstructor(), 590 Ctor_Complete, V, 591 Member->const_arg_begin(), 592 Member->const_arg_end()); 593 } else { 594 // non-static data member initilaizers. 595 FieldDecl *Field = Member->getMember(); 596 QualType FieldType = getContext().getCanonicalType((Field)->getType()); 597 assert(!getContext().getAsArrayType(FieldType) 598 && "FIXME. Field arrays initialization unsupported"); 599 600 LoadOfThis = LoadCXXThis(); 601 LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); 602 if (FieldType->getAs<RecordType>()) { 603 604 assert(Member->getConstructor() && 605 "EmitCtorPrologue - no constructor to initialize member"); 606 EmitCXXConstructorCall(Member->getConstructor(), 607 Ctor_Complete, LHS.getAddress(), 608 Member->const_arg_begin(), 609 Member->const_arg_end()); 610 continue; 611 } 612 613 assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only"); 614 Expr *RhsExpr = *Member->arg_begin(); 615 llvm::Value *RHS = EmitScalarExpr(RhsExpr, true); 616 if (LHS.isBitfield()) 617 EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0); 618 else 619 EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType); 620 } 621 } 622 623 // Initialize the vtable pointer 624 if (ClassDecl->isPolymorphic() || ClassDecl->getNumVBases()) { 625 if (!LoadOfThis) 626 LoadOfThis = LoadCXXThis(); 627 llvm::Value *VtableField; 628 llvm::Type *Ptr8Ty, *PtrPtr8Ty; 629 Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 630 PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0); 631 VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty); 632 llvm::Value *vtable = GenerateVtable(ClassDecl); 633 Builder.CreateStore(vtable, VtableField); 634 } 635} 636 637/// EmitDtorEpilogue - Emit all code that comes at the end of class's 638/// destructor. This is to call destructors on members and base classes 639/// in reverse order of their construction. 640void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { 641 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext()); 642 assert(!ClassDecl->isPolymorphic() && 643 "FIXME. polymorphic destruction not supported"); 644 (void)ClassDecl; // prevent warning. 645 646 for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(), 647 *E = DD->destr_end(); B != E; ++B) { 648 uintptr_t BaseOrMember = (*B); 649 if (DD->isMemberToDestroy(BaseOrMember)) { 650 FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember); 651 QualType FieldType = getContext().getCanonicalType((FD)->getType()); 652 assert(!getContext().getAsArrayType(FieldType) 653 && "FIXME. Field arrays destruction unsupported"); 654 const RecordType *RT = FieldType->getAs<RecordType>(); 655 CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 656 if (FieldClassDecl->hasTrivialDestructor()) 657 continue; 658 llvm::Value *LoadOfThis = LoadCXXThis(); 659 LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0); 660 EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 661 Dtor_Complete, LHS.getAddress()); 662 } else { 663 const RecordType *RT = 664 DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>(); 665 CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 666 if (BaseClassDecl->hasTrivialDestructor()) 667 continue; 668 llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 669 ClassDecl,BaseClassDecl); 670 EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), 671 Dtor_Complete, V); 672 } 673 } 674} 675