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