1//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code dealing with generation of the layout of virtual table
11// tables (VTT).
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_VTTBUILDER_H
16#define LLVM_CLANG_AST_VTTBUILDER_H
17
18#include "clang/AST/BaseSubobject.h"
19#include "clang/AST/CXXInheritance.h"
20#include "clang/AST/GlobalDecl.h"
21#include "clang/AST/RecordLayout.h"
22#include "clang/Basic/ABI.h"
23#include <utility>
24
25namespace clang {
26
27class VTTVTable {
28  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
29  CharUnits BaseOffset;
30
31public:
32  VTTVTable() {}
33  VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
34    : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
35  VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
36    : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
37      BaseOffset(Base.getBaseOffset()) {}
38
39  const CXXRecordDecl *getBase() const {
40    return BaseAndIsVirtual.getPointer();
41  }
42
43  CharUnits getBaseOffset() const {
44    return BaseOffset;
45  }
46
47  bool isVirtual() const {
48    return BaseAndIsVirtual.getInt();
49  }
50
51  BaseSubobject getBaseSubobject() const {
52    return BaseSubobject(getBase(), getBaseOffset());
53  }
54};
55
56struct VTTComponent {
57  uint64_t VTableIndex;
58  BaseSubobject VTableBase;
59
60  VTTComponent() {}
61  VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
62    : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
63};
64
65/// \brief Class for building VTT layout information.
66class VTTBuilder {
67
68  ASTContext &Ctx;
69
70  /// \brief The most derived class for which we're building this vtable.
71  const CXXRecordDecl *MostDerivedClass;
72
73  typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
74
75  /// \brief The VTT vtables.
76  VTTVTablesVectorTy VTTVTables;
77
78  typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
79
80  /// \brief The VTT components.
81  VTTComponentsVectorTy VTTComponents;
82
83  /// \brief The AST record layout of the most derived class.
84  const ASTRecordLayout &MostDerivedClassLayout;
85
86  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
87
88  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
89
90  /// \brief The sub-VTT indices for the bases of the most derived class.
91  llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
92
93  /// \brief The secondary virtual pointer indices of all subobjects of
94  /// the most derived class.
95  llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
96
97  /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
98  bool GenerateDefinition;
99
100  /// \brief Add a vtable pointer to the VTT currently being built.
101  void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
102                        const CXXRecordDecl *VTableClass);
103
104  /// \brief Lay out the secondary VTTs of the given base subobject.
105  void LayoutSecondaryVTTs(BaseSubobject Base);
106
107  /// \brief Lay out the secondary virtual pointers for the given base
108  /// subobject.
109  ///
110  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
111  /// or a direct or indirect base of a virtual base.
112  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
113                                      bool BaseIsMorallyVirtual,
114                                      uint64_t VTableIndex,
115                                      const CXXRecordDecl *VTableClass,
116                                      VisitedVirtualBasesSetTy &VBases);
117
118  /// \brief Lay out the secondary virtual pointers for the given base
119  /// subobject.
120  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
121                                      uint64_t VTableIndex);
122
123  /// \brief Lay out the VTTs for the virtual base classes of the given
124  /// record declaration.
125  void LayoutVirtualVTTs(const CXXRecordDecl *RD,
126                         VisitedVirtualBasesSetTy &VBases);
127
128  /// \brief Lay out the VTT for the given subobject, including any
129  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
130  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
131
132public:
133  VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
134             bool GenerateDefinition);
135
136  // \brief Returns a reference to the VTT components.
137  const VTTComponentsVectorTy &getVTTComponents() const {
138    return VTTComponents;
139  }
140
141  // \brief Returns a reference to the VTT vtables.
142  const VTTVTablesVectorTy &getVTTVTables() const {
143    return VTTVTables;
144  }
145
146  /// \brief Returns a reference to the sub-VTT indices.
147  const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
148    return SubVTTIndicies;
149  }
150
151  /// \brief Returns a reference to the secondary virtual pointer indices.
152  const llvm::DenseMap<BaseSubobject, uint64_t> &
153  getSecondaryVirtualPointerIndices() const {
154    return SecondaryVirtualPointerIndices;
155  }
156
157};
158
159}
160
161#endif
162