1//===----- ABI.h - ABI related declarations ---------------------*- 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 ABI related information about constructors,
11/// destructors and thunks.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_ABI_H
16#define LLVM_CLANG_BASIC_ABI_H
17
18#include "llvm/Support/DataTypes.h"
19#include <cstring>
20
21namespace clang {
22
23/// C++ constructor types.
24enum CXXCtorType {
25 Ctor_Complete, ///< Complete object ctor
26 Ctor_Base, ///< Base object ctor
27 Ctor_Comdat, ///< The COMDAT used for ctors
28 Ctor_CopyingClosure, ///< Copying closure variant of a ctor
29 Ctor_DefaultClosure, ///< Default closure variant of a ctor
30};
31
32/// C++ destructor types.
33enum CXXDtorType {
34 Dtor_Deleting, ///< Deleting dtor
35 Dtor_Complete, ///< Complete object dtor
36 Dtor_Base, ///< Base object dtor
37 Dtor_Comdat ///< The COMDAT used for dtors
38};
39
40/// A return adjustment.
41struct ReturnAdjustment {
42 /// The non-virtual adjustment from the derived object to its
43 /// nearest virtual base.
44 int64_t NonVirtual;
45
46 /// Holds the ABI-specific information about the virtual return
47 /// adjustment, if needed.
48 union VirtualAdjustment {
49 // Itanium ABI
50 struct {
51 /// The offset (in bytes), relative to the address point
52 /// of the virtual base class offset.
53 int64_t VBaseOffsetOffset;
54 } Itanium;
55
56 // Microsoft ABI
57 struct {
58 /// The offset (in bytes) of the vbptr, relative to the beginning
59 /// of the derived class.
60 uint32_t VBPtrOffset;
61
62 /// Index of the virtual base in the vbtable.
63 uint32_t VBIndex;
64 } Microsoft;
65
66 VirtualAdjustment() {
67 memset(this, 0, sizeof(*this));
68 }
69
70 bool Equals(const VirtualAdjustment &Other) const {
71 return memcmp(this, &Other, sizeof(Other)) == 0;
72 }
73
74 bool isEmpty() const {
75 VirtualAdjustment Zero;
76 return Equals(Zero);
77 }
78
79 bool Less(const VirtualAdjustment &RHS) const {
80 return memcmp(this, &RHS, sizeof(RHS)) < 0;
81 }
82 } Virtual;
83
84 ReturnAdjustment() : NonVirtual(0) {}
85
86 bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
87
88 friend bool operator==(const ReturnAdjustment &LHS,
89 const ReturnAdjustment &RHS) {
90 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
91 }
92
93 friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) {
94 return !(LHS == RHS);
95 }
96
97 friend bool operator<(const ReturnAdjustment &LHS,
98 const ReturnAdjustment &RHS) {
99 if (LHS.NonVirtual < RHS.NonVirtual)
100 return true;
101
102 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
103 }
104};
105
106/// A \c this pointer adjustment.
107struct ThisAdjustment {
108 /// The non-virtual adjustment from the derived object to its
109 /// nearest virtual base.
110 int64_t NonVirtual;
111
112 /// Holds the ABI-specific information about the virtual this
113 /// adjustment, if needed.
114 union VirtualAdjustment {
115 // Itanium ABI
116 struct {
117 /// The offset (in bytes), relative to the address point,
118 /// of the virtual call offset.
119 int64_t VCallOffsetOffset;
120 } Itanium;
121
122 struct {
123 /// The offset of the vtordisp (in bytes), relative to the ECX.
124 int32_t VtordispOffset;
125
126 /// The offset of the vbptr of the derived class (in bytes),
127 /// relative to the ECX after vtordisp adjustment.
128 int32_t VBPtrOffset;
129
130 /// The offset (in bytes) of the vbase offset in the vbtable.
131 int32_t VBOffsetOffset;
132 } Microsoft;
133
134 VirtualAdjustment() {
135 memset(this, 0, sizeof(*this));
136 }
137
138 bool Equals(const VirtualAdjustment &Other) const {
139 return memcmp(this, &Other, sizeof(Other)) == 0;
140 }
141
142 bool isEmpty() const {
143 VirtualAdjustment Zero;
144 return Equals(Zero);
145 }
146
147 bool Less(const VirtualAdjustment &RHS) const {
148 return memcmp(this, &RHS, sizeof(RHS)) < 0;
149 }
150 } Virtual;
151
152 ThisAdjustment() : NonVirtual(0) { }
153
154 bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
155
156 friend bool operator==(const ThisAdjustment &LHS,
157 const ThisAdjustment &RHS) {
158 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
159 }
160
161 friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
162 return !(LHS == RHS);
163 }
164
165 friend bool operator<(const ThisAdjustment &LHS,
166 const ThisAdjustment &RHS) {
167 if (LHS.NonVirtual < RHS.NonVirtual)
168 return true;
169
170 return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
171 }
172};
173
174class CXXMethodDecl;
175
176/// The \c this pointer adjustment as well as an optional return
177/// adjustment for a thunk.
178struct ThunkInfo {
179 /// The \c this pointer adjustment.
180 ThisAdjustment This;
181
182 /// The return adjustment.
183 ReturnAdjustment Return;
184
185 /// Holds a pointer to the overridden method this thunk is for,
186 /// if needed by the ABI to distinguish different thunks with equal
187 /// adjustments. Otherwise, null.
188 /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
189 /// an ABI-specific comparator.
190 const CXXMethodDecl *Method;
191
192 ThunkInfo() : Method(nullptr) { }
193
194 ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
195 const CXXMethodDecl *Method = nullptr)
196 : This(This), Return(Return), Method(Method) {}
197
198 friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
199 return LHS.This == RHS.This && LHS.Return == RHS.Return &&
200 LHS.Method == RHS.Method;
201 }
202
203 bool isEmpty() const {
204 return This.isEmpty() && Return.isEmpty() && Method == nullptr;
205 }
206};
207
208} // end namespace clang
209
210#endif
211