Coverage Report

Created: 2018-10-23 15:26

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/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_WASM_SYMBOLS_H
11
#define LLD_WASM_SYMBOLS_H
12
13
#include "Config.h"
14
#include "lld/Common/LLVM.h"
15
#include "llvm/Object/Archive.h"
16
#include "llvm/Object/Wasm.h"
17
18
using llvm::object::Archive;
19
using llvm::object::WasmSymbol;
20
using llvm::wasm::WasmGlobal;
21
using llvm::wasm::WasmGlobalType;
22
using llvm::wasm::WasmSignature;
23
using llvm::wasm::WasmSymbolType;
24
25
namespace lld {
26
namespace wasm {
27
28
class InputFile;
29
class InputChunk;
30
class InputSegment;
31
class InputFunction;
32
class InputGlobal;
33
class InputSection;
34
35
4
#define INVALID_INDEX UINT32_MAX
36
37
// The base class for real symbol classes.
38
class Symbol {
39
public:
40
  enum Kind {
41
    DefinedFunctionKind,
42
    DefinedDataKind,
43
    DefinedGlobalKind,
44
    SectionKind,
45
    UndefinedFunctionKind,
46
    UndefinedDataKind,
47
    UndefinedGlobalKind,
48
    LazyKind,
49
  };
50
51
7.35k
  Kind kind() const { return SymbolKind; }
52
53
1.61k
  bool isDefined() const {
54
1.61k
    return SymbolKind == DefinedFunctionKind || 
SymbolKind == DefinedDataKind800
||
55
1.61k
           
SymbolKind == DefinedGlobalKind296
||
SymbolKind == SectionKind138
;
56
1.61k
  }
57
58
2.58k
  bool isUndefined() const {
59
2.58k
    return SymbolKind == UndefinedFunctionKind ||
60
2.58k
           
SymbolKind == UndefinedDataKind2.52k
||
SymbolKind == UndefinedGlobalKind2.51k
;
61
2.58k
  }
62
63
100
  bool isLazy() const { return SymbolKind == LazyKind; }
64
65
  bool isLocal() const;
66
  bool isWeak() const;
67
  bool isHidden() const;
68
69
  // Returns the symbol name.
70
682
  StringRef getName() const { return Name; }
71
72
  // Returns the file from which this symbol was created.
73
337
  InputFile *getFile() const { return File; }
74
75
  InputChunk *getChunk() const;
76
77
  // Indicates that the section or import for this symbol will be included in
78
  // the final image.
79
  bool isLive() const;
80
81
  // Marks the symbol's InputChunk as Live, so that it will be included in the
82
  // final image.
83
  void markLive();
84
85
  void setHidden(bool IsHidden);
86
87
  // Get/set the index in the output symbol table.  This is only used for
88
  // relocatable output.
89
  uint32_t getOutputSymbolIndex() const;
90
  void setOutputSymbolIndex(uint32_t Index);
91
92
  WasmSymbolType getWasmType() const;
93
  bool isExported() const;
94
95
  // True if this symbol was referenced by a regular (non-bitcode) object.
96
  unsigned IsUsedInRegularObj : 1;
97
  unsigned ForceExport : 1;
98
99
protected:
100
  Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
101
      : IsUsedInRegularObj(false), ForceExport(false), Name(Name),
102
1.26k
        SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
103
104
  StringRef Name;
105
  Kind SymbolKind;
106
  uint32_t Flags;
107
  InputFile *File;
108
  uint32_t OutputSymbolIndex = INVALID_INDEX;
109
  bool Referenced;
110
};
111
112
class FunctionSymbol : public Symbol {
113
public:
114
716
  static bool classof(const Symbol *S) {
115
716
    return S->kind() == DefinedFunctionKind ||
116
716
           
S->kind() == UndefinedFunctionKind303
;
117
716
  }
118
119
  // Get/set the table index
120
  void setTableIndex(uint32_t Index);
121
  uint32_t getTableIndex() const;
122
  bool hasTableIndex() const;
123
124
  // Get/set the function index
125
  uint32_t getFunctionIndex() const;
126
  void setFunctionIndex(uint32_t Index);
127
  bool hasFunctionIndex() const;
128
129
  const WasmSignature *FunctionType;
130
131
protected:
132
  FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
133
                 const WasmSignature *Type)
134
695
      : Symbol(Name, K, Flags, F), FunctionType(Type) {}
135
136
  uint32_t TableIndex = INVALID_INDEX;
137
  uint32_t FunctionIndex = INVALID_INDEX;
138
};
139
140
class DefinedFunction : public FunctionSymbol {
141
public:
142
  DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
143
                  InputFunction *Function);
144
145
2.97k
  static bool classof(const Symbol *S) {
146
2.97k
    return S->kind() == DefinedFunctionKind;
147
2.97k
  }
148
149
  InputFunction *Function;
150
};
151
152
class UndefinedFunction : public FunctionSymbol {
153
public:
154
  UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
155
                    const WasmSignature *Type = nullptr)
