Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/Symbols.h
Line
Count
Source (jump to first uncovered line)
1
//===- Symbols.h ------------------------------------------------*- 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
#ifndef LLD_COFF_SYMBOLS_H
10
#define LLD_COFF_SYMBOLS_H
11
12
#include "Chunks.h"
13
#include "Config.h"
14
#include "lld/Common/LLVM.h"
15
#include "lld/Common/Memory.h"
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/Object/Archive.h"
18
#include "llvm/Object/COFF.h"
19
#include <atomic>
20
#include <memory>
21
#include <vector>
22
23
namespace lld {
24
25
std::string toString(coff::Symbol &b);
26
27
// There are two different ways to convert an Archive::Symbol to a string:
28
// One for Microsoft name mangling and one for Itanium name mangling.
29
// Call the functions toCOFFString and toELFString, not just toString.
30
std::string toCOFFString(const coff::Archive::Symbol &b);
31
32
namespace coff {
33
34
using llvm::object::Archive;
35
using llvm::object::COFFSymbolRef;
36
using llvm::object::coff_import_header;
37
using llvm::object::coff_symbol_generic;
38
39
class ArchiveFile;
40
class InputFile;
41
class ObjFile;
42
class SymbolTable;
43
44
// The base class for real symbol classes.
45
class Symbol {
46
public:
47
  enum Kind {
48
    // The order of these is significant. We start with the regular defined
49
    // symbols as those are the most prevalent and the zero tag is the cheapest
50
    // to set. Among the defined kinds, the lower the kind is preferred over
51
    // the higher kind when testing whether one symbol should take precedence
52
    // over another.
53
    DefinedRegularKind = 0,
54
    DefinedCommonKind,
55
    DefinedLocalImportKind,
56
    DefinedImportThunkKind,
57
    DefinedImportDataKind,
58
    DefinedAbsoluteKind,
59
    DefinedSyntheticKind,
60
61
    UndefinedKind,
62
    LazyKind,
63
64
    LastDefinedCOFFKind = DefinedCommonKind,
65
    LastDefinedKind = DefinedSyntheticKind,
66
  };
67
68
39.4k
  Kind kind() const { return static_cast<Kind>(symbolKind); }
69
70
  // Returns the symbol name.
71
  StringRef getName();
72
73
  void replaceKeepingName(Symbol *other, size_t size);
74
75
  // Returns the file from which this symbol was created.
76
  InputFile *getFile();
77
78
  // Indicates that this symbol will be included in the final image. Only valid
79
  // after calling markLive.
80
  bool isLive() const;
81
82
protected:
83
  friend SymbolTable;
84
  explicit Symbol(Kind k, StringRef n = "")
85
      : symbolKind(k), isExternal(true), isCOMDAT(false),
86
        writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false),
87
        isRuntimePseudoReloc(false), nameSize(n.size()),
88
12.1k
        nameData(n.empty() ? nullptr : n.data()) {}
89
90
  const unsigned symbolKind : 8;
91
  unsigned isExternal : 1;
92
93
public:
94
  // This bit is used by the \c DefinedRegular subclass.
95
  unsigned isCOMDAT : 1;
96
97
  // This bit is used by Writer::createSymbolAndStringTable() to prevent
98
  // symbols from being written to the symbol table more than once.
99
  unsigned writtenToSymtab : 1;
100
101
  // True if this symbol was referenced by a regular (non-bitcode) object.
102
  unsigned isUsedInRegularObj : 1;
103
104
  // True if we've seen both a lazy and an undefined symbol with this symbol
105
  // name, which means that we have enqueued an archive member load and should
106
  // not load any more archive members to resolve the same symbol.
107
  unsigned pendingArchiveLoad : 1;
108
109
  /// True if we've already added this symbol to the list of GC roots.
110
  unsigned isGCRoot : 1;
111
112
  unsigned isRuntimePseudoReloc : 1;
113
114
protected:
115
  // Symbol name length. Assume symbol lengths fit in a 32-bit integer.
116
  uint32_t nameSize;
117
118
  const char *nameData;
119
};
120
121
// The base class for any defined symbols, including absolute symbols,
122
// etc.
123
class Defined : public Symbol {
124
public:
125
11.1k
  Defined(Kind k, StringRef n) : Symbol(k, n) {}
126
127
7.39k
  static bool classof(const Symbol *s) { return s->kind() <= LastDefinedKind; }
128
129
  // Returns the RVA (relative virtual address) of this symbol. The
130
  // writer sets and uses RVAs.
131
  uint64_t getRVA();
132
133
  // Returns the chunk containing this symbol. Absolute symbols and __ImageBase
134
  // do not have chunks, so this may return null.
135
  Chunk *getChunk();
136
};
137
138
// Symbols defined via a COFF object file or bitcode file.  For COFF files, this
139
// stores a coff_symbol_generic*, and names of internal symbols are lazily
140
// loaded through that. For bitcode files, Sym is nullptr and the name is stored
141
// as a decomposed StringRef.
142
class DefinedCOFF : public Defined {
143
  friend Symbol;
144
145
public:
146
  DefinedCOFF(Kind k, InputFile *f, StringRef n, const coff_symbol_generic *s)
147
4.73k
      : Defined(k, n), file(f), sym(s) {}
148
149
771
  static bool classof(const Symbol *s) {
150
771
    return s->kind() <= LastDefinedCOFFKind;
151
771
  }
152
153
5
  InputFile *getFile() { return file; }
154
155
  COFFSymbolRef getCOFFSymbol();
156
157
  InputFile *file;
158
159
protected:
160
  const coff_symbol_generic *sym;
161
};
162
163
// Regular defined symbols read from object file symbol tables.
164
class DefinedRegular : public DefinedCOFF {
165
public:
166
  DefinedRegular(InputFile *f, StringRef n, bool isCOMDAT,
167
                 bool isExternal = false,
168
                 const coff_symbol_generic *s = nullptr,
169
                 SectionChunk *c = nullptr)
170
4.71k
      : DefinedCOFF(DefinedRegularKind, f, n, s), data(c ? &c->repl : nullptr) {
171
4.71k
    this->isExternal = isExternal;
172
4.71k
    this->isCOMDAT = isCOMDAT;
173
4.71k
  }
174
175
4.30k
  static bool classof(const Symbol *s) {
176
4.30k
    return s->kind() == DefinedRegularKind;
177
4.30k
  }
178
179
2.96k
  uint64_t getRVA() const { return (*data)->getRVA() + sym->Value; }
180
7.78k
  SectionChunk *getChunk() const { return *data; }
181
309
  uint32_t getValue() const { return sym->Value; }
182
183
  SectionChunk **data;
184
};
185
186
class DefinedCommon : public DefinedCOFF {
187
public:
188
  DefinedCommon(InputFile *f, StringRef n, uint64_t size,
189
                const coff_symbol_generic *s = nullptr,
190
                CommonChunk *c = nullptr)
191
14
      : DefinedCOFF(DefinedCommonKind, f, n, s), data(c), size(size) {
192
14
    this->isExternal = true;
193
14
  }
194
195
4
  static bool classof(const Symbol *s) {
196
4
    return s->kind() == DefinedCommonKind;
197
4
  }
198
199
37
  uint64_t getRVA() { return data->getRVA(); }
200
49
  CommonChunk *getChunk() { return data; }
201
202
private:
203
  friend SymbolTable;
204
0
  uint64_t getSize() const { return size; }
205
  CommonChunk *data;
206
  uint64_t size;
207
};
208
209
// Absolute symbols.
210
class DefinedAbsolute : public Defined {
211
public:
212
  DefinedAbsolute(StringRef n, COFFSymbolRef s)
213
12
      : Defined(DefinedAbsoluteKind, n), va(s.getValue()) {
214
12
    isExternal = s.isExternal();
215
12
  }
216
217
  DefinedAbsolute(StringRef n, uint64_t v)
218
5.35k
      : Defined(DefinedAbsoluteKind, n), va(v) {}
219
220
342
  static bool classof(const Symbol *s) {
221
342
    return s->kind() == DefinedAbsoluteKind;
222
342
  }
223
224
94
  uint64_t getRVA() { return va - config->imageBase; }
225
33
  void setVA(uint64_t v) { va = v; }
226
227
  // Section index relocations against absolute symbols resolve to
228
  // this 16 bit number, and it is the largest valid section index
229
  // plus one. This variable keeps it.
230
  static uint16_t numOutputSections;
231
232
private:
233
  uint64_t va;
234
};
235
236
// This symbol is used for linker-synthesized symbols like __ImageBase and
237
// __safe_se_handler_table.
238
class DefinedSynthetic : public Defined {
239
public:
240
  explicit DefinedSynthetic(StringRef name, Chunk *c)
241
873
      : Defined(DefinedSyntheticKind, name), c(c) {}
242
243
39
  static bool classof(const Symbol *s) {
244
39
    return s->kind() == DefinedSyntheticKind;
245
39
  }
246
247
  // A null chunk indicates that this is __ImageBase. Otherwise, this is some
248
  // other synthesized chunk, like SEHTableChunk.
249
140
  uint32_t getRVA() { return c ? 
c->getRVA()104
:
036
; }
250
269
  Chunk *getChunk() { return c; }
251
252
private:
253
  Chunk *c;
254
};
255
256
// This class represents a symbol defined in an archive file. It is
257
// created from an archive file header, and it knows how to load an
258
// object file from an archive to replace itself with a defined
259
// symbol. If the resolver finds both Undefined and Lazy for
260
// the same name, it will ask the Lazy to load a file.
261
class Lazy : public Symbol {
262
public:
263
  Lazy(ArchiveFile *f, const Archive::Symbol s)
264
373
      : Symbol(LazyKind, s.getName()), file(f), sym(s) {}
265
266
1.76k
  static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
267
268
  ArchiveFile *file;
269
270
private:
271
  friend SymbolTable;
272
273
private:
274
  const Archive::Symbol sym;
275
};
276
277
// Undefined symbols.
278
class Undefined : public Symbol {
279
public:
280
570
  explicit Undefined(StringRef n) : Symbol(UndefinedKind, n) {}
281
282
10.4k
  static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
283
284
  // An undefined symbol can have a fallback symbol which gives an
285
  // undefined symbol a second chance if it would remain undefined.
286
  // If it remains undefined, it'll be replaced with whatever the
287
  // Alias pointer points to.
288
  Symbol *weakAlias = nullptr;
289
290
  // If this symbol is external weak, try to resolve it to a defined
291
  // symbol by searching the chain of fallback symbols. Returns the symbol if
292
  // successful, otherwise returns null.
293
  Defined *getWeakAlias();
294
};
295
296
// Windows-specific classes.
297
298
// This class represents a symbol imported from a DLL. This has two
299
// names for internal use and external use. The former is used for
300
// name resolution, and the latter is used for the import descriptor
301
// table in an output. The former has "__imp_" prefix.
302
class DefinedImportData : public Defined {
303
public:
304
  DefinedImportData(StringRef n, ImportFile *f)
305
108
      : Defined(DefinedImportDataKind, n), file(f) {
306
108
  }
307
308
1.63k
  static bool classof(const Symbol *s) {
309
1.63k
    return s->kind() == DefinedImportDataKind;
310
1.63k
  }
311
312
139
  uint64_t getRVA() { return file->location->getRVA(); }
313
54
  Chunk *getChunk() { return file->location; }
314
103
  void setLocation(Chunk *addressTable) { file->location = addressTable; }
315
316
163
  StringRef getDLLName() { return file->dllName; }
317
183
  StringRef getExternalName() { return file->externalName; }
318
93
  uint16_t getOrdinal() { return file->hdr->OrdinalHint; }
319
320
  ImportFile *file;
321
};
322
323
// This class represents a symbol for a jump table entry which jumps
324
// to a function in a DLL. Linker are supposed to create such symbols
325
// without "__imp_" prefix for all function symbols exported from
326
// DLLs, so that you can call DLL functions as regular functions with
327
// a regular name. A function pointer is given as a DefinedImportData.
328
class DefinedImportThunk : public Defined {
329
public:
330
  DefinedImportThunk(StringRef name, DefinedImportData *s, uint16_t machine);
331
332
1.60k
  static bool classof(const Symbol *s) {
333
1.60k
    return s->kind() == DefinedImportThunkKind;
334
1.60k
  }
335
336
123
  uint64_t getRVA() { return data->getRVA(); }
337
299
  Chunk *getChunk() { return data; }
338
339
  DefinedImportData *wrappedSym;
340
341
private:
342
  Chunk *data;
343
};
344
345
// If you have a symbol "foo" in your object file, a symbol name
346
// "__imp_foo" becomes automatically available as a pointer to "foo".
347
// This class is for such automatically-created symbols.
348
// Yes, this is an odd feature. We didn't intend to implement that.
349
// This is here just for compatibility with MSVC.
350
class DefinedLocalImport : public Defined {
351
public:
352
  DefinedLocalImport(StringRef n, Defined *s)
353
9
      : Defined(DefinedLocalImportKind, n), data(make<LocalImportChunk>(s)) {}
354
355
0
  static bool classof(const Symbol *s) {
356
0
    return s->kind() == DefinedLocalImportKind;
357
0
  }
358
359
16
  uint64_t getRVA() { return data->getRVA(); }
360
32
  Chunk *getChunk() { return data; }
361
362
private:
363
  LocalImportChunk *data;
364
};
365
366
3.42k
inline uint64_t Defined::getRVA() {
367
3.42k
  switch (kind()) {
368
3.42k
  case DefinedAbsoluteKind:
369
94
    return cast<DefinedAbsolute>(this)->getRVA();
370
3.42k
  case DefinedSyntheticKind:
371
140
    return cast<DefinedSynthetic>(this)->getRVA();
372
3.42k
  case DefinedImportDataKind:
373
139
    return cast<DefinedImportData>(this)->getRVA();
374
3.42k
  case DefinedImportThunkKind:
375
123
    return cast<DefinedImportThunk>(this)->getRVA();
376
3.42k
  case DefinedLocalImportKind:
377
16
    return cast<DefinedLocalImport>(this)->getRVA();
378
3.42k
  case DefinedCommonKind:
379
37
    return cast<DefinedCommon>(this)->getRVA();
380
3.42k
  case DefinedRegularKind:
381
2.87k
    return cast<DefinedRegular>(this)->getRVA();
382
3.42k
  case LazyKind:
383
0
  case UndefinedKind:
384
0
    llvm_unreachable("Cannot get the address for an undefined symbol.");
385
0
  }
386
0
  llvm_unreachable("unknown symbol kind");
387
0
}
388
389
7.36k
inline Chunk *Defined::getChunk() {
390
7.36k
  switch (kind()) {
391
7.36k
  case DefinedRegularKind:
392
5.48k
    return cast<DefinedRegular>(this)->getChunk();
393
7.36k
  case DefinedAbsoluteKind:
394
1.29k
    return nullptr;
395
7.36k
  case DefinedSyntheticKind:
396
269
    return cast<DefinedSynthetic>(this)->getChunk();
397
7.36k
  case DefinedImportDataKind:
398
54
    return cast<DefinedImportData>(this)->getChunk();
399
7.36k
  case DefinedImportThunkKind:
400
194
    return cast<DefinedImportThunk>(this)->getChunk();
401
7.36k
  case DefinedLocalImportKind:
402
23
    return cast<DefinedLocalImport>(this)->getChunk();
403
7.36k
  case DefinedCommonKind:
404
48
    return cast<DefinedCommon>(this)->getChunk();
405
7.36k
  case LazyKind:
406
0
  case UndefinedKind:
407
0
    llvm_unreachable("Cannot get the chunk of an undefined symbol.");
408
0
  }
409
0
  llvm_unreachable("unknown symbol kind");
410
0
}
411
412
// A buffer class that is large enough to hold any Symbol-derived
413
// object. We allocate memory using this class and instantiate a symbol
414
// using the placement new.
415
union SymbolUnion {
416
  alignas(DefinedRegular) char a[sizeof(DefinedRegular)];
417
  alignas(DefinedCommon) char b[sizeof(DefinedCommon)];
418
  alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)];
