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