clang API Documentation
00001 //===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This contains code dealing with C++ code generation of virtual tables. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "CodeGenModule.h" 00015 #include "CodeGenFunction.h" 00016 #include "CGCXXABI.h" 00017 #include "clang/AST/CXXInheritance.h" 00018 #include "clang/AST/RecordLayout.h" 00019 #include "clang/Frontend/CodeGenOptions.h" 00020 #include "llvm/ADT/DenseSet.h" 00021 #include "llvm/ADT/SetVector.h" 00022 #include "llvm/Support/Compiler.h" 00023 #include "llvm/Support/Format.h" 00024 #include "llvm/Transforms/Utils/Cloning.h" 00025 #include <algorithm> 00026 #include <cstdio> 00027 00028 using namespace clang; 00029 using namespace CodeGen; 00030 00031 CodeGenVTables::CodeGenVTables(CodeGenModule &CGM) 00032 : CGM(CGM), VTContext(CGM.getContext()) { } 00033 00034 bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) { 00035 assert(RD->isDynamicClass() && "Non dynamic classes have no VTable."); 00036 00037 TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 00038 if (TSK == TSK_ExplicitInstantiationDeclaration) 00039 return false; 00040 00041 const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); 00042 if (!KeyFunction) 00043 return true; 00044 00045 // Itanium C++ ABI, 5.2.6 Instantiated Templates: 00046 // An instantiation of a class template requires: 00047 // - In the object where instantiated, the virtual table... 00048 if (TSK == TSK_ImplicitInstantiation || 00049 TSK == TSK_ExplicitInstantiationDefinition) 00050 return true; 00051 00052 // If we're building with optimization, we always emit VTables since that 00053 // allows for virtual function calls to be devirtualized. 00054 // (We don't want to do this in -fapple-kext mode however). 00055 if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext) 00056 return true; 00057 00058 return KeyFunction->hasBody(); 00059 } 00060 00061 llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 00062 const ThunkInfo &Thunk) { 00063 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 00064 00065 // Compute the mangled name. 00066 SmallString<256> Name; 00067 llvm::raw_svector_ostream Out(Name); 00068 if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) 00069 getCXXABI().getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), 00070 Thunk.This, Out); 00071 else 00072 getCXXABI().getMangleContext().mangleThunk(MD, Thunk, Out); 00073 Out.flush(); 00074 00075 llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD); 00076 return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true); 00077 } 00078 00079 static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, 00080 llvm::Value *Ptr, 00081 int64_t NonVirtualAdjustment, 00082 int64_t VirtualAdjustment) { 00083 if (!NonVirtualAdjustment && !VirtualAdjustment) 00084 return Ptr; 00085 00086 llvm::Type *Int8PtrTy = CGF.Int8PtrTy; 00087 llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); 00088 00089 if (NonVirtualAdjustment) { 00090 // Do the non-virtual adjustment. 00091 V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); 00092 } 00093 00094 if (VirtualAdjustment) { 00095 llvm::Type *PtrDiffTy = 00096 CGF.ConvertType(CGF.getContext().getPointerDiffType()); 00097 00098 // Do the virtual adjustment. 00099 llvm::Value *VTablePtrPtr = 00100 CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); 00101 00102 llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); 00103 00104 llvm::Value *OffsetPtr = 00105 CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 00106 00107 OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); 00108 00109 // Load the adjustment offset from the vtable. 00110 llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); 00111 00112 // Adjust our pointer. 00113 V = CGF.Builder.CreateInBoundsGEP(V, Offset); 00114 } 00115 00116 // Cast back to the original type. 00117 return CGF.Builder.CreateBitCast(V, Ptr->getType()); 00118 } 00119 00120 static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, 00121 const ThunkInfo &Thunk, llvm::Function *Fn) { 00122 CGM.setGlobalVisibility(Fn, MD); 00123 00124 if (!CGM.getCodeGenOpts().HiddenWeakVTables) 00125 return; 00126 00127 // If the thunk has weak/linkonce linkage, but the function must be 00128 // emitted in every translation unit that references it, then we can 00129 // emit its thunks with hidden visibility, since its thunks must be 00130 // emitted when the function is. 00131 00132 // This follows CodeGenModule::setTypeVisibility; see the comments 00133 // there for explanation. 00134 00135 if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage && 00136 Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) || 00137 Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility) 00138 return; 00139 00140 if (MD->getExplicitVisibility()) 00141 return; 00142 00143 switch (MD->getTemplateSpecializationKind()) { 00144 case TSK_ExplicitInstantiationDefinition: 00145 case TSK_ExplicitInstantiationDeclaration: 00146 return; 00147 00148 case TSK_Undeclared: 00149 break; 00150 00151 case TSK_ExplicitSpecialization: 00152 case TSK_ImplicitInstantiation: 00153 if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables) 00154 return; 00155 break; 00156 } 00157 00158 // If there's an explicit definition, and that definition is 00159 // out-of-line, then we can't assume that all users will have a 00160 // definition to emit. 00161 const FunctionDecl *Def = 0; 00162 if (MD->hasBody(Def) && Def->isOutOfLine()) 00163 return; 00164 00165 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); 00166 } 00167 00168 #ifndef NDEBUG 00169 static bool similar(const ABIArgInfo &infoL, CanQualType typeL, 00170 const ABIArgInfo &infoR, CanQualType typeR) { 00171 return (infoL.getKind() == infoR.getKind() && 00172 (typeL == typeR || 00173 (isa<PointerType>(typeL) && isa<PointerType>(typeR)) || 00174 (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR)))); 00175 } 00176 #endif 00177 00178 static RValue PerformReturnAdjustment(CodeGenFunction &CGF, 00179 QualType ResultType, RValue RV, 00180 const ThunkInfo &Thunk) { 00181 // Emit the return adjustment. 00182 bool NullCheckValue = !ResultType->isReferenceType(); 00183 00184 llvm::BasicBlock *AdjustNull = 0; 00185 llvm::BasicBlock *AdjustNotNull = 0; 00186 llvm::BasicBlock *AdjustEnd = 0; 00187 00188 llvm::Value *ReturnValue = RV.getScalarVal(); 00189 00190 if (NullCheckValue) { 00191 AdjustNull = CGF.createBasicBlock("adjust.null"); 00192 AdjustNotNull = CGF.createBasicBlock("adjust.notnull"); 00193 AdjustEnd = CGF.createBasicBlock("adjust.end"); 00194 00195 llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue); 00196 CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull); 00197 CGF.EmitBlock(AdjustNotNull); 00198 } 00199 00200 ReturnValue = PerformTypeAdjustment(CGF, ReturnValue, 00201 Thunk.Return.NonVirtual, 00202 Thunk.Return.VBaseOffsetOffset); 00203 00204 if (NullCheckValue) { 00205 CGF.Builder.CreateBr(AdjustEnd); 00206 CGF.EmitBlock(AdjustNull); 00207 CGF.Builder.CreateBr(AdjustEnd); 00208 CGF.EmitBlock(AdjustEnd); 00209 00210 llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2); 00211 PHI->addIncoming(ReturnValue, AdjustNotNull); 00212 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), 00213 AdjustNull); 00214 ReturnValue = PHI; 00215 } 00216 00217 return RValue::get(ReturnValue); 00218 } 00219 00220 // This function does roughly the same thing as GenerateThunk, but in a 00221 // very different way, so that va_start and va_end work correctly. 00222 // FIXME: This function assumes "this" is the first non-sret LLVM argument of 00223 // a function, and that there is an alloca built in the entry block 00224 // for all accesses to "this". 00225 // FIXME: This function assumes there is only one "ret" statement per function. 00226 // FIXME: Cloning isn't correct in the presence of indirect goto! 00227 // FIXME: This implementation of thunks bloats codesize by duplicating the 00228 // function definition. There are alternatives: 00229 // 1. Add some sort of stub support to LLVM for cases where we can 00230 // do a this adjustment, then a sibcall. 00231 // 2. We could transform the definition to take a va_list instead of an 00232 // actual variable argument list, then have the thunks (including a 00233 // no-op thunk for the regular definition) call va_start/va_end. 00234 // There's a bit of per-call overhead for this solution, but it's 00235 // better for codesize if the definition is long. 00236 void CodeGenFunction::GenerateVarArgsThunk( 00237 llvm::Function *Fn, 00238 const CGFunctionInfo &FnInfo, 00239 GlobalDecl GD, const ThunkInfo &Thunk) { 00240 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 00241 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 00242 QualType ResultType = FPT->getResultType(); 00243 00244 // Get the original function 00245 assert(FnInfo.isVariadic()); 00246 llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo); 00247 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); 00248 llvm::Function *BaseFn = cast<llvm::Function>(Callee); 00249 00250 // Clone to thunk. 00251 llvm::Function *NewFn = llvm::CloneFunction(BaseFn); 00252 CGM.getModule().getFunctionList().push_back(NewFn); 00253 Fn->replaceAllUsesWith(NewFn); 00254 NewFn->takeName(Fn); 00255 Fn->eraseFromParent(); 00256 Fn = NewFn; 00257 00258 // "Initialize" CGF (minimally). 00259 CurFn = Fn; 00260 00261 // Get the "this" value 00262 llvm::Function::arg_iterator AI = Fn->arg_begin(); 00263 if (CGM.ReturnTypeUsesSRet(FnInfo)) 00264 ++AI; 00265 00266 // Find the first store of "this", which will be to the alloca associated 00267 // with "this". 00268 llvm::Value *ThisPtr = &*AI; 00269 llvm::BasicBlock *EntryBB = Fn->begin(); 00270 llvm::Instruction *ThisStore = 0; 00271 for (llvm::BasicBlock::iterator I = EntryBB->begin(), E = EntryBB->end(); 00272 I != E; I++) { 00273 if (isa<llvm::StoreInst>(I) && I->getOperand(0) == ThisPtr) { 00274 ThisStore = cast<llvm::StoreInst>(I); 00275 break; 00276 } 00277 } 00278 assert(ThisStore && "Store of this should be in entry block?"); 00279 // Adjust "this", if necessary. 00280 Builder.SetInsertPoint(ThisStore); 00281 llvm::Value *AdjustedThisPtr = 00282 PerformTypeAdjustment(*this, ThisPtr, 00283 Thunk.This.NonVirtual, 00284 Thunk.This.VCallOffsetOffset); 00285 ThisStore->setOperand(0, AdjustedThisPtr); 00286 00287 if (!Thunk.Return.isEmpty()) { 00288 // Fix up the returned value, if necessary. 00289 for (llvm::Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++) { 00290 llvm::Instruction *T = I->getTerminator(); 00291 if (isa<llvm::ReturnInst>(T)) { 00292 RValue RV = RValue::get(T->getOperand(0)); 00293 T->eraseFromParent(); 00294 Builder.SetInsertPoint(&*I); 00295 RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk); 00296 Builder.CreateRet(RV.getScalarVal()); 00297 break; 00298 } 00299 } 00300 } 00301 } 00302 00303 void CodeGenFunction::GenerateThunk(llvm::Function *Fn, 00304 const CGFunctionInfo &FnInfo, 00305 GlobalDecl GD, const ThunkInfo &Thunk) { 00306 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 00307 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 00308 QualType ResultType = FPT->getResultType(); 00309 QualType ThisType = MD->getThisType(getContext()); 00310 00311 FunctionArgList FunctionArgs; 00312 00313 // FIXME: It would be nice if more of this code could be shared with 00314 // CodeGenFunction::GenerateCode. 00315 00316 // Create the implicit 'this' parameter declaration. 00317 CurGD = GD; 00318 CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs); 00319 00320 // Add the rest of the parameters. 00321 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 00322 E = MD->param_end(); I != E; ++I) { 00323 ParmVarDecl *Param = *I; 00324 00325 FunctionArgs.push_back(Param); 00326 } 00327 00328 StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs, 00329 SourceLocation()); 00330 00331 CGM.getCXXABI().EmitInstanceFunctionProlog(*this); 00332 CXXThisValue = CXXABIThisValue; 00333 00334 // Adjust the 'this' pointer if necessary. 00335 llvm::Value *AdjustedThisPtr = 00336 PerformTypeAdjustment(*this, LoadCXXThis(), 00337 Thunk.This.NonVirtual, 00338 Thunk.This.VCallOffsetOffset); 00339 00340 CallArgList CallArgs; 00341 00342 // Add our adjusted 'this' pointer. 00343 CallArgs.add(RValue::get(AdjustedThisPtr), ThisType); 00344 00345 // Add the rest of the parameters. 00346 for (FunctionDecl::param_const_iterator I = MD->param_begin(), 00347 E = MD->param_end(); I != E; ++I) { 00348 ParmVarDecl *param = *I; 00349 EmitDelegateCallArg(CallArgs, param); 00350 } 00351 00352 // Get our callee. 00353 llvm::Type *Ty = 00354 CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD)); 00355 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); 00356 00357 #ifndef NDEBUG 00358 const CGFunctionInfo &CallFnInfo = 00359 CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(), 00360 RequiredArgs::forPrototypePlus(FPT, 1)); 00361 assert(CallFnInfo.getRegParm() == FnInfo.getRegParm() && 00362 CallFnInfo.isNoReturn() == FnInfo.isNoReturn() && 00363 CallFnInfo.getCallingConvention() == FnInfo.getCallingConvention()); 00364 assert(similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), 00365 FnInfo.getReturnInfo(), FnInfo.getReturnType())); 00366 assert(CallFnInfo.arg_size() == FnInfo.arg_size()); 00367 for (unsigned i = 0, e = FnInfo.arg_size(); i != e; ++i) 00368 assert(similar(CallFnInfo.arg_begin()[i].info, 00369 CallFnInfo.arg_begin()[i].type, 00370 FnInfo.arg_begin()[i].info, FnInfo.arg_begin()[i].type)); 00371 #endif 00372 00373 // Determine whether we have a return value slot to use. 00374 ReturnValueSlot Slot; 00375 if (!ResultType->isVoidType() && 00376 FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 00377 hasAggregateLLVMType(CurFnInfo->getReturnType())) 00378 Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified()); 00379 00380 // Now emit our call. 00381 RValue RV = EmitCall(FnInfo, Callee, Slot, CallArgs, MD); 00382 00383 if (!Thunk.Return.isEmpty()) 00384 RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk); 00385 00386 if (!ResultType->isVoidType() && Slot.isNull()) 00387 CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType); 00388 00389 FinishFunction(); 00390 00391 // Set the right linkage. 00392 CGM.setFunctionLinkage(MD, Fn); 00393 00394 // Set the right visibility. 00395 setThunkVisibility(CGM, MD, Thunk, Fn); 00396 } 00397 00398 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, 00399 bool UseAvailableExternallyLinkage) 00400 { 00401 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD); 00402 00403 // FIXME: re-use FnInfo in this computation. 00404 llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk); 00405 00406 // Strip off a bitcast if we got one back. 00407 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) { 00408 assert(CE->getOpcode() == llvm::Instruction::BitCast); 00409 Entry = CE->getOperand(0); 00410 } 00411 00412 // There's already a declaration with the same name, check if it has the same 00413 // type or if we need to replace it. 00414 if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != 00415 CGM.getTypes().GetFunctionTypeForVTable(GD)) { 00416 llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry); 00417 00418 // If the types mismatch then we have to rewrite the definition. 00419 assert(OldThunkFn->isDeclaration() && 00420 "Shouldn't replace non-declaration"); 00421 00422 // Remove the name from the old thunk function and get a new thunk. 00423 OldThunkFn->setName(StringRef()); 00424 Entry = CGM.GetAddrOfThunk(GD, Thunk); 00425 00426 // If needed, replace the old thunk with a bitcast. 00427 if (!OldThunkFn->use_empty()) { 00428 llvm::Constant *NewPtrForOldDecl = 00429 llvm::ConstantExpr::getBitCast(Entry, OldThunkFn->getType()); 00430 OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl); 00431 } 00432 00433 // Remove the old thunk. 00434 OldThunkFn->eraseFromParent(); 00435 } 00436 00437 llvm::Function *ThunkFn = cast<llvm::Function>(Entry); 00438 00439 if (!ThunkFn->isDeclaration()) { 00440 if (UseAvailableExternallyLinkage) { 00441 // There is already a thunk emitted for this function, do nothing. 00442 return; 00443 } 00444 00445 // If a function has a body, it should have available_externally linkage. 00446 assert(ThunkFn->hasAvailableExternallyLinkage() && 00447 "Function should have available_externally linkage!"); 00448 00449 // Change the linkage. 00450 CGM.setFunctionLinkage(cast<CXXMethodDecl>(GD.getDecl()), ThunkFn); 00451 return; 00452 } 00453 00454 if (ThunkFn->isVarArg()) { 00455 // Varargs thunks are special; we can't just generate a call because 00456 // we can't copy the varargs. Our implementation is rather 00457 // expensive/sucky at the moment, so don't generate the thunk unless 00458 // we have to. 00459 // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly. 00460 if (!UseAvailableExternallyLinkage) 00461 CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk); 00462 } else { 00463 // Normal thunk body generation. 00464 CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk); 00465 } 00466 00467 if (UseAvailableExternallyLinkage) 00468 ThunkFn->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); 00469 } 00470 00471 void CodeGenVTables::MaybeEmitThunkAvailableExternally(GlobalDecl GD, 00472 const ThunkInfo &Thunk) { 00473 // We only want to do this when building with optimizations. 00474 if (!CGM.getCodeGenOpts().OptimizationLevel) 00475 return; 00476 00477 // We can't emit thunks for member functions with incomplete types. 00478 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 00479 if (!CGM.getTypes().isFuncTypeConvertible( 00480 cast<FunctionType>(MD->getType().getTypePtr()))) 00481 return; 00482 00483 EmitThunk(GD, Thunk, /*UseAvailableExternallyLinkage=*/true); 00484 } 00485 00486 void CodeGenVTables::EmitThunks(GlobalDecl GD) 00487 { 00488 const CXXMethodDecl *MD = 00489 cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl(); 00490 00491 // We don't need to generate thunks for the base destructor. 00492 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 00493 return; 00494 00495 const VTableContext::ThunkInfoVectorTy *ThunkInfoVector = 00496 VTContext.getThunkInfo(MD); 00497 if (!ThunkInfoVector) 00498 return; 00499 00500 for (unsigned I = 0, E = ThunkInfoVector->size(); I != E; ++I) 00501 EmitThunk(GD, (*ThunkInfoVector)[I], 00502 /*UseAvailableExternallyLinkage=*/false); 00503 } 00504 00505 llvm::Constant * 00506 CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, 00507 const VTableComponent *Components, 00508 unsigned NumComponents, 00509 const VTableLayout::VTableThunkTy *VTableThunks, 00510 unsigned NumVTableThunks) { 00511 SmallVector<llvm::Constant *, 64> Inits; 00512 00513 llvm::Type *Int8PtrTy = CGM.Int8PtrTy; 00514 00515 llvm::Type *PtrDiffTy = 00516 CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 00517 00518 QualType ClassType = CGM.getContext().getTagDeclType(RD); 00519 llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType); 00520 00521 unsigned NextVTableThunkIndex = 0; 00522 00523 llvm::Constant* PureVirtualFn = 0; 00524 00525 for (unsigned I = 0; I != NumComponents; ++I) { 00526 VTableComponent Component = Components[I]; 00527 00528 llvm::Constant *Init = 0; 00529 00530 switch (Component.getKind()) { 00531 case VTableComponent::CK_VCallOffset: 00532 Init = llvm::ConstantInt::get(PtrDiffTy, 00533 Component.getVCallOffset().getQuantity()); 00534 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 00535 break; 00536 case VTableComponent::CK_VBaseOffset: 00537 Init = llvm::ConstantInt::get(PtrDiffTy, 00538 Component.getVBaseOffset().getQuantity()); 00539 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 00540 break; 00541 case VTableComponent::CK_OffsetToTop: 00542 Init = llvm::ConstantInt::get(PtrDiffTy, 00543 Component.getOffsetToTop().getQuantity()); 00544 Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); 00545 break; 00546 case VTableComponent::CK_RTTI: 00547 Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy); 00548 break; 00549 case VTableComponent::CK_FunctionPointer: 00550 case VTableComponent::CK_CompleteDtorPointer: 00551 case VTableComponent::CK_DeletingDtorPointer: { 00552 GlobalDecl GD; 00553 00554 // Get the right global decl. 00555 switch (Component.getKind()) { 00556 default: 00557 llvm_unreachable("Unexpected vtable component kind"); 00558 case VTableComponent::CK_FunctionPointer: 00559 GD = Component.getFunctionDecl(); 00560 break; 00561 case VTableComponent::CK_CompleteDtorPointer: 00562 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete); 00563 break; 00564 case VTableComponent::CK_DeletingDtorPointer: 00565 GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting); 00566 break; 00567 } 00568 00569 if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { 00570 // We have a pure virtual member function. 00571 if (!PureVirtualFn) { 00572 llvm::FunctionType *Ty = 00573 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); 00574 PureVirtualFn = 00575 CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual"); 00576 PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, 00577 Int8PtrTy); 00578 } 00579 00580 Init = PureVirtualFn; 00581 } else { 00582 // Check if we should use a thunk. 00583 if (NextVTableThunkIndex < NumVTableThunks && 00584 VTableThunks[NextVTableThunkIndex].first == I) { 00585 const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; 00586 00587 MaybeEmitThunkAvailableExternally(GD, Thunk); 00588 Init = CGM.GetAddrOfThunk(GD, Thunk); 00589 00590 NextVTableThunkIndex++; 00591 } else { 00592 llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD); 00593 00594 Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); 00595 } 00596 00597 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); 00598 } 00599 break; 00600 } 00601 00602 case VTableComponent::CK_UnusedFunctionPointer: 00603 Init = llvm::ConstantExpr::getNullValue(Int8PtrTy); 00604 break; 00605 }; 00606 00607 Inits.push_back(Init); 00608 } 00609 00610 llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents); 00611 return llvm::ConstantArray::get(ArrayType, Inits); 00612 } 00613 00614 llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { 00615 llvm::GlobalVariable *&VTable = VTables[RD]; 00616 if (VTable) 00617 return VTable; 00618 00619 // We may need to generate a definition for this vtable. 00620 if (ShouldEmitVTableInThisTU(RD)) 00621 CGM.DeferredVTables.push_back(RD); 00622 00623 SmallString<256> OutName; 00624 llvm::raw_svector_ostream Out(OutName); 00625 CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out); 00626 Out.flush(); 00627 StringRef Name = OutName.str(); 00628 00629 llvm::ArrayType *ArrayType = 00630 llvm::ArrayType::get(CGM.Int8PtrTy, 00631 VTContext.getVTableLayout(RD).getNumVTableComponents()); 00632 00633 VTable = 00634 CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 00635 llvm::GlobalValue::ExternalLinkage); 00636 VTable->setUnnamedAddr(true); 00637 return VTable; 00638 } 00639 00640 void 00641 CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, 00642 llvm::GlobalVariable::LinkageTypes Linkage, 00643 const CXXRecordDecl *RD) { 00644 const VTableLayout &VTLayout = VTContext.getVTableLayout(RD); 00645 00646 // Create and set the initializer. 00647 llvm::Constant *Init = 00648 CreateVTableInitializer(RD, 00649 VTLayout.vtable_component_begin(), 00650 VTLayout.getNumVTableComponents(), 00651 VTLayout.vtable_thunk_begin(), 00652 VTLayout.getNumVTableThunks()); 00653 VTable->setInitializer(Init); 00654 00655 // Set the correct linkage. 00656 VTable->setLinkage(Linkage); 00657 00658 // Set the right visibility. 00659 CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); 00660 } 00661 00662 llvm::GlobalVariable * 00663 CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, 00664 const BaseSubobject &Base, 00665 bool BaseIsVirtual, 00666 llvm::GlobalVariable::LinkageTypes Linkage, 00667 VTableAddressPointsMapTy& AddressPoints) { 00668 OwningPtr<VTableLayout> VTLayout( 00669 VTContext.createConstructionVTableLayout(Base.getBase(), 00670 Base.getBaseOffset(), 00671 BaseIsVirtual, RD)); 00672 00673 // Add the address points. 00674 AddressPoints = VTLayout->getAddressPoints(); 00675 00676 // Get the mangled construction vtable name. 00677 SmallString<256> OutName; 00678 llvm::raw_svector_ostream Out(OutName); 00679 CGM.getCXXABI().getMangleContext(). 00680 mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(), Base.getBase(), 00681 Out); 00682 Out.flush(); 00683 StringRef Name = OutName.str(); 00684 00685 llvm::ArrayType *ArrayType = 00686 llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->getNumVTableComponents()); 00687 00688 // Create the variable that will hold the construction vtable. 00689 llvm::GlobalVariable *VTable = 00690 CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage); 00691 CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForConstructionVTable); 00692 00693 // V-tables are always unnamed_addr. 00694 VTable->setUnnamedAddr(true); 00695 00696 // Create and set the initializer. 00697 llvm::Constant *Init = 00698 CreateVTableInitializer(Base.getBase(), 00699 VTLayout->vtable_component_begin(), 00700 VTLayout->getNumVTableComponents(), 00701 VTLayout->vtable_thunk_begin(), 00702 VTLayout->getNumVTableThunks()); 00703 VTable->setInitializer(Init); 00704 00705 return VTable; 00706 } 00707 00708 void 00709 CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, 00710 const CXXRecordDecl *RD) { 00711 llvm::GlobalVariable *VTable = GetAddrOfVTable(RD); 00712 if (VTable->hasInitializer()) 00713 return; 00714 00715 EmitVTableDefinition(VTable, Linkage, RD); 00716 00717 if (RD->getNumVBases()) { 00718 llvm::GlobalVariable *VTT = GetAddrOfVTT(RD); 00719 EmitVTTDefinition(VTT, Linkage, RD); 00720 } 00721 00722 // If this is the magic class __cxxabiv1::__fundamental_type_info, 00723 // we will emit the typeinfo for the fundamental types. This is the 00724 // same behaviour as GCC. 00725 const DeclContext *DC = RD->getDeclContext(); 00726 if (RD->getIdentifier() && 00727 RD->getIdentifier()->isStr("__fundamental_type_info") && 00728 isa<NamespaceDecl>(DC) && 00729 cast<NamespaceDecl>(DC)->getIdentifier() && 00730 cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && 00731 DC->getParent()->isTranslationUnit()) 00732 CGM.EmitFundamentalRTTIDescriptors(); 00733 }