Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:51

0001 //===----- Thunk.h - Declarations related to VTable Thunks ------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Enums/classes describing THUNK related information about constructors,
0011 /// destructors and thunks.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_BASIC_THUNK_H
0016 #define LLVM_CLANG_BASIC_THUNK_H
0017 
0018 #include <cstdint>
0019 #include <cstring>
0020 
0021 namespace clang {
0022 
0023 class CXXMethodDecl;
0024 class Type;
0025 
0026 /// A return adjustment.
0027 struct ReturnAdjustment {
0028   /// The non-virtual adjustment from the derived object to its
0029   /// nearest virtual base.
0030   int64_t NonVirtual = 0;
0031 
0032   /// Holds the ABI-specific information about the virtual return
0033   /// adjustment, if needed.
0034   union VirtualAdjustment {
0035     // Itanium ABI
0036     struct {
0037       /// The offset (in bytes), relative to the address point
0038       /// of the virtual base class offset.
0039       int64_t VBaseOffsetOffset;
0040     } Itanium;
0041 
0042     // Microsoft ABI
0043     struct {
0044       /// The offset (in bytes) of the vbptr, relative to the beginning
0045       /// of the derived class.
0046       uint32_t VBPtrOffset;
0047 
0048       /// Index of the virtual base in the vbtable.
0049       uint32_t VBIndex;
0050     } Microsoft;
0051 
0052     VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
0053 
0054     bool Equals(const VirtualAdjustment &Other) const {
0055       return memcmp(this, &Other, sizeof(Other)) == 0;
0056     }
0057 
0058     bool isEmpty() const {
0059       VirtualAdjustment Zero;
0060       return Equals(Zero);
0061     }
0062 
0063     bool Less(const VirtualAdjustment &RHS) const {
0064       return memcmp(this, &RHS, sizeof(RHS)) < 0;
0065     }
0066   } Virtual;
0067 
0068   ReturnAdjustment() = default;
0069 
0070   bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
0071 
0072   friend bool operator==(const ReturnAdjustment &LHS,
0073                          const ReturnAdjustment &RHS) {
0074     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
0075   }
0076 
0077   friend bool operator!=(const ReturnAdjustment &LHS,
0078                          const ReturnAdjustment &RHS) {
0079     return !(LHS == RHS);
0080   }
0081 
0082   friend bool operator<(const ReturnAdjustment &LHS,
0083                         const ReturnAdjustment &RHS) {
0084     if (LHS.NonVirtual < RHS.NonVirtual)
0085       return true;
0086 
0087     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
0088   }
0089 };
0090 
0091 /// A \c this pointer adjustment.
0092 struct ThisAdjustment {
0093   /// The non-virtual adjustment from the derived object to its
0094   /// nearest virtual base.
0095   int64_t NonVirtual = 0;
0096 
0097   /// Holds the ABI-specific information about the virtual this
0098   /// adjustment, if needed.
0099   union VirtualAdjustment {
0100     // Itanium ABI
0101     struct {
0102       /// The offset (in bytes), relative to the address point,
0103       /// of the virtual call offset.
0104       int64_t VCallOffsetOffset;
0105     } Itanium;
0106 
0107     struct {
0108       /// The offset of the vtordisp (in bytes), relative to the ECX.
0109       int32_t VtordispOffset;
0110 
0111       /// The offset of the vbptr of the derived class (in bytes),
0112       /// relative to the ECX after vtordisp adjustment.
0113       int32_t VBPtrOffset;
0114 
0115       /// The offset (in bytes) of the vbase offset in the vbtable.
0116       int32_t VBOffsetOffset;
0117     } Microsoft;
0118 
0119     VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
0120 
0121     bool Equals(const VirtualAdjustment &Other) const {
0122       return memcmp(this, &Other, sizeof(Other)) == 0;
0123     }
0124 
0125     bool isEmpty() const {
0126       VirtualAdjustment Zero;
0127       return Equals(Zero);
0128     }
0129 
0130     bool Less(const VirtualAdjustment &RHS) const {
0131       return memcmp(this, &RHS, sizeof(RHS)) < 0;
0132     }
0133   } Virtual;
0134 
0135   ThisAdjustment() = default;
0136 
0137   bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
0138 
0139   friend bool operator==(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
0140     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
0141   }
0142 
0143   friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
0144     return !(LHS == RHS);
0145   }
0146 
0147   friend bool operator<(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
0148     if (LHS.NonVirtual < RHS.NonVirtual)
0149       return true;
0150 
0151     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
0152   }
0153 };
0154 
0155 /// The \c this pointer adjustment as well as an optional return
0156 /// adjustment for a thunk.
0157 struct ThunkInfo {
0158   /// The \c this pointer adjustment.
0159   ThisAdjustment This;
0160 
0161   /// The return adjustment.
0162   ReturnAdjustment Return;
0163 
0164   /// Holds a pointer to the overridden method this thunk is for,
0165   /// if needed by the ABI to distinguish different thunks with equal
0166   /// adjustments.
0167   /// In the Itanium ABI, this field can hold the method that created the
0168   /// vtable entry for this thunk.
0169   /// Otherwise, null.
0170   /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
0171   /// an ABI-specific comparator.
0172   const CXXMethodDecl *Method;
0173   const Type *ThisType;
0174 
0175   ThunkInfo() : Method(nullptr), ThisType(nullptr) {}
0176 
0177   ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
0178             const Type *ThisT, const CXXMethodDecl *Method = nullptr)
0179       : This(This), Return(Return), Method(Method), ThisType(ThisT) {}
0180 
0181   friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
0182     return LHS.This == RHS.This && LHS.Return == RHS.Return &&
0183            LHS.Method == RHS.Method && LHS.ThisType == RHS.ThisType;
0184   }
0185 
0186   bool isEmpty() const {
0187     return This.isEmpty() && Return.isEmpty() && Method == nullptr;
0188   }
0189 };
0190 
0191 } // end namespace clang
0192 
0193 #endif