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
21namespace clang {
22
23/// \brief C++ constructor types.
24enum 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.
31enum 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.
38struct 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.
104struct 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
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