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 
21 namespace clang {
22 
23 /// C++ constructor types.
24 enum 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.
33 enum 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.
41 struct 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.
107 struct 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 
174 class CXXMethodDecl;
175 
176 /// The \c this pointer adjustment as well as an optional return
177 /// adjustment for a thunk.
178 struct 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