Coverage Report

Created: 2019-05-19 14:56

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