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
21namespace clang {
22
23class CXXMethodDecl;
24
25/// A return adjustment.
26struct ReturnAdjustment {
27 /// The non-virtual adjustment from the derived object to its
28 /// nearest virtual base.
29 int64_t NonVirtual = 0;
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 VirtualAdjustment() { memset(s: this, c: 0, n: sizeof(*this)); }
52
53 bool Equals(const VirtualAdjustment &Other) const {
54 return memcmp(s1: this, s2: &Other, n: sizeof(Other)) == 0;
55 }
56
57 bool isEmpty() const {
58 VirtualAdjustment Zero;
59 return Equals(Other: Zero);
60 }
61
62 bool Less(const VirtualAdjustment &RHS) const {
63 return memcmp(s1: this, s2: &RHS, n: sizeof(RHS)) < 0;
64 }
65 } Virtual;
66
67 ReturnAdjustment() = default;
68
69 bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
70
71 friend bool operator==(const ReturnAdjustment &LHS,
72 const ReturnAdjustment &RHS) {
73 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(Other: RHS.Virtual);
74 }
75
76 friend bool operator!=(const ReturnAdjustment &LHS,
77 const ReturnAdjustment &RHS) {
78 return !(LHS == RHS);
79 }
80
81 friend bool operator<(const ReturnAdjustment &LHS,
82 const ReturnAdjustment &RHS) {
83 if (LHS.NonVirtual < RHS.NonVirtual)
84 return true;
85
86 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS: RHS.Virtual);
87 }
88};
89
90/// A \c this pointer adjustment.
91struct ThisAdjustment {
92 /// The non-virtual adjustment from the derived object to its
93 /// nearest virtual base.
94 int64_t NonVirtual = 0;
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 VirtualAdjustment() { memset(s: this, c: 0, n: sizeof(*this)); }
119
120 bool Equals(const VirtualAdjustment &Other) const {
121 return memcmp(s1: this, s2: &Other, n: sizeof(Other)) == 0;
122 }
123
124 bool isEmpty() const {
125 VirtualAdjustment Zero;
126 return Equals(Other: Zero);
127 }
128
129 bool Less(const VirtualAdjustment &RHS) const {
130 return memcmp(s1: this, s2: &RHS, n: sizeof(RHS)) < 0;
131 }
132 } Virtual;
133
134 ThisAdjustment() = default;
135
136 bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
137
138 friend bool operator==(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
139 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(Other: RHS.Virtual);
140 }
141
142 friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
143 return !(LHS == RHS);
144 }
145
146 friend bool operator<(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
147 if (LHS.NonVirtual < RHS.NonVirtual)
148 return true;
149
150 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS: RHS.Virtual);
151 }
152};
153
154/// The \c this pointer adjustment as well as an optional return
155/// adjustment for a thunk.
156struct 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 ThunkInfo() : Method(nullptr) {}
171
172 ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
173 const CXXMethodDecl *Method = nullptr)
174 : This(This), Return(Return), Method(Method) {}
175
176 friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
177 return LHS.This == RHS.This && LHS.Return == RHS.Return &&
178 LHS.Method == RHS.Method;
179 }
180
181 bool isEmpty() const {
182 return This.isEmpty() && Return.isEmpty() && Method == nullptr;
183 }
184};
185
186} // end namespace clang
187
188#endif
189

source code of clang/include/clang/Basic/Thunk.h