Coverage Report

Created: 2018-08-19 14:04

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