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 "llvm/ADT/SetVector.h"
24#include <utility>
25
26namespace clang {
27
28class VTTVTable {
29  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
30  CharUnits BaseOffset;
31
32public:
33  VTTVTable() {}
34  VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
35    : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
36  VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
37    : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
38      BaseOffset(Base.getBaseOffset()) {}
39
40  const CXXRecordDecl *getBase() const {
41    return BaseAndIsVirtual.getPointer();
42  }
43
44  CharUnits getBaseOffset() const {
45    return BaseOffset;
46  }
47
48  bool isVirtual() const {
49    return BaseAndIsVirtual.getInt();
50  }
51
52  BaseSubobject getBaseSubobject() const {
53    return BaseSubobject(getBase(), getBaseOffset());
54  }
55};
56
57struct VTTComponent {
58  uint64_t VTableIndex;
59  BaseSubobject VTableBase;
60
61  VTTComponent() {}
62  VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
63    : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
64};
65
66/// VTT builder - Class for building VTT layout information.
67class VTTBuilder {
68
69  ASTContext &Ctx;
70
71  /// MostDerivedClass - The most derived class for which we're building this
72  /// vtable.
73  const CXXRecordDecl *MostDerivedClass;
74
75  typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
76
77  /// VTTVTables - The VTT vtables.
78  VTTVTablesVectorTy VTTVTables;
79
80  typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
81
82  /// VTTComponents - The VTT components.
83  VTTComponentsVectorTy VTTComponents;
84
85  /// MostDerivedClassLayout - the AST record layout of the most derived class.
86  const ASTRecordLayout &MostDerivedClassLayout;
87
88  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
89
90  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
91
92  /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
93  /// class.
94  llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
95
96  /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
97  /// all subobjects of the most derived class.
98  llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
99
100  /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
101  /// the VTT.
102  bool GenerateDefinition;
103
104  /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
105  ///
106  /// \param AddressPoints - If the vtable is a construction vtable, this has
107  /// the address points for it.
108  void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
109                        const CXXRecordDecl *VTableClass);
110
111  /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
112  /// subobject.
113  void LayoutSecondaryVTTs(BaseSubobject Base);
114
115  /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
116  /// for the given base subobject.
117  ///
118  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
119  /// or a direct or indirect base of a virtual base.
120  ///
121  /// \param AddressPoints - If the vtable is a construction vtable, this has
122  /// the address points for it.
123  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
124                                      bool BaseIsMorallyVirtual,
125                                      uint64_t VTableIndex,
126                                      const CXXRecordDecl *VTableClass,
127                                      VisitedVirtualBasesSetTy &VBases);
128
129  /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
130  /// for the given base subobject.
131  ///
132  /// \param AddressPoints - If the vtable is a construction vtable, this has
133  /// the address points for it.
134  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
135                                      uint64_t VTableIndex);
136
137  /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
138  /// given record decl.
139  void LayoutVirtualVTTs(const CXXRecordDecl *RD,
140                         VisitedVirtualBasesSetTy &VBases);
141
142  /// LayoutVTT - Will lay out the VTT for the given subobject, including any
143  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
144  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
145
146public:
147  VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
148             bool GenerateDefinition);
149
150  // getVTTComponents - Returns a reference to the VTT components.
151  const VTTComponentsVectorTy &getVTTComponents() const {
152    return VTTComponents;
153  }
154
155  // getVTTVTables - Returns a reference to the VTT vtables.
156  const VTTVTablesVectorTy &getVTTVTables() const {
157    return VTTVTables;
158  }
159
160  /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
161  const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
162    return SubVTTIndicies;
163  }
164
165  /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
166  /// virtual pointer indices.
167  const llvm::DenseMap<BaseSubobject, uint64_t> &
168  getSecondaryVirtualPointerIndices() const {
169    return SecondaryVirtualPointerIndices;
170  }
171
172};
173
174}
175
176#endif
177