156
104
      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {}
157
158
0
  static bool classof(const Symbol *S) {
159
0
    return S->kind() == UndefinedFunctionKind;
160
0
  }
161
};
162
163
class SectionSymbol : public Symbol {
164
public:
165
233
  static bool classof(const Symbol *S) { return S->kind() == SectionKind; }
166
167
  SectionSymbol(StringRef Name, uint32_t Flags, const InputSection *S,
168
                InputFile *F = nullptr)
169
14
      : Symbol(Name, SectionKind, Flags, F), Section(S) {}
170
171
  const InputSection *Section;
172
173
  uint32_t getOutputSectionIndex() const;
174
  void setOutputSectionIndex(uint32_t Index);
175
176
protected:
177
  uint32_t OutputSectionIndex = INVALID_INDEX;
178
};
179
180
class DataSymbol : public Symbol {
181
public:
182
95
  static bool classof(const Symbol *S) {
183
95
    return S->kind() == DefinedDataKind || 
S->kind() == UndefinedDataKind47
;
184
95
  }
185
186
protected:
187
  DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
188
402
      : Symbol(Name, K, Flags, F) {}
189
};
190
191
class DefinedData : public DataSymbol {
192
public:
193
  // Constructor for regular data symbols originating from input files.
194
  DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
195
              InputSegment *Segment, uint32_t Offset, uint32_t Size)
196
      : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
197
80
        Offset(Offset), Size(Size) {}
198
199
  // Constructor for linker synthetic data symbols.
200
  DefinedData(StringRef Name, uint32_t Flags)
201
312
      : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {}
202
203
1.09k
  static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; }
204
205
  // Returns the output virtual address of a defined data symbol.
206
  uint32_t getVirtualAddress() const;
207
  void setVirtualAddress(uint32_t VA);
208
209
  // Returns the offset of a defined data symbol within its OutputSegment.
210
  uint32_t getOutputSegmentOffset() const;
211
  uint32_t getOutputSegmentIndex() const;
212
22
  uint32_t getSize() const { return Size; }
213
214
  InputSegment *Segment = nullptr;
215
216
protected:
217
  uint32_t Offset = 0;
218
  uint32_t Size = 0;
219
};
220
221
class UndefinedData : public DataSymbol {
222
public:
223
  UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
224
10
      : DataSymbol(Name, UndefinedDataKind, Flags, File) {}
225
0
  static bool classof(const Symbol *S) {
226
0
    return S->kind() == UndefinedDataKind;
227
0
  }
228
};
229
230
class GlobalSymbol : public Symbol {
231
public:
232
35
  static bool classof(const Symbol *S) {
233
35
    return S->kind() == DefinedGlobalKind || 
S->kind() == UndefinedGlobalKind32
;
234
35
  }
235
236
12
  const WasmGlobalType *getGlobalType() const { return GlobalType; }
237
238
  // Get/set the global index
239
  uint32_t getGlobalIndex() const;
240
  void setGlobalIndex(uint32_t Index);
241
  bool hasGlobalIndex() const;
242
243
protected:
244
  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
245
               const WasmGlobalType *GlobalType)
246
116
      : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
247
248
  // Explicit function type, needed for undefined or synthetic functions only.
249
  // For regular defined globals this information comes from the InputChunk.
250
  const WasmGlobalType *GlobalType;
251
  uint32_t GlobalIndex = INVALID_INDEX;
252
};
253
254
class DefinedGlobal : public GlobalSymbol {
255
public:
256
  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
257
                InputGlobal *Global);