419
  alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)];
420
  alignas(Lazy) char e[sizeof(Lazy)];
421
  alignas(Undefined) char f[sizeof(Undefined)];
422
  alignas(DefinedImportData) char g[sizeof(DefinedImportData)];
423
  alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)];
424
  alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)];
425
};
426
427
template <typename T, typename... ArgT>
428
8.86k
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
8.86k
  static_assert(std::is_trivially_destructible<T>(),
430
8.86k
                "Symbol types must be trivially destructible");
431
8.86k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
8.86k
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
8.86k
                "SymbolUnion not aligned enough");
434
8.86k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
8.86k
         "Not a Symbol");
436
8.86k
  new (s) T(std::forward<ArgT>(arg)...);
437
8.86k
}
void lld::coff::replaceSymbol<lld::coff::DefinedRegular, lld::coff::ObjFile*, llvm::StringRef&, bool, bool, llvm::object::coff_symbol_generic const*, std::nullptr_t>(lld::coff::Symbol*, lld::coff::ObjFile*&&, llvm::StringRef&&&, bool&&, bool&&, llvm::object::coff_symbol_generic const*&&, std::nullptr_t&&)
Line
Count
Source
428
5
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
5
  static_assert(std::is_trivially_destructible<T>(),
430
5
                "Symbol types must be trivially destructible");
