blob: b4a6fe3bdb942550401a8c53e93bb5c8153a76e1 [file] [log] [blame]
//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
// The LLVM Compiler Infrastructure
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This contains code dealing with generation of the layout of virtual table
// tables (VTT).
#include "clang/AST/BaseSubobject.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
#include <utility>
namespace clang {
class VTTVTable {
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
CharUnits BaseOffset;
VTTVTable() {}
VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
: BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
: BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
BaseOffset(Base.getBaseOffset()) {}
const CXXRecordDecl *getBase() const {
return BaseAndIsVirtual.getPointer();
CharUnits getBaseOffset() const {
return BaseOffset;
bool isVirtual() const {
return BaseAndIsVirtual.getInt();
BaseSubobject getBaseSubobject() const {
return BaseSubobject(getBase(), getBaseOffset());
struct VTTComponent {
uint64_t VTableIndex;
BaseSubobject VTableBase;
VTTComponent() {}
VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
: VTableIndex(VTableIndex), VTableBase(VTableBase) {}
/// \brief Class for building VTT layout information.
class VTTBuilder {
ASTContext &Ctx;
/// \brief The most derived class for which we're building this vtable.
const CXXRecordDecl *MostDerivedClass;
typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
/// \brief The VTT vtables.
VTTVTablesVectorTy VTTVTables;
typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
/// \brief The VTT components.
VTTComponentsVectorTy VTTComponents;
/// \brief The AST record layout of the most derived class.
const ASTRecordLayout &MostDerivedClassLayout;
typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
/// \brief The sub-VTT indices for the bases of the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
/// \brief The secondary virtual pointer indices of all subobjects of
/// the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
/// \brief Whether the VTT builder should generate LLVM IR for the VTT.
bool GenerateDefinition;
/// \brief Add a vtable pointer to the VTT currently being built.
void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
const CXXRecordDecl *VTableClass);
/// \brief Lay out the secondary VTTs of the given base subobject.
void LayoutSecondaryVTTs(BaseSubobject Base);
/// \brief Lay out the secondary virtual pointers for the given base
/// subobject.
/// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
/// or a direct or indirect base of a virtual base.
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
bool BaseIsMorallyVirtual,
uint64_t VTableIndex,
const CXXRecordDecl *VTableClass,
VisitedVirtualBasesSetTy &VBases);
/// \brief Lay out the secondary virtual pointers for the given base
/// subobject.
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
uint64_t VTableIndex);
/// \brief Lay out the VTTs for the virtual base classes of the given
/// record declaration.
void LayoutVirtualVTTs(const CXXRecordDecl *RD,
VisitedVirtualBasesSetTy &VBases);
/// \brief Lay out the VTT for the given subobject, including any
/// secondary VTTs, secondary virtual pointers and virtual VTTs.
void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition);
// \brief Returns a reference to the VTT components.
const VTTComponentsVectorTy &getVTTComponents() const {
return VTTComponents;
// \brief Returns a reference to the VTT vtables.
const VTTVTablesVectorTy &getVTTVTables() const {
return VTTVTables;
/// \brief Returns a reference to the sub-VTT indices.
const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
return SubVTTIndicies;
/// \brief Returns a reference to the secondary virtual pointer indices.
const llvm::DenseMap<BaseSubobject, uint64_t> &
getSecondaryVirtualPointerIndices() const {
return SecondaryVirtualPointerIndices;