258
259
1.69k
  static bool classof(const Symbol *S) {
260
1.69k
    return S->kind() == DefinedGlobalKind;
261
1.69k
  }
262
263
  InputGlobal *Global;
264
};
265
266
class UndefinedGlobal : public GlobalSymbol {
267
public:
268
  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
269
                  const WasmGlobalType *Type = nullptr)
270
8
      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {}
271
272
0
  static bool classof(const Symbol *S) {
273
0
    return S->kind() == UndefinedGlobalKind;
274
0
  }
275
};
276
277
class LazySymbol : public Symbol {
278
public:
279
  LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym)
280
35
      : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
281
282
122
  static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
283
  void fetch();
284
285
private:
286
  Archive::Symbol ArchiveSymbol;
287
};
288
289
// linker-generated symbols
290
struct WasmSym {
291
  // __stack_pointer
292
  // Global that holds the address of the top of the explicit value stack in
293
  // linear memory.
294
  static DefinedGlobal *StackPointer;
295
296
  // __data_end
297
  // Symbol marking the end of the data and bss.
298
  static DefinedData *DataEnd;
299
300
  // __heap_base
301
  // Symbol marking the end of the data, bss and explicit stack.  Any linear
302
  // memory following this address is not used by the linked code and can
303
  // therefore be used as a backing store for brk()/malloc() implementations.
304
  static DefinedData *HeapBase;
305
306
  // __wasm_call_ctors
307
  // Function that directly calls all ctors in priority order.
308
  static DefinedFunction *CallCtors;
309
310
  // __dso_handle
311
  // Symbol used in calls to __cxa_atexit to determine current DLL
312
  static DefinedData *DsoHandle;
313
};
314
315
// A buffer class that is large enough to hold any Symbol-derived
316
// object. We allocate memory using this class and instantiate a symbol
317
// using the placement new.
318
union SymbolUnion {
319
  alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
320
  alignas(DefinedData) char B[sizeof(DefinedData)];
321
  alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
322
  alignas(LazySymbol) char D[sizeof(LazySymbol)];
323
  alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)];
324
  alignas(UndefinedData) char F[sizeof(UndefinedData)];
325
  alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)];
326
  alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
327
};
328
329
template <typename T, typename... ArgT>
330
1.18k
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
1.18k
  static_assert(std::is_trivially_destructible<T>(),
332
1.18k
                "Symbol types must be trivially destructible");
333
1.18k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
1.18k
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
1.18k
                "SymbolUnion not aligned enough");
336
1.18k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
1.18k
         "Not a Symbol");
338
1.18k
339
1.18k
  Symbol SymCopy = *S;
340
1.18k
341
1.18k
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
1.18k
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
1.18k
  S2->ForceExport = SymCopy.ForceExport;
344
1.18k
  return S2;
345
1.18k
}
lld::wasm::DefinedFunction* lld::wasm::replaceSymbol<lld::wasm::DefinedFunction, llvm::StringRef, unsigned int&, std::nullptr_t, lld::wasm::SyntheticFunction*&>(lld::wasm::Symbol*, llvm::StringRef&&, unsigned int&&&, std::nullptr_t&&, lld::wasm::SyntheticFunction*&&&)
Line
Count
Source
330
7
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
7
  static_assert(std::is_trivially_destructible<T>(),
332
7
                "Symbol types must be trivially destructible");
333
7
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
7
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
7
                "SymbolUnion not aligned enough");
336
7
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
7
         "Not a Symbol");
338
7
339
7
  Symbol SymCopy = *S;
340
7
341
7
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
7
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
7
  S2->ForceExport = SymCopy.ForceExport;
344
7
  return S2;
345
7
}
lld::wasm::UndefinedFunction* lld::wasm::replaceSymbol<lld::wasm::UndefinedFunction, llvm::StringRef, int, lld::wasm::InputFile*, llvm::wasm::WasmSignature const*&>(lld::wasm::Symbol*, llvm::StringRef&&, int&&, lld::wasm::InputFile*&&, llvm::wasm::WasmSignature const*&&&)
Line
Count
Source
330
39
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
39
  static_assert(std::is_trivially_destructible<T>(),
332
39
                "Symbol types must be trivially destructible");
