Home | History | Annotate | Line # | Download | only in Basic
      1 //===----- Thunk.h - Declarations related to VTable Thunks ------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// Enums/classes describing THUNK related information about constructors,
     11 /// destructors and thunks.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_BASIC_THUNK_H
     16 #define LLVM_CLANG_BASIC_THUNK_H
     17 
     18 #include <cstdint>
     19 #include <cstring>
     20 
     21 namespace clang {
     22 
     23 class CXXMethodDecl;
     24 
     25 /// A return adjustment.
     26 struct ReturnAdjustment {
     27   /// The non-virtual adjustment from the derived object to its
     28   /// nearest virtual base.
     29   int64_t NonVirtual;
     30 
     31   /// Holds the ABI-specific information about the virtual return
     32   /// adjustment, if needed.
     33   union VirtualAdjustment {
     34     // Itanium ABI
     35     struct {
     36       /// The offset (in bytes), relative to the address point
     37       /// of the virtual base class offset.
     38       int64_t VBaseOffsetOffset;
     39     } Itanium;
     40 
     41     // Microsoft ABI
     42     struct {
     43       /// The offset (in bytes) of the vbptr, relative to the beginning
     44       /// of the derived class.
     45       uint32_t VBPtrOffset;
     46 
     47       /// Index of the virtual base in the vbtable.
     48       uint32_t VBIndex;
     49     } Microsoft;
     50 
     51     VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
     52 
     53     bool Equals(const VirtualAdjustment &Other) const {
     54       return memcmp(this, &Other, sizeof(Other)) == 0;
     55     }
     56 
     57     bool isEmpty() const {
     58       VirtualAdjustment Zero;
     59       return Equals(Zero);
     60     }
     61 
     62     bool Less(const VirtualAdjustment &RHS) const {
     63       return memcmp(this, &RHS, sizeof(RHS)) < 0;
     64     }
     65   } Virtual;
     66 
     67   ReturnAdjustment() : NonVirtual(0) {}
     68 
     69   bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
     70 
     71   friend bool operator==(const ReturnAdjustment &LHS,
     72                          const ReturnAdjustment &RHS) {
     73     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
     74   }
     75 
     76   friend bool operator!=(const ReturnAdjustment &LHS,
     77                          const ReturnAdjustment &RHS) {
     78     return !(LHS == RHS);
     79   }
     80 
     81   friend bool operator<(const ReturnAdjustment &LHS,
     82                         const ReturnAdjustment &RHS) {
     83     if (LHS.NonVirtual < RHS.NonVirtual)
     84       return true;
     85 
     86     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
     87   }
     88 };
     89 
     90 /// A \c this pointer adjustment.
     91 struct ThisAdjustment {
     92   /// The non-virtual adjustment from the derived object to its
     93   /// nearest virtual base.
     94   int64_t NonVirtual;
     95 
     96   /// Holds the ABI-specific information about the virtual this
     97   /// adjustment, if needed.
     98   union VirtualAdjustment {
     99     // Itanium ABI
    100     struct {
    101       /// The offset (in bytes), relative to the address point,
    102       /// of the virtual call offset.
    103       int64_t VCallOffsetOffset;
    104     } Itanium;
    105 
    106     struct {
    107       /// The offset of the vtordisp (in bytes), relative to the ECX.
    108       int32_t VtordispOffset;
    109 
    110       /// The offset of the vbptr of the derived class (in bytes),
    111       /// relative to the ECX after vtordisp adjustment.
    112       int32_t VBPtrOffset;
    113 
    114       /// The offset (in bytes) of the vbase offset in the vbtable.
    115       int32_t VBOffsetOffset;
    116     } Microsoft;
    117 
    118     VirtualAdjustment() { memset(this, 0, sizeof(*this)); }
    119 
    120     bool Equals(const VirtualAdjustment &Other) const {
    121       return memcmp(this, &Other, sizeof(Other)) == 0;
    122     }
    123 
    124     bool isEmpty() const {
    125       VirtualAdjustment Zero;
    126       return Equals(Zero);
    127     }
    128 
    129     bool Less(const VirtualAdjustment &RHS) const {
    130       return memcmp(this, &RHS, sizeof(RHS)) < 0;
    131     }
    132   } Virtual;
    133 
    134   ThisAdjustment() : NonVirtual(0) {}
    135 
    136   bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
    137 
    138   friend bool operator==(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
    139     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
    140   }
    141 
    142   friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
    143     return !(LHS == RHS);
    144   }
    145 
    146   friend bool operator<(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
    147     if (LHS.NonVirtual < RHS.NonVirtual)
    148       return true;
    149 
    150     return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
    151   }
    152 };
    153 
    154 /// The \c this pointer adjustment as well as an optional return
    155 /// adjustment for a thunk.
    156 struct ThunkInfo {
    157   /// The \c this pointer adjustment.
    158   ThisAdjustment This;
    159 
    160   /// The return adjustment.
    161   ReturnAdjustment Return;
    162 
    163   /// Holds a pointer to the overridden method this thunk is for,
    164   /// if needed by the ABI to distinguish different thunks with equal
    165   /// adjustments. Otherwise, null.
    166   /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
    167   /// an ABI-specific comparator.
    168   const CXXMethodDecl *Method;
    169 
    170   ThunkInfo() : Method(nullptr) {}
    171 
    172   ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
    173             const CXXMethodDecl *Method = nullptr)
    174       : This(This), Return(Return), Method(Method) {}
    175 
    176   friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
    177     return LHS.This == RHS.This && LHS.Return == RHS.Return &&
    178            LHS.Method == RHS.Method;
    179   }
    180 
    181   bool isEmpty() const {
    182     return This.isEmpty() && Return.isEmpty() && Method == nullptr;
    183   }
    184 };
    185 
    186 } // end namespace clang
    187 
    188 #endif
    189