431
5
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
5
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
5
                "SymbolUnion not aligned enough");
434
5
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
5
         "Not a Symbol");
436
5
  new (s) T(std::forward<ArgT>(arg)...);
437
5
}
void lld::coff::replaceSymbol<lld::coff::Undefined, llvm::StringRef>(lld::coff::Symbol*, llvm::StringRef&&)
Line
Count
Source
428
103
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
103
  static_assert(std::is_trivially_destructible<T>(),
430
103
                "Symbol types must be trivially destructible");
431
103
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
103
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
103
                "SymbolUnion not aligned enough");
434
103
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
103
         "Not a Symbol");
436
103
  new (s) T(std::forward<ArgT>(arg)...);
437
103
}
void lld::coff::replaceSymbol<lld::coff::DefinedLocalImport, llvm::StringRef&, lld::coff::Defined*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::Defined*&&&)
Line
Count
Source
428
9
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
9
  static_assert(std::is_trivially_destructible<T>(),
430
9
                "Symbol types must be trivially destructible");
431
9
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
9
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
9
                "SymbolUnion not aligned enough");
434
9
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
9
         "Not a Symbol");
436
9
  new (s) T(std::forward<ArgT>(arg)...);
437
9
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, int>(lld::coff::Symbol*, llvm::StringRef&&&, int&&)
Line
Count
Source
428
20
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
20
  static_assert(std::is_trivially_destructible<T>(),
430
20
                "Symbol types must be trivially destructible");