333
39
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
39
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
39
                "SymbolUnion not aligned enough");
336
39
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
39
         "Not a Symbol");
338
39
339
39
  Symbol SymCopy = *S;
340
39
341
39
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
39
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
39
  S2->ForceExport = SymCopy.ForceExport;
344
39
  return S2;
345
39
}
lld::wasm::UndefinedData* lld::wasm::replaceSymbol<lld::wasm::UndefinedData, llvm::StringRef, int, lld::wasm::InputFile*>(lld::wasm::Symbol*, llvm::StringRef&&, int&&, lld::wasm::InputFile*&&)
Line
Count
Source
330
2
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
2
  static_assert(std::is_trivially_destructible<T>(),
332
2
                "Symbol types must be trivially destructible");
333
2
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
2
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
2
                "SymbolUnion not aligned enough");
336
2
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
2
         "Not a Symbol");
338
2
339
2
  Symbol SymCopy = *S;
340
2
341
2
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
2
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
2
  S2->ForceExport = SymCopy.ForceExport;
344
2
  return S2;
345
2
}
lld::wasm::DefinedFunction* lld::wasm::replaceSymbol<lld::wasm::DefinedFunction, llvm::StringRef&, unsigned int&, std::nullptr_t, lld::wasm::InputFunction*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, std::nullptr_t&&, lld::wasm::InputFunction*&&&)
Line
Count
Source
330
104
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
104
  static_assert(std::is_trivially_destructible<T>(),
332
104
                "Symbol types must be trivially destructible");
333
104
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
104
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
104
                "SymbolUnion not aligned enough");
336
104
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
104
         "Not a Symbol");
338
104
339
104
  Symbol SymCopy = *S;
340
104
341
104
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
104
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
104
  S2->ForceExport = SymCopy.ForceExport;
344
104
  return S2;
345
104
}
lld::wasm::DefinedData* lld::wasm::replaceSymbol<lld::wasm::DefinedData, llvm::StringRef&, unsigned int&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&)
Line
Count
Source
330
312
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
312
  static_assert(std::is_trivially_destructible<T>(),
332
312
                "Symbol types must be trivially destructible");
333
312
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
312
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
312
                "SymbolUnion not aligned enough");
336
312
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
312
         "Not a Symbol");
338
312
339
312
  Symbol SymCopy = *S;
340
312
341
312
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
312
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
312
  S2->ForceExport = SymCopy.ForceExport;
344
312
  return S2;
345
312
}
lld::wasm::DefinedGlobal* lld::wasm::replaceSymbol<lld::wasm::DefinedGlobal, llvm::StringRef&, unsigned int&, std::nullptr_t, lld::wasm::InputGlobal*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, std::nullptr_t&&, lld::wasm::InputGlobal*&&&)
Line
Count
Source
330
104
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
104
  static_assert(std::is_trivially_destructible<T>(),
332
104
                "Symbol types must be trivially destructible");
333
104
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
104
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
104
                "SymbolUnion not aligned enough");
336
104
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
104
         "Not a Symbol");
338
104
339
104
  Symbol SymCopy = *S;
340
104
341
104
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
104
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
104
  S2->ForceExport = SymCopy.ForceExport;
344
104
  return S2;
345
104
}
lld::wasm::DefinedFunction* lld::wasm::replaceSymbol<lld::wasm::DefinedFunction, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, lld::wasm::InputFunction*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, lld::wasm::InputFunction*&&&)
Line
Count
Source
330
442
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
442
  static_assert(std::is_trivially_destructible<T>(),
332
442
                "Symbol types must be trivially destructible");
333
442
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
442
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
442
                "SymbolUnion not aligned enough");
336
442
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
442
         "Not a Symbol");
338
442
339
442
  Symbol SymCopy = *S;
340
442
341
442
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
442
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
442
  S2->ForceExport = SymCopy.ForceExport;
344
442
  return S2;
345
442
}
lld::wasm::DefinedData* lld::wasm::replaceSymbol<lld::wasm::DefinedData, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, lld::wasm::InputSegment*&, unsigned int&, unsigned int&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, lld::wasm::InputSegment*&&&, unsigned int&&&, unsigned int&&&)
Line
Count
Source
330
58
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
58
  static_assert(std::is_trivially_destructible<T>(),
332
58
                "Symbol types must be trivially destructible");
