Coverage Report

Created: 2021-09-21 08:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/Thunk.h
Line
Count
Source (jump to first uncovered line)
1
//===----- Thunk.h - Declarations related to VTable Thunks ------*- 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
/// \file
10
/// Enums/classes describing THUNK related information about constructors,
11
/// destructors and thunks.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_BASIC_THUNK_H
16
#define LLVM_CLANG_BASIC_THUNK_H
17
18
#include <cstdint>
19
#include <cstring>
20
21
namespace clang {
22
23
class CXXMethodDecl;
24
25
/// A return adjustment.
26
struct ReturnAdjustment {
27
  /// The non-virtual adjustment from the derived object to its
28
  /// nearest virtual base.
29
  int64_t NonVirtual;
30
31
  /// Holds the ABI-specific information about the virtual return
32
  /// adjustment, if needed.
33
  union VirtualAdjustment {
34
    // Itanium ABI
35
    struct {
36
      /// The offset (in bytes), relative to the address point
37
      /// of the virtual base class offset.
38
      int64_t VBaseOffsetOffset;
39
    } Itanium;
40
41
    // Microsoft ABI
42
    struct {
43
      /// The offset (in bytes) of the vbptr, relative to the beginning
44
      /// of the derived class.
45
      uint32_t VBPtrOffset;
46
47
      /// Index of the virtual base in the vbtable.
48
      uint32_t VBIndex;
49
    } Microsoft;
50
51
64.6k
    VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
52
53
32.9k
    bool Equals(const VirtualAdjustment &Other) const {
54
32.9k
      return memcmp(this, &Other, sizeof(Other)) == 0;
55
32.9k
    }
56
57
32.8k
    bool isEmpty() const {
58
32.8k
      VirtualAdjustment Zero;
59
32.8k
      return Equals(Zero);
60
32.8k
    }
61
62
14
    bool Less(const VirtualAdjustment &RHS) const {
63
14
      return memcmp(this, &RHS, sizeof(RHS)) < 0;
64
14
    }
65
  } Virtual;
66
67
31.8k
  ReturnAdjustment() : NonVirtual(0) {}
68
69
33.0k
  bool isEmpty() const { return !NonVirtual && 
Virtual.isEmpty()32.8k
; }
70
71
  friend bool operator==(const ReturnAdjustment &LHS,
72
120
                         const ReturnAdjustment &RHS) {
73
120
    return LHS.NonVirtual == RHS.NonVirtual && 
LHS.Virtual.Equals(RHS.Virtual)101
;
74
120
  }
75
76
  friend bool operator!=(const ReturnAdjustment &LHS,
77
0
                         const ReturnAdjustment &RHS) {
78
0
    return !(LHS == RHS);
79
0
  }
80
81
  friend bool operator<(const ReturnAdjustment &LHS,
82
27
                        const ReturnAdjustment &RHS) {
83
27
    if (LHS.NonVirtual < RHS.NonVirtual)
84
13
      return true;
85
86
14
    return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
87
27
  }
88
};
89
90
/// A \c this pointer adjustment.
91
struct ThisAdjustment {
92
  /// The non-virtual adjustment from the derived object to its
93
  /// nearest virtual base.
94
  int64_t NonVirtual;
95
96
  /// Holds the ABI-specific information about the virtual this
97
  /// adjustment, if needed.
98
  union VirtualAdjustment {
99
    // Itanium ABI
100
    struct {
101
      /// The offset (in bytes), relative to the address point,
102
      /// of the virtual call offset.
103
      int64_t VCallOffsetOffset;
104
    } Itanium;
105
106
    struct {
107
      /// The offset of the vtordisp (in bytes), relative to the ECX.
108
      int32_t VtordispOffset;
109
110
      /// The offset of the vbptr of the derived class (in bytes),
111
      /// relative to the ECX after vtordisp adjustment.
112
      int32_t VBPtrOffset;
113
114
      /// The offset (in bytes) of the vbase offset in the vbtable.
115
      int32_t VBOffsetOffset;
116
    } Microsoft;
117
118
30.3k
    VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
119
120
4.39k
    bool Equals(const VirtualAdjustment &Other) const {
121
4.39k
      return memcmp(this, &Other, sizeof(Other)) == 0;
122
4.39k
    }
123
124
4.26k
    bool isEmpty() const {
125
4.26k
      VirtualAdjustment Zero;
126
4.26k
      return Equals(Zero);
127
4.26k
    }
128
129
48
    bool Less(const VirtualAdjustment &RHS) const {
130
48
      return memcmp(this, &RHS, sizeof(RHS)) < 0;
131
48
    }
132
  } Virtual;
133
134
26.0k
  ThisAdjustment() : NonVirtual(0) {}
135
136
4.34k
  bool isEmpty() const { return !NonVirtual && 
Virtual.isEmpty()3.34k
; }
137
138
147
  friend bool operator==(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
139
147
    return LHS.NonVirtual == RHS.NonVirtual && 
LHS.Virtual.Equals(RHS.Virtual)128
;
140
147
  }
141
142
0
  friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
143
0
    return !(LHS == RHS);
144
0
  }
145
146
62
  friend bool operator<(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
147
62
    if (LHS.NonVirtual < RHS.NonVirtual)
148
9
      return true;
149
150
53
    return LHS.NonVirtual == RHS.NonVirtual && 
LHS.Virtual.Less(RHS.Virtual)48
;
151
62
  }
152
};
153
154
/// The \c this pointer adjustment as well as an optional return
155
/// adjustment for a thunk.
156
struct ThunkInfo {
157
  /// The \c this pointer adjustment.
158
  ThisAdjustment This;
159
160
  /// The return adjustment.
161
  ReturnAdjustment Return;
162
163
  /// Holds a pointer to the overridden method this thunk is for,
164
  /// if needed by the ABI to distinguish different thunks with equal
165
  /// adjustments. Otherwise, null.
166
  /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
167
  /// an ABI-specific comparator.
168
  const CXXMethodDecl *Method;
169
170
16.1k
  ThunkInfo() : Method(nullptr) {}
171
172
  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
173
            const CXXMethodDecl *Method = nullptr)
174
1.95k
      : This(This), Return(Return), Method(Method) {}
175
176
147
  friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
177
147
    return LHS.This == RHS.This && 
LHS.Return == RHS.Return120
&&
178
147
           
LHS.Method == RHS.Method88
;
179
147
  }
180
181
3.02k
  bool isEmpty() const {
182
3.02k
    return This.isEmpty() && 
Return.isEmpty()2.50k
&&
Method == nullptr2.42k
;
183
3.02k
  }
184
};
185
186
} // end namespace clang
187
188
#endif