431
20
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
20
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
20
                "SymbolUnion not aligned enough");
434
20
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
20
         "Not a Symbol");
436
20
  new (s) T(std::forward<ArgT>(arg)...);
437
20
}
void lld::coff::replaceSymbol<lld::coff::Undefined, llvm::StringRef&>(lld::coff::Symbol*, llvm::StringRef&&&)
Line
Count
Source
428
467
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
467
  static_assert(std::is_trivially_destructible<T>(),
430
467
                "Symbol types must be trivially destructible");
431
467
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
467
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
467
                "SymbolUnion not aligned enough");
434
467
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
467
         "Not a Symbol");
436
467
  new (s) T(std::forward<ArgT>(arg)...);
437
467
}
void lld::coff::replaceSymbol<lld::coff::Lazy, lld::coff::ArchiveFile*&, llvm::object::Archive::Symbol const&>(lld::coff::Symbol*, lld::coff::ArchiveFile*&&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
428
373
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
373
  static_assert(std::is_trivially_destructible<T>(),
430
373
                "Symbol types must be trivially destructible");
431
373
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
373
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
373
                "SymbolUnion not aligned enough");
434
373
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
373
         "Not a Symbol");
436
373
  new (s) T(std::forward<ArgT>(arg)...);
437
373
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, llvm::object::COFFSymbolRef&>(lld::coff::Symbol*, llvm::StringRef&&&, llvm::object::COFFSymbolRef&&&)
Line
Count
Source
428
8
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
8
  static_assert(std::is_trivially_destructible<T>(),
430
8
                "Symbol types must be trivially destructible");
