Coverage Report

Created: 2019-07-24 05:18

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