Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index c6b38d3..6dc3956 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -44,9 +44,9 @@
/// path from the derived class to the base class involves a virtual base
/// class.
CharUnits NonVirtualOffset;
-
- BaseOffset() : DerivedClass(0), VirtualBase(0),
- NonVirtualOffset(CharUnits::Zero()) { }
+
+ BaseOffset() : DerivedClass(nullptr), VirtualBase(nullptr),
+ NonVirtualOffset(CharUnits::Zero()) { }
BaseOffset(const CXXRecordDecl *DerivedClass,
const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset)
: DerivedClass(DerivedClass), VirtualBase(VirtualBase),
@@ -64,10 +64,15 @@
/// Method - The method decl of the overrider.
const CXXMethodDecl *Method;
+ /// VirtualBase - The virtual base class subobject of this overridder.
+ /// Note that this records the closest derived virtual base class subobject.
+ const CXXRecordDecl *VirtualBase;
+
/// Offset - the base offset of the overrider's parent in the layout class.
CharUnits Offset;
-
- OverriderInfo() : Method(0), Offset(CharUnits::Zero()) { }
+
+ OverriderInfo() : Method(nullptr), VirtualBase(nullptr),
+ Offset(CharUnits::Zero()) { }
};
private:
@@ -201,6 +206,7 @@
Overrider.Offset = OverriderOffset;
Overrider.Method = Method.Method;
+ Overrider.VirtualBase = Method.InVirtualSubobject;
}
}
@@ -216,8 +222,8 @@
CharUnits NonVirtualOffset = CharUnits::Zero();
unsigned NonVirtualStart = 0;
- const CXXRecordDecl *VirtualBase = 0;
-
+ const CXXRecordDecl *VirtualBase = nullptr;
+
// First, look for the virtual base class.
for (int I = Path.size(), E = 0; I != E; --I) {
const CXXBasePathElement &Element = Path[I - 1];
@@ -1290,7 +1296,7 @@
// We don't have vcall offsets for this virtual base, go ahead and
// build them.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
- /*FinalOverriders=*/0,
+ /*FinalOverriders=*/nullptr,
BaseSubobject(Offset.VirtualBase,
CharUnits::Zero()),
/*BaseIsVirtual=*/true,
@@ -1444,8 +1450,8 @@
return OverriddenMD;
}
}
-
- return 0;
+
+ return nullptr;
}
void ItaniumVTableBuilder::AddMethods(
@@ -1499,7 +1505,7 @@
llvm_unreachable("Found a duplicate primary base!");
}
- const CXXDestructorDecl *ImplicitVirtualDtor = 0;
+ const CXXDestructorDecl *ImplicitVirtualDtor = nullptr;
typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy;
NewVirtualFunctionsTy NewVirtualFunctions;
@@ -2138,7 +2144,7 @@
ThunkInfoVectorTy ThunksVector = Thunks[MD];
std::sort(ThunksVector.begin(), ThunksVector.end(),
[](const ThunkInfo &LHS, const ThunkInfo &RHS) {
- assert(LHS.Method == 0 && RHS.Method == 0);
+ assert(LHS.Method == nullptr && RHS.Method == nullptr);
return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
});
@@ -2284,8 +2290,8 @@
VirtualBaseClassOffsetOffsets.find(ClassPair);
if (I != VirtualBaseClassOffsetOffsets.end())
return I->second;
-
- VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0,
+
+ VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/nullptr,
BaseSubobject(RD, CharUnits::Zero()),
/*BaseIsVirtual=*/false,
/*OffsetInLayoutClass=*/CharUnits::Zero());
@@ -2529,7 +2535,7 @@
// pointing to the middle of a section.
BasesSetVectorTy VisitedBases;
- AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0,
+ AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, nullptr,
VisitedBases);
assert(Components.size() && "vftable can't be empty");
@@ -2649,6 +2655,8 @@
CharUnits Ret;
bool First = true;
+ const ASTRecordLayout &OverriderRDLayout =
+ Context.getASTRecordLayout(Overrider.Method->getParent());
for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
I != E; ++I) {
const CXXBasePath &Path = (*I);
@@ -2665,19 +2673,18 @@
const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD);
if (Element.Base->isVirtual()) {
- LastVBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD);
- if (Overrider.Method->getParent() == PrevRD) {
- // This one's interesting. If the final overrider is in a vbase B of the
- // most derived class and it overrides a method of the B's own vbase A,
- // it uses A* as "this". In its prologue, it can cast A* to B* with
- // a static offset. This offset is used regardless of the actual
- // offset of A from B in the most derived class, requiring an
- // this-adjusting thunk in the vftable if A and B are laid out
- // differently in the most derived class.
- ThisOffset += Layout.getVBaseClassOffset(CurRD);
- } else {
- ThisOffset = LastVBaseOffset;
- }
+ // The interesting things begin when you have virtual inheritance.
+ // The final overrider will use a static adjustment equal to the offset
+ // of the vbase in the final overrider class.
+ // For example, if the final overrider is in a vbase B of the most
+ // derived class and it overrides a method of the B's own vbase A,
+ // it uses A* as "this". In its prologue, it can cast A* to B* with
+ // a static offset. This offset is used regardless of the actual
+ // offset of A from B in the most derived class, requiring an
+ // this-adjusting thunk in the vftable if A and B are laid out
+ // differently in the most derived class.
+ LastVBaseOffset = ThisOffset =
+ Overrider.Offset + OverriderRDLayout.getVBaseClassOffset(CurRD);
} else {
ThisOffset += Layout.getBaseClassOffset(CurRD);
}
@@ -2715,26 +2722,22 @@
VBaseMap.find(WhichVFPtr.getVBaseWithVPtr());
assert(VBaseMapEntry != VBaseMap.end());
- // Check if we need a vtordisp adjustment at all.
- if (!VBaseMapEntry->second.hasVtorDisp())
+ // If there's no vtordisp or the final overrider is defined in the same vbase
+ // as the initial declaration, we don't need any vtordisp adjustment.
+ if (!VBaseMapEntry->second.hasVtorDisp() ||
+ Overrider.VirtualBase == WhichVFPtr.getVBaseWithVPtr())
return;
- CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
+ // OK, now we know we need to use a vtordisp thunk.
// The implicit vtordisp field is located right before the vbase.
+ CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
TA.Virtual.Microsoft.VtordispOffset =
(VFPtrVBaseOffset - WhichVFPtr.FullOffsetInMDC).getQuantity() - 4;
- // If the final overrider is defined in either:
- // - the most derived class or its non-virtual base or
- // - the same vbase as the initial declaration,
- // a simple vtordisp thunk will suffice.
- const CXXRecordDecl *OverriderRD = Overrider.Method->getParent();
- if (OverriderRD == MostDerivedClass)
- return;
-
- const CXXRecordDecl *OverriderVBase =
- ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase;
- if (!OverriderVBase || OverriderVBase == WhichVFPtr.getVBaseWithVPtr())
+ // A simple vtordisp thunk will suffice if the final overrider is defined
+ // in either the most derived class or its non-virtual base.
+ if (Overrider.Method->getParent() == MostDerivedClass ||
+ !Overrider.VirtualBase)
return;
// Otherwise, we need to do use the dynamic offset of the final overrider
@@ -2744,7 +2747,7 @@
MostDerivedClassLayout.getVBPtrOffset()).getQuantity();
TA.Virtual.Microsoft.VBOffsetOffset =
Context.getTypeSizeInChars(Context.IntTy).getQuantity() *
- VTables.getVBTableIndex(MostDerivedClass, OverriderVBase);
+ VTables.getVBTableIndex(MostDerivedClass, Overrider.VirtualBase);
TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity();
}
@@ -2813,7 +2816,7 @@
// See if this class expands a vftable of the base we look at, which is either
// the one defined by the vfptr base path or the primary base of the current class.
- const CXXRecordDecl *NextBase = 0, *NextLastVBase = LastVBase;
+ const CXXRecordDecl *NextBase = nullptr, *NextLastVBase = LastVBase;
CharUnits NextBaseOffset;
if (BaseDepth < WhichVFPtr.PathToBaseWithVPtr.size()) {
NextBase = WhichVFPtr.PathToBaseWithVPtr[BaseDepth];
@@ -2942,7 +2945,7 @@
}
AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment,
- ReturnAdjustingThunk ? MD : 0));
+ ReturnAdjustingThunk ? MD : nullptr));
}
}
@@ -3174,11 +3177,7 @@
const VPtrInfoVector &BasePaths =
ForVBTables ? enumerateVBTables(Base) : getVFPtrOffsets(Base);
- for (VPtrInfoVector::const_iterator II = BasePaths.begin(),
- EE = BasePaths.end();
- II != EE; ++II) {
- VPtrInfo *BaseInfo = *II;
-
+ for (VPtrInfo *BaseInfo : BasePaths) {
// Don't include the path if it goes through a virtual base that we've
// already included.
if (setsIntersect(VBasesSeen, BaseInfo->ContainingVBases))
@@ -3196,12 +3195,16 @@
// FIXME: Why do we need this?
P->PathToBaseWithVPtr.insert(P->PathToBaseWithVPtr.begin(), Base);
- // Keep track of which derived class ultimately uses the vtable, and what
- // the full adjustment is from the MDC to this vtable. The adjustment is
- // captured by an optional vbase and a non-virtual offset.
- if (Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
+ // Keep track of which vtable the derived class is going to extend with
+ // new methods or bases. We append to either the vftable of our primary
+ // base, or the first non-virtual base that has a vbtable.
+ if (P->ReusingBase == Base &&
+ Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
: Layout.getPrimaryBase()))
P->ReusingBase = RD;
+
+ // Keep track of the full adjustment from the MDC to this vtable. The
+ // adjustment is captured by an optional vbase and a non-virtual offset.
if (B.isVirtual())
P->ContainingVBases.push_back(Base);
else if (P->ContainingVBases.empty())
@@ -3234,7 +3237,7 @@
static bool extendPath(VPtrInfo *P) {
if (P->NextBaseToMangle) {
P->MangledPath.push_back(P->NextBaseToMangle);
- P->NextBaseToMangle = 0; // Prevent the path from being extended twice.
+ P->NextBaseToMangle = nullptr;// Prevent the path from being extended twice.
return true;
}
return false;
@@ -3272,6 +3275,8 @@
}
MicrosoftVTableContext::~MicrosoftVTableContext() {
+ for (auto &P : VFPtrLocations)
+ llvm::DeleteContainerPointers(*P.second);
llvm::DeleteContainerSeconds(VFPtrLocations);
llvm::DeleteContainerSeconds(VFTableLayouts);
llvm::DeleteContainerSeconds(VBaseInfo);