431
8
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
8
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
8
                "SymbolUnion not aligned enough");
434
8
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
8
         "Not a Symbol");
436
8
  new (s) T(std::forward<ArgT>(arg)...);
437
8
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, unsigned long long&>(lld::coff::Symbol*, llvm::StringRef&&&, unsigned long long&&&)
Line
Count
Source
428
5.33k
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
5.33k
  static_assert(std::is_trivially_destructible<T>(),
430
5.33k
                "Symbol types must be trivially destructible");
431
5.33k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
5.33k
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
5.33k
                "SymbolUnion not aligned enough");
434
5.33k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
5.33k
         "Not a Symbol");
436
5.33k
  new (s) T(std::forward<ArgT>(arg)...);
437
5.33k
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef&, lld::coff::Chunk*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::Chunk*&&&)
Line
Count
Source
428
618
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
618
  static_assert(std::is_trivially_destructible<T>(),
430
618
                "Symbol types must be trivially destructible");
431
618
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
618
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
618
                "SymbolUnion not aligned enough");
434
618
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
618
         "Not a Symbol");
436
618
  new (s) T(std::forward<ArgT>(arg)...);
437
618
}
void lld::coff::replaceSymbol<lld::coff::DefinedRegular, lld::coff::InputFile*&, llvm::StringRef&, bool, bool, llvm::object::coff_symbol_generic const*&, lld::coff::SectionChunk*&>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, bool&&, bool&&, llvm::object::coff_symbol_generic const*&&&, lld::coff::SectionChunk*&&&)
Line
Count
Source
428
1.15k
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
1.15k
  static_assert(std::is_trivially_destructible<T>(),
430
1.15k
                "Symbol types must be trivially destructible");
