aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/CXXInheritance.cpp48
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp7
2 files changed, 54 insertions, 1 deletions
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index c563c37d58..90a214ed8e 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/RecordLayout.h"
#include "clang/AST/DeclCXX.h"
#include <algorithm>
#include <set>
@@ -662,3 +663,50 @@ CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
}
}
}
+
+static void
+AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
+ CXXIndirectPrimaryBaseSet& Bases) {
+ // If the record has a virtual primary base class, add it to our set.
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+ if (Layout.getPrimaryBaseWasVirtual())
+ Bases.insert(Layout.getPrimaryBase());
+
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ assert(!E->getType()->isDependentType() &&
+ "Cannot get indirect primary bases for class with dependent bases.");
+
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // Only bases with virtual bases participate in computing the
+ // indirect primary virtual base classes.
+ if (BaseDecl->getNumVBases())
+ AddIndirectPrimaryBases(BaseDecl, Context, Bases);
+ }
+
+}
+
+void
+CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const {
+ ASTContext &Context = getASTContext();
+
+ if (!getNumVBases())
+ return;
+
+ for (CXXRecordDecl::base_class_const_iterator I = bases_begin(),
+ E = bases_end(); I != E; ++I) {
+ assert(!E->getType()->isDependentType() &&
+ "Cannot get indirect primary bases for class with dependent bases.");
+
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // Only bases with virtual bases participate in computing the
+ // indirect primary virtual base classes.
+ if (BaseDecl->getNumVBases())
+ AddIndirectPrimaryBases(BaseDecl, Context, Bases);
+ }
+}
+
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index f846fca506..fcaf1e112d 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -14,6 +14,7 @@
#include "CGRecordLayout.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
@@ -63,7 +64,11 @@ public:
typedef std::pair<const CXXRecordDecl *, unsigned> LLVMBaseInfo;
llvm::SmallVector<LLVMBaseInfo, 16> LLVMNonVirtualBases;
-
+
+ /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
+ /// primary base classes for some other direct or indirect base class.
+ CXXIndirectPrimaryBaseSet IndirectPrimaryBases;
+
/// IsZeroInitializable - Whether this struct can be C++
/// zero-initialized with an LLVM zeroinitializer.
bool IsZeroInitializable;