Coverage Report

Created: 2020-11-24 06:42

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/TargetCXXABI.h
Line
Count
Source (jump to first uncovered line)
1
//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- 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
/// Defines the TargetCXXABI class, which abstracts details of the
11
/// C++ ABI that we're targeting.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
16
#define LLVM_CLANG_BASIC_TARGETCXXABI_H
17
18
#include "clang/Basic/LLVM.h"
19
#include "llvm/Support/ErrorHandling.h"
20
21
namespace clang {
22
23
/// The basic abstraction for the target C++ ABI.
24
class TargetCXXABI {
25
public:
26
  /// The basic C++ ABI kind.
27
  enum Kind {
28
    /// The generic Itanium ABI is the standard ABI of most open-source
29
    /// and Unix-like platforms.  It is the primary ABI targeted by
30
    /// many compilers, including Clang and GCC.
31
    ///
32
    /// It is documented here:
33
    ///   http://www.codesourcery.com/public/cxx-abi/
34
    GenericItanium,
35
36
    /// The generic ARM ABI is a modified version of the Itanium ABI
37
    /// proposed by ARM for use on ARM-based platforms.
38
    ///
39
    /// These changes include:
40
    ///   - the representation of member function pointers is adjusted
41
    ///     to not conflict with the 'thumb' bit of ARM function pointers;
42
    ///   - constructors and destructors return 'this';
43
    ///   - guard variables are smaller;
44
    ///   - inline functions are never key functions;
45
    ///   - array cookies have a slightly different layout;
46
    ///   - additional convenience functions are specified;
47
    ///   - and more!
48
    ///
49
    /// It is documented here:
50
    ///    http://infocenter.arm.com
51
    ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
52
    GenericARM,
53
54
    /// The iOS ABI is a partial implementation of the ARM ABI.
55
    /// Several of the features of the ARM ABI were not fully implemented
56
    /// in the compilers that iOS was launched with.
57
    ///
58
    /// Essentially, the iOS ABI includes the ARM changes to:
59
    ///   - member function pointers,
60
    ///   - guard variables,
61
    ///   - array cookies, and
62
    ///   - constructor/destructor signatures.
63
    iOS,
64
65
    /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
66
    /// closely, but we don't guarantee to follow it perfectly.
67
    ///
68
    /// It is documented here:
69
    ///    http://infocenter.arm.com
70
    ///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
71
    iOS64,
72
73
    /// WatchOS is a modernisation of the iOS ABI, which roughly means it's
74
    /// the iOS64 ABI ported to 32-bits. The primary difference from iOS64 is
75
    /// that RTTI objects must still be unique at the moment.
76
    WatchOS,
77
78
    /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
79
    /// but it has fewer divergences than the 32-bit ARM ABI.
80
    ///
81
    /// The relevant changes from the generic ABI in this case are:
82
    ///   - representation of member function pointers adjusted as in ARM.
83
    ///   - guard variables  are smaller.
84
    GenericAArch64,
85
86
    /// The generic Mips ABI is a modified version of the Itanium ABI.
87
    ///
88
    /// At the moment, only change from the generic ABI in this case is:
89
    ///   - representation of member function pointers adjusted as in ARM.
90
    GenericMIPS,
91
92
    /// The WebAssembly ABI is a modified version of the Itanium ABI.
93
    ///
94
    /// The changes from the Itanium ABI are:
95
    ///   - representation of member function pointers is adjusted, as in ARM;
96
    ///   - member functions are not specially aligned;
97
    ///   - constructors and destructors return 'this', as in ARM;
98
    ///   - guard variables are 32-bit on wasm32, as in ARM;
99
    ///   - unused bits of guard variables are reserved, as in ARM;
100
    ///   - inline functions are never key functions, as in ARM;
101
    ///   - C++11 POD rules are used for tail padding, as in iOS64.
102
    ///
103
    /// TODO: At present the WebAssembly ABI is not considered stable, so none
104
    /// of these details is necessarily final yet.
105
    WebAssembly,
106
107
    /// The Fuchsia ABI is a modified version of the Itanium ABI.
108
    ///
109
    /// The relevant changes from the Itanium ABI are:
110
    ///   - constructors and destructors return 'this', as in ARM.
111
    Fuchsia,
112
113
    /// The XL ABI is the ABI used by IBM xlclang compiler and is a modified
114
    /// version of the Itanium ABI.
115
    ///
116
    /// The relevant changes from the Itanium ABI are:
117
    ///   - static initialization is adjusted to use sinit and sterm functions;
118
    XL,
119
120
    /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
121
    /// compatible compilers).
122
    ///
123
    /// FIXME: should this be split into Win32 and Win64 variants?
124
    ///
125
    /// Only scattered and incomplete official documentation exists.
126
    Microsoft
127
  };
128
129
private:
130
  // Right now, this class is passed around as a cheap value type.
131
  // If you add more members, especially non-POD members, please
132
  // audit the users to pass it by reference instead.
133
  Kind TheKind;
134
135
public:
136
  /// A bogus initialization of the platform ABI.
137
90.8k
  TargetCXXABI() : TheKind(GenericItanium) {}
138
139
1.45M
  TargetCXXABI(Kind kind) : TheKind(kind) {}
140
141
95.5k
  void set(Kind kind) {
142
95.5k
    TheKind = kind;
143
95.5k
  }
144
145
23.2M
  Kind getKind() const { return TheKind; }
146
147
  /// Does this ABI generally fall into the Itanium family of ABIs?
148
615k
  bool isItaniumFamily() const {
149
615k
    switch (getKind()) {
150
598k
    case Fuchsia:
151
598k
    case GenericAArch64:
152
598k
    case GenericItanium:
153
598k
    case GenericARM:
154
598k
    case iOS:
155
598k
    case iOS64:
156
598k
    case WatchOS:
157
598k
    case GenericMIPS:
158
598k
    case WebAssembly:
159
598k
    case XL:
160
598k
      return true;
161
162
16.9k
    case Microsoft:
163
16.9k
      return false;
164
0
    }
165
0
    llvm_unreachable("bad ABI kind");
166
0
  }
167
168
  /// Is this ABI an MSVC-compatible ABI?
169
14.6M
  bool isMicrosoft() const {
170
14.6M
    switch (getKind()) {
171
14.4M
    case Fuchsia:
172
14.4M
    case GenericAArch64:
173
14.4M
    case GenericItanium:
174
14.4M
    case GenericARM:
175
14.4M
    case iOS:
176
14.4M
    case iOS64:
177
14.4M
    case WatchOS:
178
14.4M
    case GenericMIPS:
179
14.4M
    case WebAssembly:
180
14.4M
    case XL:
181
14.4M
      return false;
182
183
213k
    case Microsoft:
184
213k
      return true;
185
0
    }
186
0
    llvm_unreachable("bad ABI kind");
187
0
  }
188
189
  /// Are member functions differently aligned?
190
  ///
191
  /// Many Itanium-style C++ ABIs require member functions to be aligned, so
192
  /// that a pointer to such a function is guaranteed to have a zero in the
193
  /// least significant bit, so that pointers to member functions can use that
194
  /// bit to distinguish between virtual and non-virtual functions. However,
195
  /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
196
  /// functions via other means, and consequently don't require that member
197
  /// functions be aligned.
198
278k
  bool areMemberFunctionsAligned() const {
199
278k
    switch (getKind()) {
200
636
    case WebAssembly:
201
      // WebAssembly doesn't require any special alignment for member functions.
202
636
      return false;
203
277k
    case Fuchsia:
204
277k
    case GenericARM:
205
277k
    case GenericAArch64:
206
277k
    case GenericMIPS:
207
      // TODO: ARM-style pointers to member functions put the discriminator in
208
      //       the this adjustment, so they don't require functions to have any
209
      //       special alignment and could therefore also return false.
210
277k
    case GenericItanium:
211
277k
    case iOS:
212
277k
    case iOS64:
213
277k
    case WatchOS:
214
277k
    case Microsoft:
215
277k
    case XL:
216
277k
      return true;
217
0
    }
218
0
    llvm_unreachable("bad ABI kind");
219
0
  }
220
221
  /// Are arguments to a call destroyed left to right in the callee?
222
  /// This is a fundamental language change, since it implies that objects
223
  /// passed by value do *not* live to the end of the full expression.
224
  /// Temporaries passed to a function taking a const reference live to the end
225
  /// of the full expression as usual.  Both the caller and the callee must
226
  /// have access to the destructor, while only the caller needs the
227
  /// destructor if this is false.
228
1.95M
  bool areArgsDestroyedLeftToRightInCallee() const {
229
1.95M
    return isMicrosoft();
230
1.95M
  }
231
232
  /// Does this ABI have different entrypoints for complete-object
233
  /// and base-subobject constructors?
234
402k
  bool hasConstructorVariants() const {
235
402k
    return isItaniumFamily();
236
402k
  }
237
238
  /// Does this ABI allow virtual bases to be primary base classes?
239
199
  bool hasPrimaryVBases() const {
240
199
    return isItaniumFamily();
241
199
  }
242
243
  /// Does this ABI use key functions?  If so, class data such as the
244
  /// vtable is emitted with strong linkage by the TU containing the key
245
  /// function.
246
165k
  bool hasKeyFunctions() const {
247
165k
    return isItaniumFamily();
248
165k
  }
249
250
  /// Can an out-of-line inline function serve as a key function?
251
  ///
252
  /// This flag is only useful in ABIs where type data (for example,
253
  /// vtables and type_info objects) are emitted only after processing
254
  /// the definition of a special "key" virtual function.  (This is safe
255
  /// because the ODR requires that every virtual function be defined
256
  /// somewhere in a program.)  This usually permits such data to be
257
  /// emitted in only a single object file, as opposed to redundantly
258
  /// in every object file that requires it.
259
  ///
260
  /// One simple and common definition of "key function" is the first
261
  /// virtual function in the class definition which is not defined there.
262
  /// This rule works very well when that function has a non-inline
263
  /// definition in some non-header file.  Unfortunately, when that
264
  /// function is defined inline, this rule requires the type data
265
  /// to be emitted weakly, as if there were no key function.
266
  ///
267
  /// The ARM ABI observes that the ODR provides an additional guarantee:
268
  /// a virtual function is always ODR-used, so if it is defined inline,
269
  /// that definition must appear in every translation unit that defines
270
  /// the class.  Therefore, there is no reason to allow such functions
271
  /// to serve as key functions.
272
  ///
273
  /// Because this changes the rules for emitting type data,
274
  /// it can cause type data to be emitted with both weak and strong
275
  /// linkage, which is not allowed on all platforms.  Therefore,
276
  /// exploiting this observation requires an ABI break and cannot be
277
  /// done on a generic Itanium platform.
278
4.33M
  bool canKeyFunctionBeInline() const {
279
4.33M
    switch (getKind()) {
280
181k
    case Fuchsia:
281
181k
    case GenericARM:
282
181k
    case iOS64:
283
181k
    case WebAssembly:
284
181k
    case WatchOS:
285
181k
      return false;
286
287
4.15M
    case GenericAArch64:
288
4.15M
    case GenericItanium:
289
4.15M
    case iOS:   // old iOS compilers did not follow this rule
290
4.15M
    case Microsoft:
291
4.15M
    case GenericMIPS:
292
4.15M
    case XL:
293
4.15M
      return true;
294
0
    }
295
0
    llvm_unreachable("bad ABI kind");
296
0
  }
297
298
  /// When is record layout allowed to allocate objects in the tail
299
  /// padding of a base class?
300
  ///
301
  /// This decision cannot be changed without breaking platform ABI
302
  /// compatibility. In ISO C++98, tail padding reuse was only permitted for
303
  /// non-POD base classes, but that restriction was removed retroactively by
304
  /// DR 43, and tail padding reuse is always permitted in all de facto C++
305
  /// language modes. However, many platforms use a variant of the old C++98
306
  /// rule for compatibility.
307
  enum TailPaddingUseRules {
308
    /// The tail-padding of a base class is always theoretically
309
    /// available, even if it's POD.
310
    AlwaysUseTailPadding,
311
312
    /// Only allocate objects in the tail padding of a base class if
313
    /// the base class is not POD according to the rules of C++ TR1.
314
    UseTailPaddingUnlessPOD03,
315
316
    /// Only allocate objects in the tail padding of a base class if
317
    /// the base class is not POD according to the rules of C++11.
318
    UseTailPaddingUnlessPOD11
319
  };
320
194k
  TailPaddingUseRules getTailPaddingUseRules() const {
321
194k
    switch (getKind()) {
322
    // To preserve binary compatibility, the generic Itanium ABI has
323
    // permanently locked the definition of POD to the rules of C++ TR1,
324
    // and that trickles down to derived ABIs.
325
194k
    case GenericItanium:
326
194k
    case GenericAArch64:
327
194k
    case GenericARM:
328
194k
    case iOS:
329
194k
    case GenericMIPS:
330
194k
    case XL:
331
194k
      return UseTailPaddingUnlessPOD03;
332
333
    // iOS on ARM64 and WebAssembly use the C++11 POD rules.  They do not honor
334
    // the Itanium exception about classes with over-large bitfields.
335
276
    case Fuchsia:
336
276
    case iOS64:
337
276
    case WebAssembly:
338
276
    case WatchOS:
339
276
      return UseTailPaddingUnlessPOD11;
340
341
    // MSVC always allocates fields in the tail-padding of a base class
342
    // subobject, even if they're POD.
343
0
    case Microsoft:
344
0
      return AlwaysUseTailPadding;
345
0
    }
346
0
    llvm_unreachable("bad ABI kind");
347
0
  }
348
349
1.45M
  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
350
1.45M
    return left.getKind() == right.getKind();
351
1.45M
  }
352
353
1.37M
  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
354
1.37M
    return !(left == right);
355
1.37M
  }
356
};
357
358
}  // end namespace clang
359
360
#endif