431
1.15k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
1.15k
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
1.15k
                "SymbolUnion not aligned enough");
434
1.15k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
1.15k
         "Not a Symbol");
436
1.15k
  new (s) T(std::forward<ArgT>(arg)...);
437
1.15k
}
void lld::coff::replaceSymbol<lld::coff::DefinedRegular, lld::coff::InputFile*&, llvm::StringRef&, bool, bool, llvm::object::coff_symbol_generic const*&, std::nullptr_t>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, bool&&, bool&&, llvm::object::coff_symbol_generic const*&&&, std::nullptr_t&&)
Line
Count
Source
428
345
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
345
  static_assert(std::is_trivially_destructible<T>(),
430
345
                "Symbol types must be trivially destructible");
431
345
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
345
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
345
                "SymbolUnion not aligned enough");
434
345
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
345
         "Not a Symbol");
436
345
  new (s) T(std::forward<ArgT>(arg)...);
437
345
}
void lld::coff::replaceSymbol<lld::coff::DefinedCommon, lld::coff::InputFile*&, llvm::StringRef&, unsigned long long&, llvm::object::coff_symbol_generic const*&, lld::coff::CommonChunk*&>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, unsigned long long&&&, llvm::object::coff_symbol_generic const*&&&, lld::coff::CommonChunk*&&&)
Line
Count
Source
428
14
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
14
  static_assert(std::is_trivially_destructible<T>(),
430
14
                "Symbol types must be trivially destructible");
