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