1218887Sdim//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===//
2218887Sdim//
3218887Sdim//                     The LLVM Compiler Infrastructure
4218887Sdim//
5218887Sdim// This file is distributed under the University of Illinois Open Source
6218887Sdim// License. See LICENSE.TXT for details.
7218887Sdim//
8218887Sdim//===----------------------------------------------------------------------===//
9239462Sdim///
10239462Sdim/// \file
11239462Sdim/// \brief Enums/classes describing ABI related information about constructors,
12239462Sdim/// destructors and thunks.
13239462Sdim///
14218887Sdim//===----------------------------------------------------------------------===//
15218887Sdim
16218887Sdim#ifndef CLANG_BASIC_ABI_H
17218887Sdim#define CLANG_BASIC_ABI_H
18218887Sdim
19218887Sdim#include "llvm/Support/DataTypes.h"
20218887Sdim
21218887Sdimnamespace clang {
22218887Sdim
23239462Sdim/// \brief C++ constructor types.
24218887Sdimenum CXXCtorType {
25239462Sdim    Ctor_Complete,          ///< Complete object ctor
26239462Sdim    Ctor_Base,              ///< Base object ctor
27239462Sdim    Ctor_CompleteAllocating ///< Complete object allocating ctor
28218887Sdim};
29218887Sdim
30239462Sdim/// \brief C++ destructor types.
31218887Sdimenum CXXDtorType {
32239462Sdim    Dtor_Deleting, ///< Deleting dtor
33239462Sdim    Dtor_Complete, ///< Complete object dtor
34239462Sdim    Dtor_Base      ///< Base object dtor
35218887Sdim};
36218887Sdim
37239462Sdim/// \brief A return adjustment.
38218887Sdimstruct ReturnAdjustment {
39239462Sdim  /// \brief The non-virtual adjustment from the derived object to its
40218887Sdim  /// nearest virtual base.
41218887Sdim  int64_t NonVirtual;
42218887Sdim
43239462Sdim  /// \brief The offset (in bytes), relative to the address point
44218887Sdim  /// of the virtual base class offset.
45218887Sdim  int64_t VBaseOffsetOffset;
46218887Sdim
47218887Sdim  ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
48218887Sdim
49218887Sdim  bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
50218887Sdim
51218887Sdim  friend bool operator==(const ReturnAdjustment &LHS,
52218887Sdim                         const ReturnAdjustment &RHS) {
53218887Sdim    return LHS.NonVirtual == RHS.NonVirtual &&
54218887Sdim      LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
55218887Sdim  }
56218887Sdim
57218887Sdim  friend bool operator<(const ReturnAdjustment &LHS,
58218887Sdim                        const ReturnAdjustment &RHS) {
59218887Sdim    if (LHS.NonVirtual < RHS.NonVirtual)
60218887Sdim      return true;
61218887Sdim
62218887Sdim    return LHS.NonVirtual == RHS.NonVirtual &&
63218887Sdim      LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
64218887Sdim  }
65218887Sdim};
66218887Sdim
67239462Sdim/// \brief A \c this pointer adjustment.
68218887Sdimstruct ThisAdjustment {
69239462Sdim  /// \brief The non-virtual adjustment from the derived object to its
70218887Sdim  /// nearest virtual base.
71218887Sdim  int64_t NonVirtual;
72218887Sdim
73239462Sdim  /// \brief The offset (in bytes), relative to the address point,
74218887Sdim  /// of the virtual call offset.
75218887Sdim  int64_t VCallOffsetOffset;
76218887Sdim
77218887Sdim  ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
78218887Sdim
79218887Sdim  bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
80218887Sdim
81218887Sdim  friend bool operator==(const ThisAdjustment &LHS,
82218887Sdim                         const ThisAdjustment &RHS) {
83218887Sdim    return LHS.NonVirtual == RHS.NonVirtual &&
84218887Sdim      LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
85218887Sdim  }
86218887Sdim
87218887Sdim  friend bool operator<(const ThisAdjustment &LHS,
88218887Sdim                        const ThisAdjustment &RHS) {
89218887Sdim    if (LHS.NonVirtual < RHS.NonVirtual)
90218887Sdim      return true;
91218887Sdim
92218887Sdim    return LHS.NonVirtual == RHS.NonVirtual &&
93218887Sdim      LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
94218887Sdim  }
95218887Sdim};
96218887Sdim
97239462Sdim/// \brief The \c this pointer adjustment as well as an optional return
98218887Sdim/// adjustment for a thunk.
99218887Sdimstruct ThunkInfo {
100239462Sdim  /// \brief The \c this pointer adjustment.
101218887Sdim  ThisAdjustment This;
102218887Sdim
103239462Sdim  /// \brief The return adjustment.
104218887Sdim  ReturnAdjustment Return;
105218887Sdim
106218887Sdim  ThunkInfo() { }
107218887Sdim
108218887Sdim  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
109218887Sdim    : This(This), Return(Return) { }
110218887Sdim
111218887Sdim  friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
112218887Sdim    return LHS.This == RHS.This && LHS.Return == RHS.Return;
113218887Sdim  }
114218887Sdim
115218887Sdim  friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
116218887Sdim    if (LHS.This < RHS.This)
117218887Sdim      return true;
118218887Sdim
119218887Sdim    return LHS.This == RHS.This && LHS.Return < RHS.Return;
120218887Sdim  }
121218887Sdim
122218887Sdim  bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
123218887Sdim};
124218887Sdim
125218887Sdim} // end namespace clang
126218887Sdim
127218887Sdim#endif // CLANG_BASIC_ABI_H
128