19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===// 29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// 39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// The LLVM Compiler Infrastructure 49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// 59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// This file is distributed under the University of Illinois Open Source 69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// License. See LICENSE.TXT for details. 79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// 89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//===----------------------------------------------------------------------===// 99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// 109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// \file 119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// \brief Enums/classes describing ABI related information about constructors, 129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// destructors and thunks. 139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// 149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//===----------------------------------------------------------------------===// 159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifndef CLANG_BASIC_ABI_H 179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#define CLANG_BASIC_ABI_H 189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "llvm/Support/DataTypes.h" 209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comnamespace clang { 229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// \brief C++ constructor types. 249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comenum CXXCtorType { 259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Ctor_Complete, ///< Complete object ctor 269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Ctor_Base, ///< Base object ctor 279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Ctor_CompleteAllocating ///< Complete object allocating ctor 289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}; 299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// \brief C++ destructor types. 319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comenum CXXDtorType { 329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Dtor_Deleting, ///< Deleting dtor 339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com Dtor_Complete, ///< Complete object dtor 349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Dtor_Base ///< Base object dtor 359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}; 369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/// \brief A return adjustment. 389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comstruct ReturnAdjustment { 399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /// \brief The non-virtual adjustment from the derived object to its 409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /// nearest virtual base. 419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int64_t NonVirtual; 429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 439d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /// \brief Holds the ABI-specific information about the virtual return 449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /// adjustment, if needed. 459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com union VirtualAdjustment { 469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Itanium ABI 479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com struct { 489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /// \brief The offset (in bytes), relative to the address point 499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com /// of the virtual base class offset. 509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com int64_t VBaseOffsetOffset; 519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } Itanium; 529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // Microsoft ABI 549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com struct { 559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com /// \brief The offset (in bytes) of the vbptr, relative to the beginning 569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com /// of the derived class. 579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com uint32_t VBPtrOffset; 589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com /// \brief Index of the virtual base in the vbtable. 609d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com uint32_t VBIndex; 619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } Microsoft; 629d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com VirtualAdjustment() { 649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com memset(this, 0, sizeof(*this)); 659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com bool Equals(const VirtualAdjustment &Other) const { 689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return memcmp(this, &Other, sizeof(Other)) == 0; 699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 709258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 719258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org bool isEmpty() const { 729258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org VirtualAdjustment Zero; 739d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return Equals(Zero); 749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 759258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 769258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org bool Less(const VirtualAdjustment &RHS) const { 779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return memcmp(this, &RHS, sizeof(RHS)) < 0; 789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } Virtual; 809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 819d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ReturnAdjustment() : NonVirtual(0) {} 829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 839258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); } 849258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 859d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com friend bool operator==(const ReturnAdjustment &LHS, 869258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org const ReturnAdjustment &RHS) { 8740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual); 8840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } 8940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 9040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) { 9140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org return !(LHS == RHS); 9240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } 9340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 9440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org friend bool operator<(const ReturnAdjustment &LHS, 9540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org const ReturnAdjustment &RHS) { 9640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org if (LHS.NonVirtual < RHS.NonVirtual) 9740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org return true; 9840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 9940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual); 10040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } 10140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org}; 10240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 10340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org/// \brief A \c this pointer adjustment. 10440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.orgstruct ThisAdjustment { 10540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// \brief The non-virtual adjustment from the derived object to its 10640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// nearest virtual base. 10740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org int64_t NonVirtual; 10840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 10940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// \brief Holds the ABI-specific information about the virtual this 11040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// adjustment, if needed. 11140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org union VirtualAdjustment { 11240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // Itanium ABI 11340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org struct { 11440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// \brief The offset (in bytes), relative to the address point, 11540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// of the virtual call offset. 11640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org int64_t VCallOffsetOffset; 11740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } Itanium; 11840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 11940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org struct { 12040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org /// \brief The offset of the vtordisp (in bytes), relative to the ECX. 12140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org 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 171class CXXMethodDecl; 172 173/// \brief The \c this pointer adjustment as well as an optional return 174/// adjustment for a thunk. 175struct 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