From 46170f9c7d561d0f94af34a4b5da909d2584370a Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 24 Nov 2010 22:50:27 +0000 Subject: [PATCH] Add CXXRecordDecl::getIndirectPrimaryBases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120129 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/CXXInheritance.h | 7 +++- include/clang/AST/DeclCXX.h | 4 +++ lib/AST/CXXInheritance.cpp | 48 +++++++++++++++++++++++++++ lib/CodeGen/CGRecordLayoutBuilder.cpp | 7 +++- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 5a84e404a1..2d30cb3b8b 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -20,6 +20,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include #include @@ -359,7 +360,11 @@ public: /// subobjects of that type. class CXXFinalOverriderMap : public llvm::DenseMap { }; - + +/// \brief A set of all the primary bases for a class. +class CXXIndirectPrimaryBaseSet + : public llvm::SmallSet { }; + } // end namespace clang #endif diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 53f04fd79a..0a7e755a9a 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -35,6 +35,7 @@ class CXXMethodDecl; class CXXRecordDecl; class CXXMemberLookupCriteria; class CXXFinalOverriderMap; +class CXXIndirectPrimaryBaseSet; class FriendDecl; /// \brief Represents any kind of function declaration, whether it is a @@ -955,6 +956,9 @@ public: /// most-derived class in the class hierarchy. void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const; + /// \brief Get the indirect primary bases for this class. + void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const; + /// viewInheritance - Renders and displays an inheritance diagram /// for this C++ class and all of its base classes (transitively) using /// GraphViz. 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 #include @@ -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(I->getType()->getAs()->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(I->getType()->getAs()->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 LLVMBaseInfo; llvm::SmallVector 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; -- 2.40.0