summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/VTableBuilder.cpp
diff options
context:
space:
mode:
authorTimur Iskhodzhanov <timurrrr@google.com>2013-10-16 18:24:06 +0000
committerTimur Iskhodzhanov <timurrrr@google.com>2013-10-16 18:24:06 +0000
commit62082b7e0b0b7a299524f6191ddbfd62ed6b17d8 (patch)
treea9d6f794874454fd7ef804838ab554867a3aa9e6 /clang/lib/AST/VTableBuilder.cpp
parent84355db7f9dc50cec5de4127d03fc40a84772f78 (diff)
downloadbcm5719-llvm-62082b7e0b0b7a299524f6191ddbfd62ed6b17d8.tar.gz
bcm5719-llvm-62082b7e0b0b7a299524f6191ddbfd62ed6b17d8.zip
[-cxx-abi microsoft] Fix this argument/parameter offsets for virtual destructors in the presence of virtual bases
Reviewed at http://llvm-reviews.chandlerc.com/D1939 llvm-svn: 192822
Diffstat (limited to 'clang/lib/AST/VTableBuilder.cpp')
-rw-r--r--clang/lib/AST/VTableBuilder.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 045b7f1a42d..2da089186c9 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -2668,11 +2668,6 @@ CharUnits
VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
BaseSubobject Base,
FinalOverriders::OverriderInfo Overrider) {
- // Complete object virtual destructors are always emitted in the most derived
- // class, thus don't have this offset.
- if (isa<CXXDestructorDecl>(MD))
- return CharUnits();
-
InitialOverriddenDefinitionCollector Collector;
visitAllOverriddenMethods(MD, Collector);
@@ -2690,6 +2685,7 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
I != E; ++I) {
const CXXBasePath &Path = (*I);
CharUnits ThisOffset = Base.getBaseOffset();
+ bool SeenVBase = false;
// For each path from the overrider to the parents of the overridden methods,
// traverse the path, calculating the this offset in the most derived class.
@@ -2701,6 +2697,7 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD);
if (Element.Base->isVirtual()) {
+ SeenVBase = true;
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,
@@ -2713,11 +2710,22 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
} else {
ThisOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD);
}
+
+ // A virtual destructor of a virtual base takes the address of the
+ // virtual base subobject as the "this" argument.
+ if (isa<CXXDestructorDecl>(MD))
+ break;
} else {
ThisOffset += Layout.getBaseClassOffset(CurRD);
}
}
+ // If a "Base" class has at least one non-virtual base with a virtual
+ // destructor, the "Base" virtual destructor will take the address of the
+ // "Base" subobject as the "this" argument.
+ if (!SeenVBase && isa<CXXDestructorDecl>(MD))
+ return Base.getBaseOffset();
+
if (Ret > ThisOffset || First) {
First = false;
Ret = ThisOffset;
OpenPOWER on IntegriCloud