431
14
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
14
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
14
                "SymbolUnion not aligned enough");
434
14
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
14
         "Not a Symbol");
436
14
  new (s) T(std::forward<ArgT>(arg)...);
437
14
}
void lld::coff::replaceSymbol<lld::coff::DefinedImportData, llvm::StringRef&, lld::coff::ImportFile*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::ImportFile*&&&)
Line
Count
Source
428
108
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
108
  static_assert(std::is_trivially_destructible<T>(),
430
108
                "Symbol types must be trivially destructible");
431
108
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
108
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
108
                "SymbolUnion not aligned enough");
434
108
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
108
         "Not a Symbol");
436
108
  new (s) T(std::forward<ArgT>(arg)...);
437
108
}
void lld::coff::replaceSymbol<lld::coff::DefinedImportThunk, llvm::StringRef&, lld::coff::DefinedImportData*&, unsigned short&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::DefinedImportData*&&&, unsigned short&&&)
Line
Count
Source
428
98
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
98
  static_assert(std::is_trivially_destructible<T>(),
430
98
                "Symbol types must be trivially destructible");
431
98
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
98
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
98
                "SymbolUnion not aligned enough");
434
98
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
98
         "Not a Symbol");
436
98
  new (s) T(std::forward<ArgT>(arg)...);
437
98
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::RVATableChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::RVATableChunk*&&&)
Line
Count
Source
428
20
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
20
  static_assert(std::is_trivially_destructible<T>(),
430
20
                "Symbol types must be trivially destructible");
431
20
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
20
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
20
                "SymbolUnion not aligned enough");
434
20
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
20
         "Not a Symbol");
436
20
  new (s) T(std::forward<ArgT>(arg)...);
437
20
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::PseudoRelocTableChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::PseudoRelocTableChunk*&&&)
Line
Count
Source
428
46
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
46
  static_assert(std::is_trivially_destructible<T>(),
430
46
                "Symbol types must be trivially destructible");
431
46
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
46
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
46
                "SymbolUnion not aligned enough");
434
46
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
46
         "Not a Symbol");
436
46
  new (s) T(std::forward<ArgT>(arg)...);
437
46
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::EmptyChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::EmptyChunk*&&&)
Line
Count
Source
428
46
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
46
  static_assert(std::is_trivially_destructible<T>(),
430
46
                "Symbol types must be trivially destructible");
431
46
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
46
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
46
                "SymbolUnion not aligned enough");
434
46
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
46
         "Not a Symbol");
436
46
  new (s) T(std::forward<ArgT>(arg)...);
437
46
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::AbsolutePointerChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::AbsolutePointerChunk*&&&)
Line
Count
Source
428
92
void replaceSymbol(Symbol *s, ArgT &&... arg) {
429
92
  static_assert(std::is_trivially_destructible<T>(),
430
92
                "Symbol types must be trivially destructible");
431
92
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
432
92
  static_assert(alignof(T) <= alignof(SymbolUnion),
433
92
                "SymbolUnion not aligned enough");
434
92
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
435
92
         "Not a Symbol");
436
92
  new (s) T(std::forward<ArgT>(arg)...);
437
92
}
438
} // namespace coff
439
440
} // namespace lld
441
442
#endif