diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-12-27 19:43:59 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-12-27 19:43:59 +0000 |
commit | 604c8b45e407da523f105144d4f4294696b37150 (patch) | |
tree | 56b4197458efd47c8d57cfeb8dd66ec308412430 /clang/lib/AST/VTableBuilder.cpp | |
parent | ac2002973cb68fba3e808eab2920036086d1a214 (diff) | |
download | bcm5719-llvm-604c8b45e407da523f105144d4f4294696b37150.tar.gz bcm5719-llvm-604c8b45e407da523f105144d4f4294696b37150.zip |
[ms-cxxabi] Emit fewer trivial return adjusting thunks
Most importantly, this makes our vtable layout match MSVC's. Previously
we would emit a return adjusting thunk whenever the return types
differed, even if the adjustment would have been trivial.
MSVC does emit some trivial return adjusting thunks, but only if there
was already an overridden method that required a return adjustment.
llvm-svn: 198080
Diffstat (limited to 'clang/lib/AST/VTableBuilder.cpp')
-rw-r--r-- | clang/lib/AST/VTableBuilder.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 408fbad17a2..b14ddbfe02e 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2541,6 +2541,8 @@ private: } } + bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD); + /// AddMethods - Add the methods of this base subobject and the relevant /// subbases to the vftable we're currently laying out. void AddMethods(BaseSubobject Base, unsigned BaseDepth, @@ -2800,6 +2802,24 @@ static void GroupNewVirtualOverloads( VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend()); } +/// We need a return adjusting thunk for this method if its return type is +/// not trivially convertible to the return type of any of its overridden +/// methods. +bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) { + OverriddenMethodsSetTy OverriddenMethods; + ComputeAllOverriddenMethods(MD, OverriddenMethods); + for (OverriddenMethodsSetTy::iterator I = OverriddenMethods.begin(), + E = OverriddenMethods.end(); + I != E; ++I) { + const CXXMethodDecl *OverriddenMD = *I; + BaseOffset Adjustment = + ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD); + if (!Adjustment.isEmpty()) + return true; + } + return false; +} + void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, const CXXRecordDecl *LastVBase, BasesSetVectorTy &VisitedBases) { @@ -2885,8 +2905,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]); } - if (Context.hasSameType(MD->getResultType(), - OverriddenMD->getResultType())) { + if (!NeedsReturnAdjustingThunk(MD)) { // No return adjustment needed - just replace the overridden method info // with the current info. MethodInfo MI(OverriddenMethodInfo.VBTableIndex, @@ -3049,6 +3068,8 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) { case VTableComponent::CK_FunctionPointer: { const CXXMethodDecl *MD = Component.getFunctionDecl(); + // FIXME: Figure out how to print the real thunk type, since they can + // differ in the return type. std::string Str = PredefinedExpr::ComputeName( PredefinedExpr::PrettyFunctionNoVirtual, MD); Out << Str; |