145 // Derive the type for the alias. 146 const llvm::PointerType *AliasType 147 = getTypes().GetFunctionType(AliasDecl)->getPointerTo(); 148 149 // Find the referrent. Some aliases might require a bitcast, in 150 // which case the caller is responsible for ensuring the soundness 151 // of these semantics. 152 llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); 153 llvm::Constant *Aliasee = Ref; 154 if (Ref->getType() != AliasType) 155 Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType); 156 157 // Create the alias with no name. 158 llvm::GlobalAlias *Alias = 159 new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule()); 160 161 // Switch any previous uses to the alias. 162 const char *MangledName = getMangledName(AliasDecl); 163 llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; 164 if (Entry) { 165 assert(Entry->isDeclaration() && "definition already exists for alias"); 166 assert(Entry->getType() == AliasType && 167 "declaration exists with different type"); 168 Entry->replaceAllUsesWith(Alias); 169 Entry->eraseFromParent(); 170 } 171 Entry = Alias; 172 173 // Finally, set up the alias with its proper name and attributes. 174 Alias->setName(MangledName); 175 SetCommonAttributes(AliasDecl.getDecl(), Alias); 176 177 return false; 178} 179 180void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 181 // The constructor used for constructing this as a complete class; 182 // constucts the virtual bases, then calls the base constructor. 183 EmitGlobal(GlobalDecl(D, Ctor_Complete)); 184 185 // The constructor used for constructing this as a base class; 186 // ignores virtual bases. 187 EmitGlobal(GlobalDecl(D, Ctor_Base)); 188} 189 190void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 191 CXXCtorType Type) { 192 // The complete constructor is equivalent to the base constructor 193 // for classes with no virtual bases. Try to emit it as an alias. 194 if (Type == Ctor_Complete && 195 !D->getParent()->getNumVBases() && 196 !TryEmitDefinitionAsAlias(GlobalDecl(D, Ctor_Complete), 197 GlobalDecl(D, Ctor_Base))) 198 return; 199 200 llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type)); 201 202 CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn); 203 204 SetFunctionDefinitionAttributes(D, Fn); 205 SetLLVMFunctionAttributesForDefinition(D, Fn); 206} 207 208llvm::GlobalValue * 209CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 210 CXXCtorType Type) { 211 const char *Name = getMangledCXXCtorName(D, Type); 212 if (llvm::GlobalValue *V = GlobalDeclMap[Name]) 213 return V; 214 215 const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 216 const llvm::FunctionType *FTy = 217 getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), 218 FPT->isVariadic()); 219 return cast<llvm::Function>( 220 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 221} 222 223const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 224 CXXCtorType Type) { 225 llvm::SmallString<256> Name; 226 getMangleContext().mangleCXXCtor(D, Type, Name); 227 228 Name += '\0'; 229 return UniqueMangledName(Name.begin(), Name.end()); 230} 231 232void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 233 // The destructor in a virtual table is always a 'deleting' 234 // destructor, which calls the complete destructor and then uses the 235 // appropriate operator delete. 236 if (D->isVirtual()) 237 EmitGlobal(GlobalDecl(D, Dtor_Deleting)); 238 239 // The destructor used for destructing this as a most-derived class; 240 // call the base destructor and then destructs any virtual bases. 241 EmitGlobal(GlobalDecl(D, Dtor_Complete)); 242 243 // The destructor used for destructing this as a base class; ignores 244 // virtual bases. 245 EmitGlobal(GlobalDecl(D, Dtor_Base)); 246} 247 248void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 249 CXXDtorType Type) { 250 // The complete destructor is equivalent to the base destructor for 251 // classes with no virtual bases, so try to emit it as an alias. 252 if (Type == Dtor_Complete && 253 !D->getParent()->getNumVBases() && 254 !TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Complete), 255 GlobalDecl(D, Dtor_Base))) 256 return; 257 258 // The base destructor is equivalent to the base destructor of its 259 // base class if there is exactly one non-virtual base class with a 260 // non-trivial destructor, there are no fields with a non-trivial 261 // destructor, and the body of the destructor is trivial. 262 if (Type == Dtor_Base && !TryEmitBaseDestructorAsAlias(D)) 263 return; 264 265 llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type)); 266 267 CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn); 268 269 SetFunctionDefinitionAttributes(D, Fn); 270 SetLLVMFunctionAttributesForDefinition(D, Fn); 271} 272 273llvm::GlobalValue * 274CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 275 CXXDtorType Type) { 276 const char *Name = getMangledCXXDtorName(D, Type); 277 if (llvm::GlobalValue *V = GlobalDeclMap[Name]) 278 return V; 279 280 const llvm::FunctionType *FTy = 281 getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false); 282 283 return cast<llvm::Function>( 284 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 285} 286 287const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 288 CXXDtorType Type) { 289 llvm::SmallString<256> Name; 290 getMangleContext().mangleCXXDtor(D, Type, Name); 291 292 Name += '\0'; 293 return UniqueMangledName(Name.begin(), Name.end()); 294} 295 296llvm::Constant * 297CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, 298 bool Extern, 299 const ThunkAdjustment &ThisAdjustment) { 300 return GenerateCovariantThunk(Fn, GD, Extern, 301 CovariantThunkAdjustment(ThisAdjustment, 302 ThunkAdjustment())); 303} 304 305llvm::Value * 306CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, 307 const ThunkAdjustment &Adjustment) { 308 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 309 310 const llvm::Type *OrigTy = V->getType(); 311 if (Adjustment.NonVirtual) { 312 // Do the non-virtual adjustment 313 V = Builder.CreateBitCast(V, Int8PtrTy); 314 V = Builder.CreateConstInBoundsGEP1_64(V, Adjustment.NonVirtual); 315 V = Builder.CreateBitCast(V, OrigTy); 316 } 317 318 if (!Adjustment.Virtual) 319 return V; 320 321 assert(Adjustment.Virtual % (LLVMPointerWidth / 8) == 0 && 322 "vtable entry unaligned"); 323 324 // Do the virtual this adjustment 325 const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); 326 const llvm::Type *PtrDiffPtrTy = PtrDiffTy->getPointerTo(); 327 328 llvm::Value *ThisVal = Builder.CreateBitCast(V, Int8PtrTy); 329 V = Builder.CreateBitCast(V, PtrDiffPtrTy->getPointerTo()); 330 V = Builder.CreateLoad(V, "vtable"); 331 332 llvm::Value *VTablePtr = V; 333 uint64_t VirtualAdjustment = Adjustment.Virtual / (LLVMPointerWidth / 8); 334 V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 335 V = Builder.CreateLoad(V); 336 V = Builder.CreateGEP(ThisVal, V); 337 338 return Builder.CreateBitCast(V, OrigTy); 339} 340 341llvm::Constant * 342CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn, 343 GlobalDecl GD, bool Extern, 344 const CovariantThunkAdjustment &Adjustment) { 345 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 346 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 347 QualType ResultType = FPT->getResultType(); 348 349 FunctionArgList Args; 350 ImplicitParamDecl *ThisDecl = 351 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 352 MD->getThisType(getContext())); 353 Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType())); 354 for (FunctionDecl::param_const_iterator i = MD->param_begin(), 355 e = MD->param_end(); 356 i != e; ++i) { 357 ParmVarDecl *D = *i; 358 Args.push_back(std::make_pair(D, D->getType())); 359 } 360 IdentifierInfo *II 361 = &CGM.getContext().Idents.get("__thunk_named_foo_"); 362 FunctionDecl *FD = FunctionDecl::Create(getContext(), 363 getContext().getTranslationUnitDecl(), 364 SourceLocation(), II, ResultType, 0, 365 Extern 366 ? FunctionDecl::Extern 367 : FunctionDecl::Static, 368 false, true); 369 StartFunction(FD, ResultType, Fn, Args, SourceLocation()); 370 371 // generate body 372 const llvm::Type *Ty = 373 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 374 FPT->isVariadic()); 375 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); 376 377 CallArgList CallArgs; 378 379 bool ShouldAdjustReturnPointer = true; 380 QualType ArgType = MD->getThisType(getContext()); 381 llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this"); 382 if (!Adjustment.ThisAdjustment.isEmpty()) { 383 // Do the this adjustment. 384 const llvm::Type *OrigTy = Callee->getType(); 385 Arg = DynamicTypeAdjust(Arg, Adjustment.ThisAdjustment); 386 387 if (!Adjustment.ReturnAdjustment.isEmpty()) { 388 const CovariantThunkAdjustment &ReturnAdjustment = 389 CovariantThunkAdjustment(ThunkAdjustment(), 390 Adjustment.ReturnAdjustment); 391 392 Callee = CGM.BuildCovariantThunk(GD, Extern, ReturnAdjustment); 393 394 Callee = Builder.CreateBitCast(Callee, OrigTy); 395 ShouldAdjustReturnPointer = false; 396 } 397 } 398 399 CallArgs.push_back(std::make_pair(RValue::get(Arg), ArgType)); 400 401 for (FunctionDecl::param_const_iterator i = MD->param_begin(), 402 e = MD->param_end(); 403 i != e; ++i) { 404 ParmVarDecl *D = *i; 405 QualType ArgType = D->getType(); 406 407 // llvm::Value *Arg = CGF.GetAddrOfLocalVar(Dst); 408 Expr *Arg = new (getContext()) DeclRefExpr(D, ArgType.getNonReferenceType(), 409 SourceLocation()); 410 CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType)); 411 } 412 413 RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs, 414 FPT->getCallConv(), 415 FPT->getNoReturnAttr()), 416 Callee, ReturnValueSlot(), CallArgs, MD); 417 if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) { 418 bool CanBeZero = !(ResultType->isReferenceType() 419 // FIXME: attr nonnull can't be zero either 420 /* || ResultType->hasAttr<NonNullAttr>() */ ); 421 // Do the return result adjustment. 422 if (CanBeZero) { 423 llvm::BasicBlock *NonZeroBlock = createBasicBlock(); 424 llvm::BasicBlock *ZeroBlock = createBasicBlock(); 425 llvm::BasicBlock *ContBlock = createBasicBlock(); 426 427 const llvm::Type *Ty = RV.getScalarVal()->getType(); 428 llvm::Value *Zero = llvm::Constant::getNullValue(Ty); 429 Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero), 430 NonZeroBlock, ZeroBlock); 431 EmitBlock(NonZeroBlock); 432 llvm::Value *NZ = 433 DynamicTypeAdjust(RV.getScalarVal(), Adjustment.ReturnAdjustment); 434 EmitBranch(ContBlock); 435 EmitBlock(ZeroBlock); 436 llvm::Value *Z = RV.getScalarVal(); 437 EmitBlock(ContBlock); 438 llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty); 439 RVOrZero->reserveOperandSpace(2); 440 RVOrZero->addIncoming(NZ, NonZeroBlock); 441 RVOrZero->addIncoming(Z, ZeroBlock); 442 RV = RValue::get(RVOrZero); 443 } else 444 RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), 445 Adjustment.ReturnAdjustment)); 446 } 447 448 if (!ResultType->isVoidType()) 449 EmitReturnOfRValue(RV, ResultType); 450 451 FinishFunction(); 452 return Fn; 453} 454 455llvm::Constant * 456CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 457 const ThunkAdjustment &ThisAdjustment) { 458 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 459 460 // Compute mangled name 461 llvm::SmallString<256> OutName; 462 if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) 463 getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), ThisAdjustment, 464 OutName); 465 else 466 getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); 467 OutName += '\0'; 468 const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); 469 470 // Get function for mangled name 471 const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); 472 return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); 473} 474 475llvm::Constant * 476CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, 477 const CovariantThunkAdjustment &Adjustment) { 478 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 479 480 // Compute mangled name 481 llvm::SmallString<256> OutName; 482 getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); 483 OutName += '\0'; 484 const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); 485 486 // Get function for mangled name 487 const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); 488 return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); 489} 490 491void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) { 492 CGVtableInfo::AdjustmentVectorTy *AdjPtr = getVtableInfo().getAdjustments(GD); 493 if (!AdjPtr) 494 return; 495 CGVtableInfo::AdjustmentVectorTy &Adj = *AdjPtr; 496 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 497 for (unsigned i = 0; i < Adj.size(); i++) { 498 GlobalDecl OGD = Adj[i].first; 499 const CXXMethodDecl *OMD = cast<CXXMethodDecl>(OGD.getDecl()); 500 QualType nc_oret = OMD->getType()->getAs<FunctionType>()->getResultType(); 501 CanQualType oret = getContext().getCanonicalType(nc_oret); 502 QualType nc_ret = MD->getType()->getAs<FunctionType>()->getResultType(); 503 CanQualType ret = getContext().getCanonicalType(nc_ret); 504 ThunkAdjustment ReturnAdjustment; 505 if (oret != ret) { 506 QualType qD = nc_ret->getPointeeType(); 507 QualType qB = nc_oret->getPointeeType(); 508 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); 509 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); 510 ReturnAdjustment = ComputeThunkAdjustment(D, B); 511 } 512 ThunkAdjustment ThisAdjustment = Adj[i].second; 513 bool Extern = !cast<CXXRecordDecl>(OMD->getDeclContext())->isInAnonymousNamespace(); 514 if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) { 515 CovariantThunkAdjustment CoAdj(ThisAdjustment, ReturnAdjustment); 516 llvm::Constant *FnConst; 517 if (!ReturnAdjustment.isEmpty()) 518 FnConst = GetAddrOfCovariantThunk(GD, CoAdj); 519 else 520 FnConst = GetAddrOfThunk(GD, ThisAdjustment); 521 if (!isa<llvm::Function>(FnConst)) { 522 llvm::Constant *SubExpr = 523 cast<llvm::ConstantExpr>(FnConst)->getOperand(0); 524 llvm::Function *OldFn = cast<llvm::Function>(SubExpr); 525 std::string Name = OldFn->getNameStr(); 526 GlobalDeclMap.erase(UniqueMangledName(Name.data(), 527 Name.data() + Name.size() + 1)); 528 llvm::Constant *NewFnConst; 529 if (!ReturnAdjustment.isEmpty()) 530 NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj); 531 else 532 NewFnConst = GetAddrOfThunk(GD, ThisAdjustment); 533 llvm::Function *NewFn = cast<llvm::Function>(NewFnConst); 534 NewFn->takeName(OldFn); 535 llvm::Constant *NewPtrForOldDecl = 536 llvm::ConstantExpr::getBitCast(NewFn, OldFn->getType()); 537 OldFn->replaceAllUsesWith(NewPtrForOldDecl); 538 OldFn->eraseFromParent(); 539 FnConst = NewFn; 540 } 541 llvm::Function *Fn = cast<llvm::Function>(FnConst); 542 if (Fn->isDeclaration()) { 543 llvm::GlobalVariable::LinkageTypes linktype; 544 linktype = llvm::GlobalValue::WeakAnyLinkage; 545 if (!Extern) 546 linktype = llvm::GlobalValue::InternalLinkage; 547 Fn->setLinkage(linktype); 548 if (!Features.Exceptions && !Features.ObjCNonFragileABI) 549 Fn->addFnAttr(llvm::Attribute::NoUnwind); 550 Fn->setAlignment(2); 551 CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj); 552 } 553 } 554 } 555} 556 557llvm::Constant * 558CodeGenModule::BuildThunk(GlobalDecl GD, bool Extern, 559 const ThunkAdjustment &ThisAdjustment) { 560 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 561 llvm::SmallString<256> OutName; 562 if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(MD)) { 563 getMangleContext().mangleCXXDtorThunk(D, GD.getDtorType(), ThisAdjustment, 564 OutName); 565 } else 566 getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); 567 568 llvm::GlobalVariable::LinkageTypes linktype; 569 linktype = llvm::GlobalValue::WeakAnyLinkage; 570 if (!Extern) 571 linktype = llvm::GlobalValue::InternalLinkage; 572 llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 573 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 574 const llvm::FunctionType *FTy = 575 getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), 576 FPT->isVariadic()); 577 578 llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), 579 &getModule()); 580 CodeGenFunction(*this).GenerateThunk(Fn, GD, Extern, ThisAdjustment); 581 llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 582 return m; 583} 584 585llvm::Constant * 586CodeGenModule::BuildCovariantThunk(const GlobalDecl &GD, bool Extern, 587 const CovariantThunkAdjustment &Adjustment) { 588 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 589 llvm::SmallString<256> OutName; 590 getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); 591 llvm::GlobalVariable::LinkageTypes linktype; 592 linktype = llvm::GlobalValue::WeakAnyLinkage; 593 if (!Extern) 594 linktype = llvm::GlobalValue::InternalLinkage; 595 llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 596 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 597 const llvm::FunctionType *FTy = 598 getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), 599 FPT->isVariadic()); 600 601 llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), 602 &getModule()); 603 CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, Adjustment); 604 llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 605 return m; 606} 607 608static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex, 609 llvm::Value *This, const llvm::Type *Ty) { 610 Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); 611 612 llvm::Value *Vtable = CGF.Builder.CreateBitCast(This, Ty); 613 Vtable = CGF.Builder.CreateLoad(Vtable); 614 615 llvm::Value *VFuncPtr = 616 CGF.Builder.CreateConstInBoundsGEP1_64(Vtable, VtableIndex, "vfn"); 617 return CGF.Builder.CreateLoad(VFuncPtr); 618} 619 620llvm::Value * 621CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This, 622 const llvm::Type *Ty) { 623 MD = MD->getCanonicalDecl(); 624 uint64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD); 625 626 return ::BuildVirtualCall(*this, VtableIndex, This, Ty); 627} 628 629llvm::Value * 630CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 631 llvm::Value *&This, const llvm::Type *Ty) { 632 DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl()); 633 uint64_t VtableIndex = 634 CGM.getVtableInfo().getMethodVtableIndex(GlobalDecl(DD, Type)); 635 636 return ::BuildVirtualCall(*this, VtableIndex, This, Ty); 637}
| 151 // Derive the type for the alias. 152 const llvm::PointerType *AliasType 153 = getTypes().GetFunctionType(AliasDecl)->getPointerTo(); 154 155 // Find the referrent. Some aliases might require a bitcast, in 156 // which case the caller is responsible for ensuring the soundness 157 // of these semantics. 158 llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl)); 159 llvm::Constant *Aliasee = Ref; 160 if (Ref->getType() != AliasType) 161 Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType); 162 163 // Create the alias with no name. 164 llvm::GlobalAlias *Alias = 165 new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule()); 166 167 // Switch any previous uses to the alias. 168 const char *MangledName = getMangledName(AliasDecl); 169 llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; 170 if (Entry) { 171 assert(Entry->isDeclaration() && "definition already exists for alias"); 172 assert(Entry->getType() == AliasType && 173 "declaration exists with different type"); 174 Entry->replaceAllUsesWith(Alias); 175 Entry->eraseFromParent(); 176 } 177 Entry = Alias; 178 179 // Finally, set up the alias with its proper name and attributes. 180 Alias->setName(MangledName); 181 SetCommonAttributes(AliasDecl.getDecl(), Alias); 182 183 return false; 184} 185 186void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 187 // The constructor used for constructing this as a complete class; 188 // constucts the virtual bases, then calls the base constructor. 189 EmitGlobal(GlobalDecl(D, Ctor_Complete)); 190 191 // The constructor used for constructing this as a base class; 192 // ignores virtual bases. 193 EmitGlobal(GlobalDecl(D, Ctor_Base)); 194} 195 196void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 197 CXXCtorType Type) { 198 // The complete constructor is equivalent to the base constructor 199 // for classes with no virtual bases. Try to emit it as an alias. 200 if (Type == Ctor_Complete && 201 !D->getParent()->getNumVBases() && 202 !TryEmitDefinitionAsAlias(GlobalDecl(D, Ctor_Complete), 203 GlobalDecl(D, Ctor_Base))) 204 return; 205 206 llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type)); 207 208 CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn); 209 210 SetFunctionDefinitionAttributes(D, Fn); 211 SetLLVMFunctionAttributesForDefinition(D, Fn); 212} 213 214llvm::GlobalValue * 215CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 216 CXXCtorType Type) { 217 const char *Name = getMangledCXXCtorName(D, Type); 218 if (llvm::GlobalValue *V = GlobalDeclMap[Name]) 219 return V; 220 221 const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 222 const llvm::FunctionType *FTy = 223 getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), 224 FPT->isVariadic()); 225 return cast<llvm::Function>( 226 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 227} 228 229const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 230 CXXCtorType Type) { 231 llvm::SmallString<256> Name; 232 getMangleContext().mangleCXXCtor(D, Type, Name); 233 234 Name += '\0'; 235 return UniqueMangledName(Name.begin(), Name.end()); 236} 237 238void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 239 // The destructor in a virtual table is always a 'deleting' 240 // destructor, which calls the complete destructor and then uses the 241 // appropriate operator delete. 242 if (D->isVirtual()) 243 EmitGlobal(GlobalDecl(D, Dtor_Deleting)); 244 245 // The destructor used for destructing this as a most-derived class; 246 // call the base destructor and then destructs any virtual bases. 247 EmitGlobal(GlobalDecl(D, Dtor_Complete)); 248 249 // The destructor used for destructing this as a base class; ignores 250 // virtual bases. 251 EmitGlobal(GlobalDecl(D, Dtor_Base)); 252} 253 254void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 255 CXXDtorType Type) { 256 // The complete destructor is equivalent to the base destructor for 257 // classes with no virtual bases, so try to emit it as an alias. 258 if (Type == Dtor_Complete && 259 !D->getParent()->getNumVBases() && 260 !TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Complete), 261 GlobalDecl(D, Dtor_Base))) 262 return; 263 264 // The base destructor is equivalent to the base destructor of its 265 // base class if there is exactly one non-virtual base class with a 266 // non-trivial destructor, there are no fields with a non-trivial 267 // destructor, and the body of the destructor is trivial. 268 if (Type == Dtor_Base && !TryEmitBaseDestructorAsAlias(D)) 269 return; 270 271 llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type)); 272 273 CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn); 274 275 SetFunctionDefinitionAttributes(D, Fn); 276 SetLLVMFunctionAttributesForDefinition(D, Fn); 277} 278 279llvm::GlobalValue * 280CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 281 CXXDtorType Type) { 282 const char *Name = getMangledCXXDtorName(D, Type); 283 if (llvm::GlobalValue *V = GlobalDeclMap[Name]) 284 return V; 285 286 const llvm::FunctionType *FTy = 287 getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false); 288 289 return cast<llvm::Function>( 290 GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 291} 292 293const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 294 CXXDtorType Type) { 295 llvm::SmallString<256> Name; 296 getMangleContext().mangleCXXDtor(D, Type, Name); 297 298 Name += '\0'; 299 return UniqueMangledName(Name.begin(), Name.end()); 300} 301 302llvm::Constant * 303CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, 304 bool Extern, 305 const ThunkAdjustment &ThisAdjustment) { 306 return GenerateCovariantThunk(Fn, GD, Extern, 307 CovariantThunkAdjustment(ThisAdjustment, 308 ThunkAdjustment())); 309} 310 311llvm::Value * 312CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, 313 const ThunkAdjustment &Adjustment) { 314 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 315 316 const llvm::Type *OrigTy = V->getType(); 317 if (Adjustment.NonVirtual) { 318 // Do the non-virtual adjustment 319 V = Builder.CreateBitCast(V, Int8PtrTy); 320 V = Builder.CreateConstInBoundsGEP1_64(V, Adjustment.NonVirtual); 321 V = Builder.CreateBitCast(V, OrigTy); 322 } 323 324 if (!Adjustment.Virtual) 325 return V; 326 327 assert(Adjustment.Virtual % (LLVMPointerWidth / 8) == 0 && 328 "vtable entry unaligned"); 329 330 // Do the virtual this adjustment 331 const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); 332 const llvm::Type *PtrDiffPtrTy = PtrDiffTy->getPointerTo(); 333 334 llvm::Value *ThisVal = Builder.CreateBitCast(V, Int8PtrTy); 335 V = Builder.CreateBitCast(V, PtrDiffPtrTy->getPointerTo()); 336 V = Builder.CreateLoad(V, "vtable"); 337 338 llvm::Value *VTablePtr = V; 339 uint64_t VirtualAdjustment = Adjustment.Virtual / (LLVMPointerWidth / 8); 340 V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 341 V = Builder.CreateLoad(V); 342 V = Builder.CreateGEP(ThisVal, V); 343 344 return Builder.CreateBitCast(V, OrigTy); 345} 346 347llvm::Constant * 348CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn, 349 GlobalDecl GD, bool Extern, 350 const CovariantThunkAdjustment &Adjustment) { 351 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 352 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 353 QualType ResultType = FPT->getResultType(); 354 355 FunctionArgList Args; 356 ImplicitParamDecl *ThisDecl = 357 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 358 MD->getThisType(getContext())); 359 Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType())); 360 for (FunctionDecl::param_const_iterator i = MD->param_begin(), 361 e = MD->param_end(); 362 i != e; ++i) { 363 ParmVarDecl *D = *i; 364 Args.push_back(std::make_pair(D, D->getType())); 365 } 366 IdentifierInfo *II 367 = &CGM.getContext().Idents.get("__thunk_named_foo_"); 368 FunctionDecl *FD = FunctionDecl::Create(getContext(), 369 getContext().getTranslationUnitDecl(), 370 SourceLocation(), II, ResultType, 0, 371 Extern 372 ? FunctionDecl::Extern 373 : FunctionDecl::Static, 374 false, true); 375 StartFunction(FD, ResultType, Fn, Args, SourceLocation()); 376 377 // generate body 378 const llvm::Type *Ty = 379 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 380 FPT->isVariadic()); 381 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); 382 383 CallArgList CallArgs; 384 385 bool ShouldAdjustReturnPointer = true; 386 QualType ArgType = MD->getThisType(getContext()); 387 llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this"); 388 if (!Adjustment.ThisAdjustment.isEmpty()) { 389 // Do the this adjustment. 390 const llvm::Type *OrigTy = Callee->getType(); 391 Arg = DynamicTypeAdjust(Arg, Adjustment.ThisAdjustment); 392 393 if (!Adjustment.ReturnAdjustment.isEmpty()) { 394 const CovariantThunkAdjustment &ReturnAdjustment = 395 CovariantThunkAdjustment(ThunkAdjustment(), 396 Adjustment.ReturnAdjustment); 397 398 Callee = CGM.BuildCovariantThunk(GD, Extern, ReturnAdjustment); 399 400 Callee = Builder.CreateBitCast(Callee, OrigTy); 401 ShouldAdjustReturnPointer = false; 402 } 403 } 404 405 CallArgs.push_back(std::make_pair(RValue::get(Arg), ArgType)); 406 407 for (FunctionDecl::param_const_iterator i = MD->param_begin(), 408 e = MD->param_end(); 409 i != e; ++i) { 410 ParmVarDecl *D = *i; 411 QualType ArgType = D->getType(); 412 413 // llvm::Value *Arg = CGF.GetAddrOfLocalVar(Dst); 414 Expr *Arg = new (getContext()) DeclRefExpr(D, ArgType.getNonReferenceType(), 415 SourceLocation()); 416 CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType)); 417 } 418 419 RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs, 420 FPT->getCallConv(), 421 FPT->getNoReturnAttr()), 422 Callee, ReturnValueSlot(), CallArgs, MD); 423 if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) { 424 bool CanBeZero = !(ResultType->isReferenceType() 425 // FIXME: attr nonnull can't be zero either 426 /* || ResultType->hasAttr<NonNullAttr>() */ ); 427 // Do the return result adjustment. 428 if (CanBeZero) { 429 llvm::BasicBlock *NonZeroBlock = createBasicBlock(); 430 llvm::BasicBlock *ZeroBlock = createBasicBlock(); 431 llvm::BasicBlock *ContBlock = createBasicBlock(); 432 433 const llvm::Type *Ty = RV.getScalarVal()->getType(); 434 llvm::Value *Zero = llvm::Constant::getNullValue(Ty); 435 Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero), 436 NonZeroBlock, ZeroBlock); 437 EmitBlock(NonZeroBlock); 438 llvm::Value *NZ = 439 DynamicTypeAdjust(RV.getScalarVal(), Adjustment.ReturnAdjustment); 440 EmitBranch(ContBlock); 441 EmitBlock(ZeroBlock); 442 llvm::Value *Z = RV.getScalarVal(); 443 EmitBlock(ContBlock); 444 llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty); 445 RVOrZero->reserveOperandSpace(2); 446 RVOrZero->addIncoming(NZ, NonZeroBlock); 447 RVOrZero->addIncoming(Z, ZeroBlock); 448 RV = RValue::get(RVOrZero); 449 } else 450 RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), 451 Adjustment.ReturnAdjustment)); 452 } 453 454 if (!ResultType->isVoidType()) 455 EmitReturnOfRValue(RV, ResultType); 456 457 FinishFunction(); 458 return Fn; 459} 460 461llvm::Constant * 462CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 463 const ThunkAdjustment &ThisAdjustment) { 464 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 465 466 // Compute mangled name 467 llvm::SmallString<256> OutName; 468 if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(MD)) 469 getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), ThisAdjustment, 470 OutName); 471 else 472 getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); 473 OutName += '\0'; 474 const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); 475 476 // Get function for mangled name 477 const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); 478 return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); 479} 480 481llvm::Constant * 482CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD, 483 const CovariantThunkAdjustment &Adjustment) { 484 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 485 486 // Compute mangled name 487 llvm::SmallString<256> OutName; 488 getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); 489 OutName += '\0'; 490 const char* Name = UniqueMangledName(OutName.begin(), OutName.end()); 491 492 // Get function for mangled name 493 const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); 494 return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); 495} 496 497void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) { 498 CGVtableInfo::AdjustmentVectorTy *AdjPtr = getVtableInfo().getAdjustments(GD); 499 if (!AdjPtr) 500 return; 501 CGVtableInfo::AdjustmentVectorTy &Adj = *AdjPtr; 502 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 503 for (unsigned i = 0; i < Adj.size(); i++) { 504 GlobalDecl OGD = Adj[i].first; 505 const CXXMethodDecl *OMD = cast<CXXMethodDecl>(OGD.getDecl()); 506 QualType nc_oret = OMD->getType()->getAs<FunctionType>()->getResultType(); 507 CanQualType oret = getContext().getCanonicalType(nc_oret); 508 QualType nc_ret = MD->getType()->getAs<FunctionType>()->getResultType(); 509 CanQualType ret = getContext().getCanonicalType(nc_ret); 510 ThunkAdjustment ReturnAdjustment; 511 if (oret != ret) { 512 QualType qD = nc_ret->getPointeeType(); 513 QualType qB = nc_oret->getPointeeType(); 514 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); 515 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); 516 ReturnAdjustment = ComputeThunkAdjustment(D, B); 517 } 518 ThunkAdjustment ThisAdjustment = Adj[i].second; 519 bool Extern = !cast<CXXRecordDecl>(OMD->getDeclContext())->isInAnonymousNamespace(); 520 if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) { 521 CovariantThunkAdjustment CoAdj(ThisAdjustment, ReturnAdjustment); 522 llvm::Constant *FnConst; 523 if (!ReturnAdjustment.isEmpty()) 524 FnConst = GetAddrOfCovariantThunk(GD, CoAdj); 525 else 526 FnConst = GetAddrOfThunk(GD, ThisAdjustment); 527 if (!isa<llvm::Function>(FnConst)) { 528 llvm::Constant *SubExpr = 529 cast<llvm::ConstantExpr>(FnConst)->getOperand(0); 530 llvm::Function *OldFn = cast<llvm::Function>(SubExpr); 531 std::string Name = OldFn->getNameStr(); 532 GlobalDeclMap.erase(UniqueMangledName(Name.data(), 533 Name.data() + Name.size() + 1)); 534 llvm::Constant *NewFnConst; 535 if (!ReturnAdjustment.isEmpty()) 536 NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj); 537 else 538 NewFnConst = GetAddrOfThunk(GD, ThisAdjustment); 539 llvm::Function *NewFn = cast<llvm::Function>(NewFnConst); 540 NewFn->takeName(OldFn); 541 llvm::Constant *NewPtrForOldDecl = 542 llvm::ConstantExpr::getBitCast(NewFn, OldFn->getType()); 543 OldFn->replaceAllUsesWith(NewPtrForOldDecl); 544 OldFn->eraseFromParent(); 545 FnConst = NewFn; 546 } 547 llvm::Function *Fn = cast<llvm::Function>(FnConst); 548 if (Fn->isDeclaration()) { 549 llvm::GlobalVariable::LinkageTypes linktype; 550 linktype = llvm::GlobalValue::WeakAnyLinkage; 551 if (!Extern) 552 linktype = llvm::GlobalValue::InternalLinkage; 553 Fn->setLinkage(linktype); 554 if (!Features.Exceptions && !Features.ObjCNonFragileABI) 555 Fn->addFnAttr(llvm::Attribute::NoUnwind); 556 Fn->setAlignment(2); 557 CodeGenFunction(*this).GenerateCovariantThunk(Fn, GD, Extern, CoAdj); 558 } 559 } 560 } 561} 562 563llvm::Constant * 564CodeGenModule::BuildThunk(GlobalDecl GD, bool Extern, 565 const ThunkAdjustment &ThisAdjustment) { 566 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 567 llvm::SmallString<256> OutName; 568 if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(MD)) { 569 getMangleContext().mangleCXXDtorThunk(D, GD.getDtorType(), ThisAdjustment, 570 OutName); 571 } else 572 getMangleContext().mangleThunk(MD, ThisAdjustment, OutName); 573 574 llvm::GlobalVariable::LinkageTypes linktype; 575 linktype = llvm::GlobalValue::WeakAnyLinkage; 576 if (!Extern) 577 linktype = llvm::GlobalValue::InternalLinkage; 578 llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 579 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 580 const llvm::FunctionType *FTy = 581 getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), 582 FPT->isVariadic()); 583 584 llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), 585 &getModule()); 586 CodeGenFunction(*this).GenerateThunk(Fn, GD, Extern, ThisAdjustment); 587 llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 588 return m; 589} 590 591llvm::Constant * 592CodeGenModule::BuildCovariantThunk(const GlobalDecl &GD, bool Extern, 593 const CovariantThunkAdjustment &Adjustment) { 594 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 595 llvm::SmallString<256> OutName; 596 getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName); 597 llvm::GlobalVariable::LinkageTypes linktype; 598 linktype = llvm::GlobalValue::WeakAnyLinkage; 599 if (!Extern) 600 linktype = llvm::GlobalValue::InternalLinkage; 601 llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 602 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 603 const llvm::FunctionType *FTy = 604 getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), 605 FPT->isVariadic()); 606 607 llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(), 608 &getModule()); 609 CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, Adjustment); 610 llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 611 return m; 612} 613 614static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VtableIndex, 615 llvm::Value *This, const llvm::Type *Ty) { 616 Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo(); 617 618 llvm::Value *Vtable = CGF.Builder.CreateBitCast(This, Ty); 619 Vtable = CGF.Builder.CreateLoad(Vtable); 620 621 llvm::Value *VFuncPtr = 622 CGF.Builder.CreateConstInBoundsGEP1_64(Vtable, VtableIndex, "vfn"); 623 return CGF.Builder.CreateLoad(VFuncPtr); 624} 625 626llvm::Value * 627CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This, 628 const llvm::Type *Ty) { 629 MD = MD->getCanonicalDecl(); 630 uint64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD); 631 632 return ::BuildVirtualCall(*this, VtableIndex, This, Ty); 633} 634 635llvm::Value * 636CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 637 llvm::Value *&This, const llvm::Type *Ty) { 638 DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl()); 639 uint64_t VtableIndex = 640 CGM.getVtableInfo().getMethodVtableIndex(GlobalDecl(DD, Type)); 641 642 return ::BuildVirtualCall(*this, VtableIndex, This, Ty); 643}
|