r192225 - Revert 192220 as it fails on an assertion
Timur Iskhodzhanov
timurrrr at google.com
Tue Oct 8 13:09:50 PDT 2013
Author: timurrrr
Date: Tue Oct 8 15:09:50 2013
New Revision: 192225
URL: http://llvm.org/viewvc/llvm-project?rev=192225&view=rev
Log:
Revert 192220 as it fails on an assertion
Removed:
cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
Modified:
cfe/trunk/include/clang/AST/VTableBuilder.h
cfe/trunk/include/clang/Basic/ABI.h
cfe/trunk/lib/AST/MicrosoftMangle.cpp
cfe/trunk/lib/AST/VTableBuilder.cpp
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/lib/CodeGen/CGVTables.h
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
Modified: cfe/trunk/include/clang/AST/VTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/VTableBuilder.h?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/VTableBuilder.h (original)
+++ cfe/trunk/include/clang/AST/VTableBuilder.h Tue Oct 8 15:09:50 2013
@@ -200,6 +200,7 @@ private:
class VTableLayout {
public:
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
+ typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
typedef const VTableComponent *vtable_component_iterator;
typedef const VTableThunkTy *vtable_thunk_iterator;
@@ -209,7 +210,7 @@ private:
uint64_t NumVTableComponents;
llvm::OwningArrayPtr<VTableComponent> VTableComponents;
- /// \brief Contains thunks needed by vtables, sorted by indices.
+ /// \brief Contains thunks needed by vtables.
uint64_t NumVTableThunks;
llvm::OwningArrayPtr<VTableThunkTy> VTableThunks;
@@ -284,12 +285,9 @@ protected:
virtual ~VTableContextBase() {}
public:
- virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl());
+ const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) {
computeVTableRelatedInformation(MD->getParent());
- // This assumes that all the destructors present in the vtable
- // use exactly the same set of thunks.
ThunksMapTy::const_iterator I = Thunks.find(MD);
if (I == Thunks.end()) {
// We did not find a thunk for this method.
@@ -485,14 +483,6 @@ public:
CharUnits VFPtrOffset);
const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
-
- const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
- // Complete destructors don't have a slot in a vftable, so no thunks needed.
- if (isa<CXXDestructorDecl>(GD.getDecl()) &&
- GD.getDtorType() == Dtor_Complete)
- return 0;
- return VTableContextBase::getThunkInfo(GD);
- }
};
}
Modified: cfe/trunk/include/clang/Basic/ABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ABI.h?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/ABI.h (original)
+++ cfe/trunk/include/clang/Basic/ABI.h Tue Oct 8 15:09:50 2013
@@ -54,10 +54,6 @@ struct ReturnAdjustment {
LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
}
- friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) {
- return !(LHS == RHS);
- }
-
friend bool operator<(const ReturnAdjustment &LHS,
const ReturnAdjustment &RHS) {
if (LHS.NonVirtual < RHS.NonVirtual)
@@ -87,10 +83,6 @@ struct ThisAdjustment {
return LHS.NonVirtual == RHS.NonVirtual &&
LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
}
-
- friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
- return !(LHS == RHS);
- }
friend bool operator<(const ThisAdjustment &LHS,
const ThisAdjustment &RHS) {
@@ -102,8 +94,6 @@ struct ThisAdjustment {
}
};
-class CXXMethodDecl;
-
/// \brief The \c this pointer adjustment as well as an optional return
/// adjustment for a thunk.
struct ThunkInfo {
@@ -113,25 +103,23 @@ struct ThunkInfo {
/// \brief The return adjustment.
ReturnAdjustment Return;
- /// \brief Holds a pointer to the overridden method this thunk is for,
- /// if needed by the ABI to distinguish different thunks with equal
- /// adjustments. Otherwise, null.
- /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
- /// an ABI-specific comparator.
- const CXXMethodDecl *Method;
-
- ThunkInfo() : Method(0) { }
-
- ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
- const CXXMethodDecl *Method = 0)
- : This(This), Return(Return), Method(Method) {}
+ ThunkInfo() { }
+
+ ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
+ : This(This), Return(Return) { }
friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
- return LHS.This == RHS.This && LHS.Return == RHS.Return &&
- LHS.Method == RHS.Method;
+ return LHS.This == RHS.This && LHS.Return == RHS.Return;
+ }
+
+ friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
+ if (LHS.This < RHS.This)
+ return true;
+
+ return LHS.This == RHS.This && LHS.Return < RHS.Return;
}
- bool isEmpty() const { return This.isEmpty() && Return.isEmpty() && Method == 0; }
+ bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
};
} // end namespace clang
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Oct 8 15:09:50 2013
@@ -15,7 +15,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
-#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -1406,8 +1405,7 @@ void MicrosoftCXXNameMangler::mangleFunc
// ::= Z # global far
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
switch (MD->getAccess()) {
- case AS_none:
- llvm_unreachable("Unsupported access specifier");
+ default:
case AS_private:
if (MD->isStatic())
Out << 'C';
@@ -1860,70 +1858,36 @@ void MicrosoftMangleContextImpl::mangleN
return Mangler.mangle(D);
}
-static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
- const ThisAdjustment &Adjustment,
- MicrosoftCXXNameMangler &Mangler,
- raw_ostream &Out) {
- // FIXME: add support for vtordisp thunks.
- if (Adjustment.NonVirtual != 0) {
- switch (MD->getAccess()) {
- case AS_none:
- llvm_unreachable("Unsupported access specifier");
- case AS_private:
- Out << 'G';
- break;
- case AS_protected:
- Out << 'O';
- break;
- case AS_public:
- Out << 'W';
- }
- llvm::APSInt APSNumber(/*BitWidth=*/32, /*isUnsigned=*/true);
- APSNumber = -Adjustment.NonVirtual;
- Mangler.mangleNumber(APSNumber);
- } else {
- switch (MD->getAccess()) {
- case AS_none:
- llvm_unreachable("Unsupported access specifier");
- case AS_private:
- Out << 'A';
- break;
- case AS_protected:
- Out << 'I';
- break;
- case AS_public:
- Out << 'Q';
- }
- }
-}
-
void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &Out) {
+ // FIXME: this is not yet a complete implementation, but merely a
+ // reasonably-working stub to avoid crashing when required to emit a thunk.
MicrosoftCXXNameMangler Mangler(*this, Out);
Out << "\01?";
Mangler.mangleName(MD);
- mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out);
- if (!Thunk.Return.isEmpty())
- assert(Thunk.Method != 0 && "Thunk info should hold the overridee decl");
-
- const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
- Mangler.mangleFunctionType(
- DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
-}
-
-void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
- const CXXDestructorDecl *DD, CXXDtorType Type,
- const ThisAdjustment &Adjustment, raw_ostream &Out) {
- // FIXME: Actually, the dtor thunk should be emitted for vector deleting
- // dtors rather than scalar deleting dtors. Just use the vector deleting dtor
- // mangling manually until we support both deleting dtor types.
- assert(Type == Dtor_Deleting);
- MicrosoftCXXNameMangler Mangler(*this, Out, DD, Type);
- Out << "\01??_E";
- Mangler.mangleName(DD->getParent());
- mangleThunkThisAdjustment(DD, Adjustment, Mangler, Out);
- Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
+ if (Thunk.This.NonVirtual != 0) {
+ // FIXME: add support for protected/private or use mangleFunctionClass.
+ Out << "W";
+ llvm::APSInt APSNumber(/*BitWidth=*/32 /*FIXME: check on x64*/,
+ /*isUnsigned=*/true);
+ APSNumber = -Thunk.This.NonVirtual;
+ Mangler.mangleNumber(APSNumber);
+ } else {
+ // FIXME: add support for protected/private or use mangleFunctionClass.
+ Out << "Q";
+ }
+ // FIXME: mangle return adjustment? Most likely includes using an overridee FPT?
+ Mangler.mangleFunctionType(MD->getType()->castAs<FunctionProtoType>(), MD);
+}
+
+void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
+ CXXDtorType Type,
+ const ThisAdjustment &,
+ raw_ostream &) {
+ unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle thunk for this destructor yet");
+ getDiags().Report(DD->getLocation(), DiagID);
}
void MicrosoftMangleContextImpl::mangleCXXVFTable(
Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
+++ cfe/trunk/lib/AST/VTableBuilder.cpp Tue Oct 8 15:09:50 2013
@@ -992,7 +992,6 @@ public:
MostDerivedClassIsVirtual(MostDerivedClassIsVirtual),
LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
- assert(!Context.getTargetInfo().getCXXABI().isMicrosoft());
LayoutVTable();
@@ -1905,21 +1904,6 @@ VTableBuilder::LayoutVTablesForVirtualBa
}
}
-struct ItaniumThunkInfoComparator {
- bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
- assert(LHS.Method == 0);
- assert(RHS.Method == 0);
-
- if (LHS.This != RHS.This)
- return LHS.This < RHS.This;
-
- if (LHS.Return != RHS.Return)
- return LHS.Return < RHS.Return;
-
- llvm_unreachable("Shouldn't observe two equal thunks");
- }
-};
-
/// dumpLayout - Dump the vtable layout.
void VTableBuilder::dumpLayout(raw_ostream& Out) {
// FIXME: write more tests that actually use the dumpLayout output to prevent
@@ -2162,8 +2146,7 @@ void VTableBuilder::dumpLayout(raw_ostre
const CXXMethodDecl *MD = I->second;
ThunkInfoVectorTy ThunksVector = Thunks[MD];
- std::sort(ThunksVector.begin(), ThunksVector.end(),
- ItaniumThunkInfoComparator());
+ std::sort(ThunksVector.begin(), ThunksVector.end());
Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -2250,15 +2233,7 @@ void VTableBuilder::dumpLayout(raw_ostre
Out << '\n';
}
-
-struct VTableThunksComparator {
- bool operator()(const VTableLayout::VTableThunkTy &LHS,
- const VTableLayout::VTableThunkTy &RHS) {
- assert(LHS.first != RHS.first &&
- "All thunks should have unique indices!");
- return LHS.first < RHS.first;
- }
-};
+
}
VTableLayout::VTableLayout(uint64_t NumVTableComponents,
@@ -2277,9 +2252,6 @@ VTableLayout::VTableLayout(uint64_t NumV
this->VTableComponents.get());
std::copy(VTableThunks, VTableThunks+NumVTableThunks,
this->VTableThunks.get());
- std::sort(this->VTableThunks.get(),
- this->VTableThunks.get() + NumVTableThunks,
- VTableThunksComparator());
}
VTableLayout::~VTableLayout() { }
@@ -2340,6 +2312,7 @@ VTableContext::getVirtualBaseOffsetOffse
static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) {
SmallVector<VTableLayout::VTableThunkTy, 1>
VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
+ std::sort(VTableThunks.begin(), VTableThunks.end());
return new VTableLayout(Builder.getNumVTableComponents(),
Builder.vtable_component_begin(),
@@ -2547,14 +2520,18 @@ private:
/// AddMethod - Add a single virtual member function to the vftable
/// components vector.
- void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) {
+ void AddMethod(const CXXMethodDecl *MD, ThisAdjustment ThisAdjustment,
+ ReturnAdjustment ReturnAdjustment) {
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
- assert(TI.Return.isEmpty() &&
+ assert(ReturnAdjustment.isEmpty() &&
"Destructor can't have return adjustment!");
Components.push_back(VTableComponent::MakeDeletingDtor(DD));
} else {
- if (!TI.isEmpty())
- VTableThunks[Components.size()] = TI;
+ // Add the return adjustment if necessary.
+ if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) {
+ VTableThunks[Components.size()].Return = ReturnAdjustment;
+ VTableThunks[Components.size()].This = ThisAdjustment;
+ }
Components.push_back(VTableComponent::MakeFunction(MD));
}
}
@@ -2839,7 +2816,6 @@ void VFTableBuilder::AddMethods(BaseSubo
FinalOverriders::OverriderInfo Overrider =
Overriders.getOverrider(MD, Base.getBaseOffset());
ThisAdjustment ThisAdjustmentOffset;
- bool ForceThunk = false;
// Check if this virtual member function overrides
// a method in one of the visited bases.
@@ -2864,7 +2840,8 @@ void VFTableBuilder::AddMethods(BaseSubo
AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]);
}
- if (MD->getResultType() == OverriddenMD->getResultType()) {
+ if (ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD)
+ .isEmpty()) {
// No return adjustment needed - just replace the overridden method info
// with the current info.
MethodInfo MI(OverriddenMethodInfo.VBTableIndex,
@@ -2882,7 +2859,6 @@ void VFTableBuilder::AddMethods(BaseSubo
// method was in the vftable.
// For now, just mark the overriden method as shadowed by a new slot.
OverriddenMethodInfo.Shadowed = true;
- ForceThunk = true;
// Also apply this adjustment to the shadowed slots.
if (!ThisAdjustmentOffset.isEmpty()) {
@@ -2931,7 +2907,6 @@ void VFTableBuilder::AddMethods(BaseSubo
ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
}
if (!ReturnAdjustmentOffset.isEmpty()) {
- ForceThunk = true;
ReturnAdjustment.NonVirtual =
ReturnAdjustmentOffset.NonVirtualOffset.getQuantity();
if (ReturnAdjustmentOffset.VirtualBase) {
@@ -2943,8 +2918,7 @@ void VFTableBuilder::AddMethods(BaseSubo
}
}
- AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment,
- ForceThunk ? MD : 0));
+ AddMethod(Overrider.Method, ThisAdjustmentOffset, ReturnAdjustment);
}
}
@@ -2955,20 +2929,6 @@ void PrintBasePath(const VFPtrInfo::Base
}
}
-struct MicrosoftThunkInfoStableSortComparator {
- bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
- if (LHS.This != RHS.This)
- return LHS.This < RHS.This;
-
- if (LHS.Return != RHS.Return)
- return LHS.Return < RHS.Return;
-
- // Keep different thunks with the same adjustments in the order they
- // were put into the vector.
- return false;
- }
-};
-
void VFTableBuilder::dumpLayout(raw_ostream &Out) {
Out << "VFTable for ";
PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out);
@@ -3082,8 +3042,7 @@ void VFTableBuilder::dumpLayout(raw_ostr
const CXXMethodDecl *MD = I->second;
ThunkInfoVectorTy ThunksVector = Thunks[MD];
- std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
- MicrosoftThunkInfoStableSortComparator());
+ std::sort(ThunksVector.begin(), ThunksVector.end());
Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -3259,6 +3218,7 @@ void MicrosoftVFTableContext::computeVTa
assert(VFTableLayouts.count(id) == 0);
SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
+ std::sort(VTableThunks.begin(), VTableThunks.end());
VFTableLayouts[id] = new VTableLayout(
Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Oct 8 15:09:50 2013
@@ -339,17 +339,11 @@ public:
SourceLocation CallLoc,
llvm::Value *This) = 0;
- virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF,
- GlobalDecl GD,
- CallArgList &CallArgs) {}
-
/// Emit any tables needed to implement virtual inheritance. For Itanium,
/// this emits virtual table tables. For the MSVC++ ABI, this emits virtual
/// base tables.
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
- virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0;
-
virtual void EmitReturnFromThunk(CodeGenFunction &CGF,
RValue RV, QualType ResultType);
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Tue Oct 8 15:09:50 2013
@@ -333,9 +333,6 @@ void CodeGenFunction::GenerateThunk(llvm
// Add our adjusted 'this' pointer.
CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
- if (isa<CXXDestructorDecl>(MD))
- CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, GD, CallArgs);
-
// Add the rest of the parameters.
for (FunctionDecl::param_const_iterator I = MD->param_begin(),
E = MD->param_end(); I != E; ++I) {
@@ -393,8 +390,14 @@ void CodeGenFunction::GenerateThunk(llvm
setThunkVisibility(CGM, MD, Thunk, Fn);
}
-void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
- bool ForVTable) {
+void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
+ bool UseAvailableExternallyLinkage)
+{
+ if (CGM.getTarget().getCXXABI().isMicrosoft()) {
+ // Emission of thunks is not supported yet in Microsoft ABI.
+ return;
+ }
+
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);
// FIXME: re-use FnInfo in this computation.
@@ -432,11 +435,9 @@ void CodeGenVTables::emitThunk(GlobalDec
}
llvm::Function *ThunkFn = cast<llvm::Function>(Entry);
- bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
- bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
if (!ThunkFn->isDeclaration()) {
- if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
+ if (UseAvailableExternallyLinkage) {
// There is already a thunk emitted for this function, do nothing.
return;
}
@@ -465,17 +466,14 @@ void CodeGenVTables::emitThunk(GlobalDec
CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
}
- CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+ if (UseAvailableExternallyLinkage)
+ ThunkFn->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
}
-void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD,
- const ThunkInfo &Thunk) {
- // If the ABI has key functions, only the TU with the key function should emit
- // the thunk. However, we can allow inlining of thunks if we emit them with
- // available_externally linkage together with vtables when optimizations are
- // enabled.
- if (CGM.getTarget().getCXXABI().hasKeyFunctions() &&
- !CGM.getCodeGenOpts().OptimizationLevel)
+void CodeGenVTables::MaybeEmitThunkAvailableExternally(GlobalDecl GD,
+ const ThunkInfo &Thunk) {
+ // We only want to do this when building with optimizations.
+ if (!CGM.getCodeGenOpts().OptimizationLevel)
return;
// We can't emit thunks for member functions with incomplete types.
@@ -484,7 +482,7 @@ void CodeGenVTables::maybeEmitThunkForVT
cast<FunctionType>(MD->getType().getTypePtr())))
return;
- emitThunk(GD, Thunk, /*ForVTable=*/true);
+ EmitThunk(GD, Thunk, /*UseAvailableExternallyLinkage=*/true);
}
void CodeGenVTables::EmitThunks(GlobalDecl GD)
@@ -496,18 +494,21 @@ void CodeGenVTables::EmitThunks(GlobalDe
if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
return;
- const VTableContext::ThunkInfoVectorTy *ThunkInfoVector;
if (VFTContext.isValid()) {
- ThunkInfoVector = VFTContext->getThunkInfo(GD);
- } else {
- ThunkInfoVector = VTContext.getThunkInfo(GD);
+ // FIXME: This is a temporary solution to force generation of vftables in
+ // Microsoft ABI. Remove when we thread VFTableContext through CodeGen.
+ VFTContext->getVFPtrOffsets(MD->getParent());
+ return;
}
+ const VTableContext::ThunkInfoVectorTy *ThunkInfoVector =
+ VTContext.getThunkInfo(MD);
if (!ThunkInfoVector)
return;
for (unsigned I = 0, E = ThunkInfoVector->size(); I != E; ++I)
- emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);
+ EmitThunk(GD, (*ThunkInfoVector)[I],
+ /*UseAvailableExternallyLinkage=*/false);
}
llvm::Constant *
@@ -602,7 +603,7 @@ CodeGenVTables::CreateVTableInitializer(
VTableThunks[NextVTableThunkIndex].first == I) {
const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
- maybeEmitThunkForVTable(GD, Thunk);
+ MaybeEmitThunkAvailableExternally(GD, Thunk);
Init = CGM.GetAddrOfThunk(GD, Thunk);
NextVTableThunkIndex++;
Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Tue Oct 8 15:09:50 2013
@@ -52,12 +52,15 @@ class CodeGenVTables {
/// indices.
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
- /// emitThunk - Emit a single thunk.
- void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable);
+ /// EmitThunk - Emit a single thunk.
+ void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
+ bool UseAvailableExternallyLinkage);
- /// maybeEmitThunkForVTable - Emit the given thunk for the vtable if needed by
- /// the ABI.
- void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk);
+ /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with
+ /// available_externally linkage to allow for inlining of thunks.
+ /// This will be done iff optimizations are enabled and the member function
+ /// doesn't contain any incomplete types.
+ void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk);
public:
/// CreateVTableInitializer - Create a vtable initializer for the given record
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Oct 8 15:09:50 2013
@@ -173,13 +173,6 @@ public:
void emitVirtualInheritanceTables(const CXXRecordDecl *RD);
- void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) {
- // Allow inlining of thunks by emitting them with available_externally
- // linkage together with vtables when needed.
- if (ForVTable)
- Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
- }
-
StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Oct 8 15:09:50 2013
@@ -173,20 +173,8 @@ public:
CXXDtorType DtorType, SourceLocation CallLoc,
llvm::Value *This);
- void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
- CallArgList &CallArgs) {
- assert(GD.getDtorType() == Dtor_Deleting &&
- "Only deleting destructor thunks are available in this ABI");
- CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
- CGM.getContext().IntTy);
- }
-
void emitVirtualInheritanceTables(const CXXRecordDecl *RD);
- void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) {
- Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
- }
-
void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
llvm::GlobalVariable *DeclPtr,
bool PerformInit);
Removed: cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp?rev=192224&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp (removed)
@@ -1,118 +0,0 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 >%t 2>&1
-// RUN: FileCheck --check-prefix=MANGLING %s < %t
-// RUN: FileCheck --check-prefix=XMANGLING %s < %t
-// RUN: FileCheck --check-prefix=CODEGEN %s < %t
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
-
-void foo(void *);
-
-struct A {
- virtual ~A();
- virtual void public_f();
- // Make sure we don't emit unneeded thunks:
- // XMANGLING-NOT: @"\01?public_f at A@@QAEXXZ"
- protected:
- virtual void protected_f();
- private:
- virtual void private_f();
-};
-
-struct B {
- virtual ~B();
- virtual void public_f();
- protected:
- virtual void protected_f();
- private:
- virtual void private_f();
-};
-
-
-struct C : A, B {
- C();
-
- virtual ~C();
- // MANGLING-DAG: @"\01??1C@@UAE at XZ"
- // MANGLING-DAG: @"\01??_GC@@UAEPAXI at Z"
- // MANGLING-DAG: @"\01??_EC@@W3AEPAXI at Z"
- // MANGLING-X64-DAG: @"\01??1C@@UEAA at XZ"
- // MANGLING-X64-DAG: @"\01??_GC@@UEAAPEAXI at Z"
- // MANGLING-X64-DAG: @"\01??_EC@@W7EAAPEAXI at Z"
-
- // Overrides public_f() of two subobjects with distinct vfptrs, thus needs a thunk.
- virtual void public_f();
- // MANGLING-DAG: @"\01?public_f at C@@UAEXXZ"
- // MANGLING-DAG: @"\01?public_f at C@@W3AEXXZ"
- // MANGLING-X64-DAG: @"\01?public_f at C@@UEAAXXZ"
- // MANGLING-X64-DAG: @"\01?public_f at C@@W7EAAXXZ"
- protected:
- virtual void protected_f();
- // MANGLING-DAG: @"\01?protected_f at C@@MAEXXZ"
- // MANGLING-DAG: @"\01?protected_f at C@@O3AEXXZ"
- // MANGLING-X64-DAG: @"\01?protected_f at C@@MEAAXXZ"
- // MANGLING-X64-DAG: @"\01?protected_f at C@@O7EAAXXZ"
-
- private:
- virtual void private_f();
- // MANGLING-DAG: @"\01?private_f at C@@EAEXXZ"
- // MANGLING-DAG: @"\01?private_f at C@@G3AEXXZ"
- // MANGLING-X64-DAG: @"\01?private_f at C@@EEAAXXZ"
- // MANGLING-X64-DAG: @"\01?private_f at C@@G7EAAXXZ"
-};
-
-C::C() {} // Emits vftable and forces thunk generation.
-
-// CODEGEN: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI at Z"(%struct.C* %this, i32 %should_call_delete)
-// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 -4
-// FIXME: should actually call _EC, not _GC.
-// CODEGEN: call x86_thiscallcc void @"\01??_GC@@UAEPAXI at Z"
-// CODEGEN: ret
-
-// CODEGEN: define weak x86_thiscallcc void @"\01?public_f at C@@W3AEXXZ"(%struct.C*
-// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 -4
-// CODEGEN: call x86_thiscallcc void @"\01?public_f at C@@UAEXXZ"(%struct.C*
-// CODEGEN: ret
-
-void zoo(C* obj) {
- delete obj;
-}
-
-struct D {
- virtual B* goo();
-};
-
-struct E : D {
- virtual C* goo();
- // MANGLING-DAG: @"\01?goo at E@@UAEPAUC@@XZ"
- // MANGLING-DAG: @"\01?goo at E@@QAEPAUB@@XZ"
- // MANGLING-X64-DAG: @"\01?goo at E@@UEAAPEAUC@@XZ"
- // MANGLING-X64-DAG: @"\01?goo at E@@QEAAPEAUB@@XZ"
-};
-
-E e; // Emits vftable and forces thunk generation.
-
-// CODEGEN: define weak x86_thiscallcc %struct.C* @"\01?goo at E@@QAEPAUB@@XZ"
-// CODEGEN: call x86_thiscallcc %struct.C* @"\01?goo at E@@UAEPAUC@@XZ"
-// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 4
-// CODEGEN: ret
-
-struct F : virtual A, virtual B {
- virtual ~F();
-};
-
-F f; // Just make sure we don't crash, e.g. mangling the complete dtor.
-
-struct G : C { };
-
-struct H : E {
- virtual G* goo();
- // MANGLING-DAG: @"\01?goo at H@@UAEPAUG@@XZ"
- // MANGLING-DAG: @"\01?goo at H@@QAEPAUB@@XZ"
- // MANGLING-DAG: @"\01?goo at H@@QAEPAUC@@XZ"
- // MANGLING-X64-DAG: @"\01?goo at H@@UEAAPEAUG@@XZ"
- // MANGLING-X64-DAG: @"\01?goo at H@@QEAAPEAUB@@XZ"
- // MANGLING-X64-DAG: @"\01?goo at H@@QEAAPEAUC@@XZ"
-};
-
-H h;
-
-// FIXME: Write vtordisp adjusting thunk tests
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Tue Oct 8 15:09:50 2013
@@ -93,11 +93,3 @@ void call_vbase_bar(B *obj) {
//
// CHECK: ret void
}
-
-struct C : B {
- C();
- // has an implicit vdtor.
-};
-
-// Used to crash on an assertion.
-C::C() {}
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp Tue Oct 8 15:09:50 2013
@@ -18,7 +18,6 @@
// RUN: FileCheck --check-prefix=RET-THUNKS-Test3 %s < %t
// RUN: FileCheck --check-prefix=RET-THUNKS-Test4 %s < %t
// RUN: FileCheck --check-prefix=RET-THUNKS-Test5 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test6 %s < %t
// RUN: FileCheck --check-prefix=MANGLING %s < %t
@@ -459,22 +458,4 @@ struct Test5 : Ret1, Test1 {
};
Test5 t5;
-
-struct Ret3 : this_adjustment::Test1 { };
-
-struct Test6 : Test1 {
- virtual Ret3* foo();
- // RET-THUNKS-Test6: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test1' in 'return_adjustment::Test6' (4 entries).
- // RET-THUNKS-Test6-NEXT: 0 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
- // RET-THUNKS-Test6-NEXT: [return adjustment: 4 non-virtual]
- // RET-THUNKS-Test6-NEXT: 1 | void return_adjustment::Ret1::z()
- // RET-THUNKS-Test6-NEXT: 2 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
- // RET-THUNKS-Test6-NEXT: 3 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-
- // RET-THUNKS-Test6: VFTable indices for 'return_adjustment::Test6' (1 entries).
- // RET-THUNKS-Test6-NEXT: 3 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-};
-
-Test6 t6;
-
}
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp?rev=192225&r1=192224&r2=192225&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp Tue Oct 8 15:09:50 2013
@@ -154,9 +154,6 @@ struct X: virtual C {
// TEST4-NOT: VFTable indices for 'Test4::X'
// MANGLING-DAG: @"\01??_7X at Test4@@6B@"
-
- // Also check the mangling of the thunk.
- // MANGLING-DAG: define weak x86_thiscallcc void @"\01?f at C@@WPPPPPPPE at AEXXZ"
};
X x;
More information about the cfe-commits
mailing list