Coverage Report

Created: 2018-09-23 03:40

/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
//                     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
/// Defines the TargetCXXABI class, which abstracts details of the
12
/// C++ ABI that we're targeting.
13
///
14
//===----------------------------------------------------------------------===//
15
16
#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
17
#define LLVM_CLANG_BASIC_TARGETCXXABI_H
18
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 Microsoft ABI is the ABI used by Microsoft Visual Studio (and
108
    /// compatible compilers).
109
    ///
110
    /// FIXME: should this be split into Win32 and Win64 variants?
111
    ///
112
    /// Only scattered and incomplete official documentation exists.
113
    Microsoft
114
  };
115
116
private:
117
  // Right now, this class is passed around as a cheap value type.
118
  // If you add more members, especially non-POD members, please
119
  // audit the users to pass it by reference instead.
120
  Kind TheKind;
121
122
public:
123
  /// A bogus initialization of the platform ABI.
124
44.4k
  TargetCXXABI() : TheKind(GenericItanium) {}
125
126
1.84M
  TargetCXXABI(Kind kind) : TheKind(kind) {}
127
128
66.3k
  void set(Kind kind) {
129
66.3k
    TheKind = kind;
130
66.3k
  }
131
132
24.4M
  Kind getKind() const { return TheKind; }
133
134
  /// Does this ABI generally fall into the Itanium family of ABIs?
135
511k
  bool isItaniumFamily() const {
136
511k
    switch (getKind()) {
137
511k
    case GenericAArch64:
138
501k
    case GenericItanium:
139
501k
    case GenericARM:
140
501k
    case iOS:
141
501k
    case iOS64:
142
501k
    case WatchOS:
143
501k
    case GenericMIPS:
144
501k
    case WebAssembly:
145
501k
      return true;
146
501k
147
501k
    case Microsoft:
148
9.67k
      return false;
149
0
    }
150
0
    llvm_unreachable("bad ABI kind");
151
0
  }
152
153
  /// Is this ABI an MSVC-compatible ABI?
154
16.1M
  bool isMicrosoft() const {
155
16.1M
    switch (getKind()) {
156
16.1M
    case GenericAArch64:
157
16.0M
    case GenericItanium:
158
16.0M
    case GenericARM:
159
16.0M
    case iOS:
160
16.0M
    case iOS64:
161
16.0M
    case WatchOS:
162
16.0M
    case GenericMIPS:
163
16.0M
    case WebAssembly:
164
16.0M
      return false;
165
16.0M
166
16.0M
    case Microsoft:
167
97.1k
      return true;
168
0
    }
169
0
    llvm_unreachable("bad ABI kind");
170
0
  }
171
172
  /// Are member functions differently aligned?
173
  ///
174
  /// Many Itanium-style C++ ABIs require member functions to be aligned, so
175
  /// that a pointer to such a function is guaranteed to have a zero in the
176
  /// least significant bit, so that pointers to member functions can use that
177
  /// bit to distinguish between virtual and non-virtual functions. However,
178
  /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
179
  /// functions via other means, and consequently don't require that member
180
  /// functions be aligned.
181
351k
  bool areMemberFunctionsAligned() const {
182
351k
    switch (getKind()) {
183
351k
    case WebAssembly:
184
207
      // WebAssembly doesn't require any special alignment for member functions.
185
207
      return false;
186
351k
    case GenericARM:
187
351k
    case GenericAArch64:
188
351k
    case GenericMIPS:
189
351k
      // TODO: ARM-style pointers to member functions put the discriminator in
190
351k
      //       the this adjustment, so they don't require functions to have any
191
351k
      //       special alignment and could therefore also return false.
192
351k
    case GenericItanium:
193
351k
    case iOS:
194
351k
    case iOS64:
195
351k
    case WatchOS:
196
351k
    case Microsoft:
197
351k
      return true;
198
0
    }
199
0
    llvm_unreachable("bad ABI kind");
200
0
  }
201
202
  /// Are arguments to a call destroyed left to right in the callee?
203
  /// This is a fundamental language change, since it implies that objects
204
  /// passed by value do *not* live to the end of the full expression.
205
  /// Temporaries passed to a function taking a const reference live to the end
206
  /// of the full expression as usual.  Both the caller and the callee must
207
  /// have access to the destructor, while only the caller needs the
208
  /// destructor if this is false.
209
2.95M
  bool areArgsDestroyedLeftToRightInCallee() const {
210
2.95M
    return isMicrosoft();
211
2.95M
  }
212
213
  /// Does this ABI have different entrypoints for complete-object
214
  /// and base-subobject constructors?
215
409k
  bool hasConstructorVariants() const {
216
409k
    return isItaniumFamily();
217
409k
  }
218
219
  /// Does this ABI allow virtual bases to be primary base classes?
220
0
  bool hasPrimaryVBases() const {
221
0
    return isItaniumFamily();
222
0
  }
223
224
  /// Does this ABI use key functions?  If so, class data such as the
225
  /// vtable is emitted with strong linkage by the TU containing the key
226
  /// function.
227
100k
  bool hasKeyFunctions() const {
228
100k
    return isItaniumFamily();
229
100k
  }
