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