Coverage Report

Created: 2021-06-15 06:44

/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 <map>
19
20
#include "clang/Basic/LLVM.h"
21
#include "llvm/ADT/StringMap.h"
22
#include "llvm/ADT/Triple.h"
23
#include "llvm/Support/ErrorHandling.h"
24
25
namespace clang {
26
27
/// The basic abstraction for the target C++ ABI.
28
class TargetCXXABI {
29
public:
30
  /// The basic C++ ABI kind.
31
  enum Kind {
32
#define CXXABI(Name, Str) Name,
33
#include "TargetCXXABI.def"
34
  };
35
36
private:
37
  // Right now, this class is passed around as a cheap value type.
38
  // If you add more members, especially non-POD members, please
39
  // audit the users to pass it by reference instead.
40
  Kind TheKind;
41
42
44
  static const auto &getABIMap() {
43
44
    static llvm::StringMap<Kind> ABIMap = {
44
484
#define CXXABI(Name, Str) {Str, Name},
45
44
#include "TargetCXXABI.def"
46
44
    };
47
44
    return ABIMap;
48
44
  }
49
50
10
  static const auto &getSpellingMap() {
51
10
    static std::map<Kind, std::string> SpellingMap = {
52
110
#define CXXABI(Name, Str) {Name, Str},
53
10
#include "TargetCXXABI.def"
54
10
    };
55
10
    return SpellingMap;
56
10
  }
57
58
public:
59
12
  static Kind getKind(StringRef Name) { return getABIMap().lookup(Name); }
60
10
  static const auto &getSpelling(Kind ABIKind) {
61
10
    return getSpellingMap().find(ABIKind)->second;
62
10
  }
63
16
  static bool isABI(StringRef Name) {
64
16
    return getABIMap().find(Name) != getABIMap().end();
65
16
  }
66
67
  // Return true if this target should use the relative vtables C++ ABI by
68
  // default.
69
134k
  static bool usesRelativeVTables(const llvm::Triple &T) {
70
134k
    return T.isOSFuchsia();
71
134k
  }
72
73
  /// A bogus initialization of the platform ABI.
74
103k
  TargetCXXABI() : TheKind(GenericItanium) {}
75
76
1.49M
  TargetCXXABI(Kind kind) : TheKind(kind) {}
77
78
109k
  void set(Kind kind) {
79
109k
    TheKind = kind;
80
109k
  }
81
82
22.1M
  Kind getKind() const { return TheKind; }
83
84
  // Check that the kind provided by the fc++-abi flag is supported on this
85
  // target. Users who want to experiment using different ABIs on specific
86
  // platforms can change this freely, but this function should be conservative
87
  // enough such that not all ABIs are allowed on all platforms. For example, we
88
  // probably don't want to allow usage of an ARM ABI on an x86 architecture.
89
12
  static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind) {
90
12
    switch (Kind) {
91
0
    case GenericARM:
92
0
      return T.isARM() || T.isAArch64();
93
94
0
    case iOS:
95
0
    case WatchOS:
96
0
    case AppleARM64:
97
0
      return T.isOSDarwin();
98
99
4
    case Fuchsia:
100
4
      return T.isOSFuchsia();
101
102
0
    case GenericAArch64:
103
0
      return T.isAArch64();
104
105
0
    case GenericMIPS:
106
0
      return T.isMIPS();
107
108
0
    case WebAssembly:
109
0
      return T.isWasm();
110
111
0
    case XL:
112
0
      return T.isOSAIX();
113
114
6
    case GenericItanium:
115
6
      return true;
116
117
2
    case Microsoft:
118
2
      return T.isKnownWindowsMSVCEnvironment();
119
12
    }
120
12
    
llvm_unreachable0
("invalid CXXABI kind");
121
12
  };
122
123
  /// Does this ABI generally fall into the Itanium family of ABIs?
124
601k
  bool isItaniumFamily() const {
125
601k
    switch (getKind()) {
126
0
#define CXXABI(Name, Str)
127
5.82M
#define ITANIUM_CXXABI(Name, Str) case Name:
128
584k
#include 
"TargetCXXABI.def"0
129
584k
      return true;
130
131
17.0k
    default:
132
17.0k
      return false;
133
601k
    }
134
601k
    
llvm_unreachable0
("bad ABI kind");
135
601k
  }
136
137
  /// Is this ABI an MSVC-compatible ABI?
138
13.0M
  bool isMicrosoft() const {
139
13.0M
    switch (getKind()) {
140
0
#define CXXABI(Name, Str)
141
190k
#define MICROSOFT_CXXABI(Name, Str) case Name:
142
190k
#include 
"TargetCXXABI.def"0
143
190k
      return true;
144
145
12.8M
    default:
146
12.8M
      return false;
147
13.0M
    }
148
13.0M
    
llvm_unreachable0
("bad ABI kind");
149
13.0M
  }
150
151
  /// Are member functions differently aligned?
152
  ///
153
  /// Many Itanium-style C++ ABIs require member functions to be aligned, so
154
  /// that a pointer to such a function is guaranteed to have a zero in the
155
  /// least significant bit, so that pointers to member functions can use that
156
  /// bit to distinguish between virtual and non-virtual functions. However,
157
  /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
158
  /// functions via other means, and consequently don't require that member
159
  /// functions be aligned.
160
336k
  bool areMemberFunctionsAligned() const {
161
336k
    switch (getKind()) {
162
1.10k
    case WebAssembly:
163
      // WebAssembly doesn't require any special alignment for member functions.
164
1.10k
      return false;
165
1.45k
    case AppleARM64:
166
1.58k
    case Fuchsia:
167
9.42k
    case GenericARM:
168
48.8k
    case GenericAArch64:
169
49.2k
    case GenericMIPS:
170
      // TODO: ARM-style pointers to member functions put the discriminator in
171
      //       the this adjustment, so they don't require functions to have any
172
      //       special alignment and could therefore also return false.
173
318k
    case GenericItanium:
174
322k
    case iOS:
175
322k
    case WatchOS:
176
335k
    case Microsoft:
177
335k
    case XL:
178
335k
      return true;
179
336k
    }
180
336k
    
llvm_unreachable0
("bad ABI kind");
181
336k
  }
182
183
  /// Are arguments to a call destroyed left to right in the callee?
184
  /// This is a fundamental language change, since it implies that objects
185
  /// passed by value do *not* live to the end of the full expression.
186
  /// Temporaries passed to a function taking a const reference live to the end
187
  /// of the full expression as usual.  Both the caller and the callee must
188
  /// have access to the destructor, while only the caller needs the
189
  /// destructor if this is false.
190
2.09M
  bool areArgsDestroyedLeftToRightInCallee() const {
191
2.09M
    return isMicrosoft();
192
2.09M
  }
193
194
  /// Does this ABI have different entrypoints for complete-object
195
  /// and base-subobject constructors?
196
395k
  bool hasConstructorVariants() const {
197
395k
    return isItaniumFamily();
198
395k
  }
199
200
  /// Does this ABI allow virtual bases to be primary base classes?
201
214
  bool hasPrimaryVBases() const {
202
214
    return isItaniumFamily();
203
214
  }
204
205
  /// Does this ABI use key functions?  If so, class data such as the
206
  /// vtable is emitted with strong linkage by the TU containing the key
207
  /// function.
208
159k
  bool hasKeyFunctions() const {
209
159k
    return isItaniumFamily();
210
159k
  }
211
212
  /// Can an out-of-line inline function serve as a key function?
213
  ///
214
  /// This flag is only useful in ABIs where type data (for example,
215
  /// vtables and type_info objects) are emitted only after processing
216
  /// the definition of a special "key" virtual function.  (This is safe
217
  /// because the ODR requires that every virtual function be defined
218
  /// somewhere in a program.)  This usually permits such data to be
219
  /// emitted in only a single object file, as opposed to redundantly
220
  /// in every object file that requires it.
221
  ///
222
  /// One simple and common definition of "key function" is the first
223
  /// virtual function in the class definition which is not defined there.
224
  /// This rule works very well when that function has a non-inline
225
  /// definition in some non-header file.  Unfortunately, when that
226
  /// function is defined inline, this rule requires the type data
227
  /// to be emitted weakly, as if there were no key function.
228
  ///
229
  /// The ARM ABI observes that the ODR provides an additional guarantee:
230
  /// a virtual function is always ODR-used, so if it is defined inline,
231
  /// that definition must appear in every translation unit that defines
232
  /// the class.  Therefore, there is no reason to allow such functions
233
  /// to serve as key functions.
234
  ///
235
  /// Because this changes the rules for emitting type data,
236
  /// it can cause type data to be emitted with both weak and strong
237
  /// linkage, which is not allowed on all platforms.  Therefore,
238
  /// exploiting this observation requires an ABI break and cannot be
239
  /// done on a generic Itanium platform.
240
4.60M
  bool canKeyFunctionBeInline() const {
241
4.60M
    switch (getKind()) {
242
78.4k
    case AppleARM64:
243
78.6k
    case Fuchsia:
244
187k
    case GenericARM:
245
188k
    case WebAssembly:
246
191k
    case WatchOS:
247
191k
      return false;
248
249
822k
    case GenericAArch64:
250
4.24M
    case GenericItanium:
251
4.26M
    case iOS:   // old iOS compilers did not follow this rule
252
4.40M
    case Microsoft:
253
4.40M
    case GenericMIPS:
254
4.41M
    case XL:
255
4.41M
      return true;
256
4.60M
    }
257
4.60M
    
llvm_unreachable0
("bad ABI kind");
258
4.60M
  }
259
260
  /// When is record layout allowed to allocate objects in the tail
261
  /// padding of a base class?
262
  ///
263
  /// This decision cannot be changed without breaking platform ABI
264
  /// compatibility. In ISO C++98, tail padding reuse was only permitted for
265
  /// non-POD base classes, but that restriction was removed retroactively by
266
  /// DR 43, and tail padding reuse is always permitted in all de facto C++
267
  /// language modes. However, many platforms use a variant of the old C++98
268
  /// rule for compatibility.
269
  enum TailPaddingUseRules {
270
    /// The tail-padding of a base class is always theoretically
271
    /// available, even if it's POD.
272
    AlwaysUseTailPadding,
273
274
    /// Only allocate objects in the tail padding of a base class if
275
    /// the base class is not POD according to the rules of C++ TR1.
276
    UseTailPaddingUnlessPOD03,
277
278
    /// Only allocate objects in the tail padding of a base class if
279
    /// the base class is not POD according to the rules of C++11.
280
    UseTailPaddingUnlessPOD11
281
  };
282
253k
  TailPaddingUseRules getTailPaddingUseRules() const {
283
253k
    switch (getKind()) {
284
    // To preserve binary compatibility, the generic Itanium ABI has
285
    // permanently locked the definition of POD to the rules of C++ TR1,
286
    // and that trickles down to derived ABIs.
287
251k
    case GenericItanium:
288
252k
    case GenericAArch64:
289
252k
    case GenericARM:
290
252k
    case iOS:
291
252k
    case GenericMIPS:
292
253k
    case XL:
293
253k
      return UseTailPaddingUnlessPOD03;
294
295
    // AppleARM64 and WebAssembly use the C++11 POD rules.  They do not honor
296
    // the Itanium exception about classes with over-large bitfields.
297
135
    case AppleARM64:
298
192
    case Fuchsia:
299
255
    case WebAssembly:
300
290
    case WatchOS:
301
290
      return UseTailPaddingUnlessPOD11;
302
303
    // MSVC always allocates fields in the tail-padding of a base class
304
    // subobject, even if they're POD.
305
0
    case Microsoft:
306
0
      return AlwaysUseTailPadding;
307
253k
    }
308
253k
    
llvm_unreachable0
("bad ABI kind");
309
253k
  }
310
311
1.49M
  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
312
1.49M
    return left.getKind() == right.getKind();
313
1.49M
  }
314
315
1.40M
  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
316
1.40M
    return !(left == right);
317
1.40M
  }
318
};
319
320
}  // end namespace clang
321
322
#endif