333
58
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
58
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
58
                "SymbolUnion not aligned enough");
336
58
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
58
         "Not a Symbol");
338
58
339
58
  Symbol SymCopy = *S;
340
58
341
58
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
58
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
58
  S2->ForceExport = SymCopy.ForceExport;
344
58
  return S2;
345
58
}
lld::wasm::DefinedGlobal* lld::wasm::replaceSymbol<lld::wasm::DefinedGlobal, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, lld::wasm::InputGlobal*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, lld::wasm::InputGlobal*&&&)
Line
Count
Source
330
4
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
4
  static_assert(std::is_trivially_destructible<T>(),
332
4
                "Symbol types must be trivially destructible");
333
4
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
4
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
4
                "SymbolUnion not aligned enough");
336
4
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
4
         "Not a Symbol");
338
4
339
4
  Symbol SymCopy = *S;
340
4
341
4
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
4
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
4
  S2->ForceExport = SymCopy.ForceExport;
344
4
  return S2;
345
4
}
lld::wasm::UndefinedFunction* lld::wasm::replaceSymbol<lld::wasm::UndefinedFunction, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, llvm::wasm::WasmSignature const*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, llvm::wasm::WasmSignature const*&&&)
Line
Count
Source
330
65
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
65
  static_assert(std::is_trivially_destructible<T>(),
332
65
                "Symbol types must be trivially destructible");
333
65
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
65
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
65
                "SymbolUnion not aligned enough");
336
65
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
65
         "Not a Symbol");
338
65
339
65
  Symbol SymCopy = *S;
340
65
341
65
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
65
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
65
  S2->ForceExport = SymCopy.ForceExport;
344
65
  return S2;
345
65
}
lld::wasm::UndefinedData* lld::wasm::replaceSymbol<lld::wasm::UndefinedData, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&)
Line
Count
Source
330
8
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
8
  static_assert(std::is_trivially_destructible<T>(),
332
8
                "Symbol types must be trivially destructible");
333
8
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
8
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
8
                "SymbolUnion not aligned enough");
336
8
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
8
         "Not a Symbol");
338
8
339
8
  Symbol SymCopy = *S;
340
8
341
8
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
8
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
8
  S2->ForceExport = SymCopy.ForceExport;
344
8
  return S2;
345
8
}
lld::wasm::UndefinedGlobal* lld::wasm::replaceSymbol<lld::wasm::UndefinedGlobal, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, llvm::wasm::WasmGlobalType const*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, llvm::wasm::WasmGlobalType const*&&&)
Line
Count
Source
330
8
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
8
  static_assert(std::is_trivially_destructible<T>(),
332
8
                "Symbol types must be trivially destructible");
333
8
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
8
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
8
                "SymbolUnion not aligned enough");
336
8
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
8
         "Not a Symbol");
338
8
339
8
  Symbol SymCopy = *S;
340
8
341
8
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
8
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
8
  S2->ForceExport = SymCopy.ForceExport;
344
8
  return S2;
345
8
}
lld::wasm::LazySymbol* lld::wasm::replaceSymbol<lld::wasm::LazySymbol, llvm::StringRef&, lld::wasm::ArchiveFile*&, llvm::object::Archive::Symbol const&>(lld::wasm::Symbol*, llvm::StringRef&&&, lld::wasm::ArchiveFile*&&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
330
35
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
331
35
  static_assert(std::is_trivially_destructible<T>(),
332
35
                "Symbol types must be trivially destructible");
333
35
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
334
35
  static_assert(alignof(T) <= alignof(SymbolUnion),
335
35
                "SymbolUnion not aligned enough");
336
35
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
337
35
         "Not a Symbol");
338
35
339
35
  Symbol SymCopy = *S;
340
35
341
35
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
342
35
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
343
35
  S2->ForceExport = SymCopy.ForceExport;
344
35
  return S2;
345
35
}
346
347
} // namespace wasm
348
349
// Returns a symbol name for an error message.
350
std::string toString(const wasm::Symbol &Sym);
351
std::string toString(wasm::Symbol::Kind Kind);
352
353
} // namespace lld
354
355
#endif