230
231
  /// Can an out-of-line inline function serve as a key function?
232
  ///
233
  /// This flag is only useful in ABIs where type data (for example,
234
  /// vtables and type_info objects) are emitted only after processing
235
  /// the definition of a special "key" virtual function.  (This is safe
236
  /// because the ODR requires that every virtual function be defined
237
  /// somewhere in a program.)  This usually permits such data to be
238
  /// emitted in only a single object file, as opposed to redundantly
239
  /// in every object file that requires it.
240
  ///
241
  /// One simple and common definition of "key function" is the first
242
  /// virtual function in the class definition which is not defined there.
243
  /// This rule works very well when that function has a non-inline
244
  /// definition in some non-header file.  Unfortunately, when that
245
  /// function is defined inline, this rule requires the type data
246
  /// to be emitted weakly, as if there were no key function.
247
  ///
248
  /// The ARM ABI observes that the ODR provides an additional guarantee:
249
  /// a virtual function is always ODR-used, so if it is defined inline,
250
  /// that definition must appear in every translation unit that defines
251
  /// the class.  Therefore, there is no reason to allow such functions
252
  /// to serve as key functions.
253
  ///
254
  /// Because this changes the rules for emitting type data,
255
  /// it can cause type data to be emitted with both weak and strong
256
  /// linkage, which is not allowed on all platforms.  Therefore,
257
  /// exploiting this observation requires an ABI break and cannot be
258
  /// done on a generic Itanium platform.
259
3.52M
  bool canKeyFunctionBeInline() const {
260
3.52M
    switch (getKind()) {
261
3.52M
    case GenericARM:
262
1.44M
    case iOS64:
263
1.44M
    case WebAssembly:
264
1.44M
    case WatchOS:
265
1.44M
      return false;
266
1.44M
267
2.08M
    case GenericAArch64:
268
2.08M
    case GenericItanium:
269
2.08M
    case iOS:   // old iOS compilers did not follow this rule
270
2.08M
    case Microsoft:
271
2.08M
    case GenericMIPS:
272
2.08M
      return true;
273
0
    }
274
0
    llvm_unreachable("bad ABI kind");
275
0
  }
276
277
  /// When is record layout allowed to allocate objects in the tail
278
  /// padding of a base class?
279
  ///
280
  /// This decision cannot be changed without breaking platform ABI
281
  /// compatibility, and yet it is tied to language guarantees which
282
  /// the committee has so far seen fit to strengthen no less than
283
  /// three separate times:
284
  ///   - originally, there were no restrictions at all;
285
  ///   - C++98 declared that objects could not be allocated in the
286
  ///     tail padding of a POD type;
287
  ///   - C++03 extended the definition of POD to include classes
288
  ///     containing member pointers; and
289
  ///   - C++11 greatly broadened the definition of POD to include
290
  ///     all trivial standard-layout classes.
291
  /// Each of these changes technically took several existing
292
  /// platforms and made them permanently non-conformant.
293
  enum TailPaddingUseRules {
294
    /// The tail-padding of a base class is always theoretically
295
    /// available, even if it's POD.  This is not strictly conforming
296
    /// in any language mode.
297
    AlwaysUseTailPadding,
298
299
    /// Only allocate objects in the tail padding of a base class if
300
    /// the base class is not POD according to the rules of C++ TR1.
301
    /// This is non-strictly conforming in C++11 mode.
302
    UseTailPaddingUnlessPOD03,
303
304
    /// Only allocate objects in the tail padding of a base class if
305
    /// the base class is not POD according to the rules of C++11.
306
    UseTailPaddingUnlessPOD11
307
  };
308
133k
  TailPaddingUseRules getTailPaddingUseRules() const {
309
133k
    switch (getKind()) {
310
133k
    // To preserve binary compatibility, the generic Itanium ABI has
311
133k
    // permanently locked the definition of POD to the rules of C++ TR1,
312
133k
    // and that trickles down to derived ABIs.
313
133k
    case GenericItanium:
314
75.0k
    case GenericAArch64:
315
75.0k
    case GenericARM:
316
75.0k
    case iOS:
317
75.0k
    case GenericMIPS:
318
75.0k
      return UseTailPaddingUnlessPOD03;
319
75.0k
320
75.0k
    // iOS on ARM64 and WebAssembly use the C++11 POD rules.  They do not honor
321
75.0k
    // the Itanium exception about classes with over-large bitfields.
322
75.0k
    case iOS64:
323
58.0k
    case WebAssembly:
324
58.0k
    case WatchOS:
325
58.0k
      return UseTailPaddingUnlessPOD11;
326
58.0k
327
58.0k
    // MSVC always allocates fields in the tail-padding of a base class
328
58.0k
    // subobject, even if they're POD.
329
58.0k
    case Microsoft:
330
0
      return AlwaysUseTailPadding;
331
0
    }
332
0
    llvm_unreachable("bad ABI kind");
333
0
  }
334
335
1.84M
  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
336
1.84M
    return left.getKind() == right.getKind();
337
1.84M
  }
338
339
1.79M
  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
340
1.79M
    return !(left == right);
341
1.79M
  }
342
};
343
344
}  // end namespace clang
345
346
#endif