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