diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /lib/CodeGen/CGVTables.cpp | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | lib/CodeGen/CGVTables.cpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index cdaa26a..5b37fe4 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -79,15 +79,16 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, llvm::Value *Ptr, int64_t NonVirtualAdjustment, - int64_t VirtualAdjustment) { + int64_t VirtualAdjustment, + bool IsReturnAdjustment) { if (!NonVirtualAdjustment && !VirtualAdjustment) return Ptr; llvm::Type *Int8PtrTy = CGF.Int8PtrTy; llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); - if (NonVirtualAdjustment) { - // Do the non-virtual adjustment. + if (NonVirtualAdjustment && !IsReturnAdjustment) { + // Perform the non-virtual adjustment for a base-to-derived cast. V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); } @@ -95,7 +96,7 @@ static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); - // Do the virtual adjustment. + // Perform the virtual adjustment. llvm::Value *VTablePtrPtr = CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); @@ -113,6 +114,11 @@ static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, V = CGF.Builder.CreateInBoundsGEP(V, Offset); } + if (NonVirtualAdjustment && IsReturnAdjustment) { + // Perform the non-virtual adjustment for a derived-to-base cast. + V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); + } + // Cast back to the original type. return CGF.Builder.CreateBitCast(V, Ptr->getType()); } @@ -150,8 +156,7 @@ static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: - if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables) - return; + return; break; } @@ -199,7 +204,8 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF, ReturnValue = PerformTypeAdjustment(CGF, ReturnValue, Thunk.Return.NonVirtual, - Thunk.Return.VBaseOffsetOffset); + Thunk.Return.VBaseOffsetOffset, + /*IsReturnAdjustment*/true); if (NullCheckValue) { CGF.Builder.CreateBr(AdjustEnd); @@ -248,7 +254,9 @@ void CodeGenFunction::GenerateVarArgsThunk( llvm::Function *BaseFn = cast<llvm::Function>(Callee); // Clone to thunk. - llvm::Function *NewFn = llvm::CloneFunction(BaseFn); + llvm::ValueToValueMapTy VMap; + llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap, + /*ModuleLevelChanges=*/false); CGM.getModule().getFunctionList().push_back(NewFn); Fn->replaceAllUsesWith(NewFn); NewFn->takeName(Fn); @@ -281,7 +289,8 @@ void CodeGenFunction::GenerateVarArgsThunk( llvm::Value *AdjustedThisPtr = PerformTypeAdjustment(*this, ThisPtr, Thunk.This.NonVirtual, - Thunk.This.VCallOffsetOffset); + Thunk.This.VCallOffsetOffset, + /*IsReturnAdjustment*/false); ThisStore->setOperand(0, AdjustedThisPtr); if (!Thunk.Return.isEmpty()) { @@ -324,7 +333,10 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, FunctionArgs.push_back(Param); } - + + // Initialize debug info if needed. + maybeInitializeDebugInfo(); + StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs, SourceLocation()); @@ -335,7 +347,8 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, llvm::Value *AdjustedThisPtr = PerformTypeAdjustment(*this, LoadCXXThis(), Thunk.This.NonVirtual, - Thunk.This.VCallOffsetOffset); + Thunk.This.VCallOffsetOffset, + /*IsReturnAdjustment*/false); CallArgList CallArgs; @@ -455,6 +468,8 @@ void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, return; } + CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn); + if (ThunkFn->isVarArg()) { // Varargs thunks are special; we can't just generate a call because // we can't copy the varargs. Our implementation is rather @@ -524,7 +539,7 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, unsigned NextVTableThunkIndex = 0; - llvm::Constant* PureVirtualFn = 0; + llvm::Constant *PureVirtualFn = 0, *DeletedVirtualFn = 0; for (unsigned I = 0; I != NumComponents; ++I) { VTableComponent Component = Components[I]; @@ -573,14 +588,25 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { // We have a pure virtual member function. if (!PureVirtualFn) { - llvm::FunctionType *Ty =
- llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
- StringRef PureCallName = CGM.getCXXABI().GetPureVirtualCallName();
- PureVirtualFn = CGM.CreateRuntimeFunction(Ty, PureCallName);
- PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn,
+ llvm::FunctionType *Ty = + llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); + StringRef PureCallName = CGM.getCXXABI().GetPureVirtualCallName(); + PureVirtualFn = CGM.CreateRuntimeFunction(Ty, PureCallName); + PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, CGM.Int8PtrTy); } Init = PureVirtualFn; + } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) { + if (!DeletedVirtualFn) { + llvm::FunctionType *Ty = + llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); + StringRef DeletedCallName = + CGM.getCXXABI().GetDeletedVirtualCallName(); + DeletedVirtualFn = CGM.CreateRuntimeFunction(Ty, DeletedCallName); + DeletedVirtualFn = llvm::ConstantExpr::getBitCast(DeletedVirtualFn, + CGM.Int8PtrTy); + } + Init = DeletedVirtualFn; } else { // Check if we should use a thunk. if (NextVTableThunkIndex < NumVTableThunks && |