Coverage Report

Created: 2023-11-11 10:31

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