Coverage Report

Created: 2019-01-21 03:01

/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
// 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_WASM_SYMBOLS_H
10
#define LLD_WASM_SYMBOLS_H
11
12
#include "Config.h"
13
#include "lld/Common/LLVM.h"
14
#include "llvm/Object/Archive.h"
15
#include "llvm/Object/Wasm.h"
16
17
namespace lld {
18
namespace wasm {
19
20
using llvm::wasm::WasmSymbolType;
21
22
class InputFile;
23
class InputChunk;
24
class InputSegment;
25
class InputFunction;
26
class InputGlobal;
27
class InputEvent;
28
class InputSection;
29
30
7
#define INVALID_INDEX UINT32_MAX
31
32
// The base class for real symbol classes.
33
class Symbol {
34
public:
35
  enum Kind {
36
    DefinedFunctionKind,
37
    DefinedDataKind,
38
    DefinedGlobalKind,
39
    DefinedEventKind,
40
    SectionKind,
41
    UndefinedFunctionKind,
42
    UndefinedDataKind,
43
    UndefinedGlobalKind,
44
    LazyKind,
45
  };
46
47
9.62k
  Kind kind() const { return SymbolKind; }
48
49
1.72k
  bool isDefined() const {
50
1.72k
    return SymbolKind == DefinedFunctionKind || 
SymbolKind == DefinedDataKind874
||
51
1.72k
           
SymbolKind == DefinedGlobalKind323
||
SymbolKind == DefinedEventKind154
||
52
1.72k
           
SymbolKind == SectionKind151
;
53
1.72k
  }
54
55
2.72k
  bool isUndefined() const {
56
2.72k
    return SymbolKind == UndefinedFunctionKind ||
57
2.72k
           
SymbolKind == UndefinedDataKind2.66k
||
SymbolKind == UndefinedGlobalKind2.65k
;
58
2.72k
  }
59
60
104
  bool isLazy() const { return SymbolKind == LazyKind; }
61
62
  bool isLocal() const;
63
  bool isWeak() const;
64
  bool isHidden() const;
65
66
  // Returns the symbol name.
67
686
  StringRef getName() const { return Name; }
68
69
  // Returns the file from which this symbol was created.
70
337
  InputFile *getFile() const { return File; }
71
72
  InputChunk *getChunk() const;
73
74
  // Indicates that the section or import for this symbol will be included in
75
  // the final image.
76
  bool isLive() const;
77
78
  // Marks the symbol's InputChunk as Live, so that it will be included in the
79
  // final image.
80
  void markLive();
81
82
  void setHidden(bool IsHidden);
83
84
  // Get/set the index in the output symbol table.  This is only used for
85
  // relocatable output.
86
  uint32_t getOutputSymbolIndex() const;
87
  void setOutputSymbolIndex(uint32_t Index);
88
89
  WasmSymbolType getWasmType() const;
90
  bool isExported() const;
91
92
  // True if this symbol was referenced by a regular (non-bitcode) object.
93
  unsigned IsUsedInRegularObj : 1;
94
  unsigned ForceExport : 1;
95
96
protected:
97
  Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
98
      : IsUsedInRegularObj(false), ForceExport(false), Name(Name),
99
1.32k
        SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
100
101
  StringRef Name;
102
  Kind SymbolKind;
103
  uint32_t Flags;
104
  InputFile *File;
105
  uint32_t OutputSymbolIndex = INVALID_INDEX;
106
  bool Referenced;
107
};
108
109
class FunctionSymbol : public Symbol {
110
public:
111
740
  static bool classof(const Symbol *S) {
112
740
    return S->kind() == DefinedFunctionKind ||
113
740
           
S->kind() == UndefinedFunctionKind327
;
114
740
  }
115
116
  // Get/set the table index
117
  void setTableIndex(uint32_t Index);
118
  uint32_t getTableIndex() const;
119
  bool hasTableIndex() const;
120
121
  // Get/set the function index
122
  uint32_t getFunctionIndex() const;
123
  void setFunctionIndex(uint32_t Index);
124
  bool hasFunctionIndex() const;
125
126
  const WasmSignature *Signature;
127
128
protected:
129
  FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
130
                 const WasmSignature *Sig)
131
715
      : Symbol(Name, K, Flags, F), Signature(Sig) {}
132
133
  uint32_t TableIndex = INVALID_INDEX;
134
  uint32_t FunctionIndex = INVALID_INDEX;
135
};
136
137
class DefinedFunction : public FunctionSymbol {
138
public:
139
  DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
140
                  InputFunction *Function);
141
142
3.14k
  static bool classof(const Symbol *S) {
143
3.14k
    return S->kind() == DefinedFunctionKind;
144
3.14k
  }
145
146
  InputFunction *Function;
147
};
148
149
class UndefinedFunction : public FunctionSymbol {
150
public:
151
  UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
152
                    const WasmSignature *Type = nullptr)
153
108
      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {}
154
155
0
  static bool classof(const Symbol *S) {
156
0
    return S->kind() == UndefinedFunctionKind;
157
0
  }
158
};
159
160
class SectionSymbol : public Symbol {
161
public:
162
233
  static bool classof(const Symbol *S) { return S->kind() == SectionKind; }
163
164
  SectionSymbol(StringRef Name, uint32_t Flags, const InputSection *S,
165
                InputFile *F = nullptr)
166
14
      : Symbol(Name, SectionKind, Flags, F), Section(S) {}
167
168
  const InputSection *Section;
169
170
  uint32_t getOutputSectionIndex() const;
171
  void setOutputSectionIndex(uint32_t Index);
172
173
protected:
174
  uint32_t OutputSectionIndex = INVALID_INDEX;
175
};
176
177
class DataSymbol : public Symbol {
178
public:
179
101
  static bool classof(const Symbol *S) {
180
101
    return S->kind() == DefinedDataKind || 
S->kind() == UndefinedDataKind53
;
181
101
  }
182
183
protected:
184
  DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
185
431
      : Symbol(Name, K, Flags, F) {}
186
};
187
188
class DefinedData : public DataSymbol {
189
public:
190
  // Constructor for regular data symbols originating from input files.
191
  DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
192
              InputSegment *Segment, uint32_t Offset, uint32_t Size)
193
      : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
194
89
        Offset(Offset), Size(Size) {}
195
196
  // Constructor for linker synthetic data symbols.
197
  DefinedData(StringRef Name, uint32_t Flags)
198
331
      : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {}
199
200
1.17k
  static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; }
201
202
  // Returns the output virtual address of a defined data symbol.
203
  uint32_t getVirtualAddress() const;
204
  void setVirtualAddress(uint32_t VA);
205
206
  // Returns the offset of a defined data symbol within its OutputSegment.
207
  uint32_t getOutputSegmentOffset() const;
208
  uint32_t getOutputSegmentIndex() const;
209
22
  uint32_t getSize() const { return Size; }
210
211
  InputSegment *Segment = nullptr;
212
213
protected:
214
  uint32_t Offset = 0;
215
  uint32_t Size = 0;
216
};
217
218
class UndefinedData : public DataSymbol {
219
public:
220
  UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
221
11
      : DataSymbol(Name, UndefinedDataKind, Flags, File) {}
222
0
  static bool classof(const Symbol *S) {
223
0
    return S->kind() == UndefinedDataKind;
224
0
  }
225
};
226
227
class GlobalSymbol : public Symbol {
228
public:
229
55
  static bool classof(const Symbol *S) {
230
55
    return S->kind() == DefinedGlobalKind || 
S->kind() == UndefinedGlobalKind52
;
231
55
  }
232
233
15
  const WasmGlobalType *getGlobalType() const { return GlobalType; }
234
235
  // Get/set the global index
236
  uint32_t getGlobalIndex() const;
237
  void setGlobalIndex(uint32_t Index);
238
  bool hasGlobalIndex() const;
239
240
protected:
241
  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
242
               const WasmGlobalType *GlobalType)
243
125
      : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
244
245
  const WasmGlobalType *GlobalType;
246
  uint32_t GlobalIndex = INVALID_INDEX;
247
};
248
249
class DefinedGlobal : public GlobalSymbol {
250
public:
251
  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
252
                InputGlobal *Global);
253
254
1.81k
  static bool classof(const Symbol *S) {
255
1.81k
    return S->kind() == DefinedGlobalKind;
256
1.81k
  }
257
258
  InputGlobal *Global;
259
};
260
261
class UndefinedGlobal : public GlobalSymbol {
262
public:
263
  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
264
                  const WasmGlobalType *Type = nullptr)
265
11
      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {}
266
267
0
  static bool classof(const Symbol *S) {
268
0
    return S->kind() == UndefinedGlobalKind;
269
0
  }
270
};
271
272
// Wasm events are features that suspend the current execution and transfer the
273
// control flow to a corresponding handler. Currently the only supported event
274
// kind is exceptions.
275
//
276
// Event tags are values to distinguish different events. For exceptions, they
277
// can be used to distinguish different language's exceptions, i.e., all C++
278
// exceptions have the same tag. Wasm can generate code capable of doing
279
// different handling actions based on the tag of caught exceptions.
280
//
281
// A single EventSymbol object represents a single tag. C++ exception event
282
// symbol is a weak symbol generated in every object file in which exceptions
283
// are used, and has name '__cpp_exception' for linking.
284
class EventSymbol : public Symbol {
285
public:
286
36
  static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
287
288
1
  const WasmEventType *getEventType() const { return EventType; }
289
290
  // Get/set the event index
291
  uint32_t getEventIndex() const;
292
  void setEventIndex(uint32_t Index);
293
  bool hasEventIndex() const;
294
295
  const WasmSignature *Signature;
296
297
protected:
298
  EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
299
              const WasmEventType *EventType, const WasmSignature *Sig)
300
1
      : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {}
301
302
  const WasmEventType *EventType;
303
  uint32_t EventIndex = INVALID_INDEX;
304
};
305
306
class DefinedEvent : public EventSymbol {
307
public:
308
  DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
309
               InputEvent *Event);
310
311
1.76k
  static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
312
313
  InputEvent *Event;
314
};
315
316
class LazySymbol : public Symbol {
317
public:
318
  LazySymbol(StringRef Name, InputFile *File,
319
             const llvm::object::Archive::Symbol &Sym)
320
35
      : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
321
322
128
  static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
323
  void fetch();
324
325
private:
326
  llvm::object::Archive::Symbol ArchiveSymbol;
327
};
328
329
// linker-generated symbols
330
struct WasmSym {
331
  // __stack_pointer
332
  // Global that holds the address of the top of the explicit value stack in
333
  // linear memory.
334
  static GlobalSymbol *StackPointer;
335
336
  // __data_end
337
  // Symbol marking the end of the data and bss.
338
  static DefinedData *DataEnd;
339
340
  // __heap_base
341
  // Symbol marking the end of the data, bss and explicit stack.  Any linear
342
  // memory following this address is not used by the linked code and can
343
  // therefore be used as a backing store for brk()/malloc() implementations.
344
  static DefinedData *HeapBase;
345
346
  // __wasm_call_ctors
347
  // Function that directly calls all ctors in priority order.
348
  static DefinedFunction *CallCtors;
349
350
  // __dso_handle
351
  // Symbol used in calls to __cxa_atexit to determine current DLL
352
  static DefinedData *DsoHandle;
353
354
  // __table_base
355
  // Used in PIC code for offset of indirect function table
356
  static UndefinedGlobal *TableBase;
357
358
  // __memory_base
359
  // Used in PIC code for offset of global data
360
  static UndefinedGlobal *MemoryBase;
361
};
362
363
// A buffer class that is large enough to hold any Symbol-derived
364
// object. We allocate memory using this class and instantiate a symbol
365
// using the placement new.
366
union SymbolUnion {
367
  alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
368
  alignas(DefinedData) char B[sizeof(DefinedData)];
369
  alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
370
  alignas(DefinedEvent) char D[sizeof(DefinedEvent)];
371
  alignas(LazySymbol) char E[sizeof(LazySymbol)];
372
  alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)];
373
  alignas(UndefinedData) char G[sizeof(UndefinedData)];
374
  alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)];
375
  alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
376
};
377
378
template <typename T, typename... ArgT>
379
1.24k
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
1.24k
  static_assert(std::is_trivially_destructible<T>(),
381
1.24k
                "Symbol types must be trivially destructible");
382
1.24k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
1.24k
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
1.24k
                "SymbolUnion not aligned enough");
385
1.24k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
1.24k
         "Not a Symbol");
387
1.24k
388
1.24k
  Symbol SymCopy = *S;
389
1.24k
390
1.24k
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
1.24k
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
1.24k
  S2->ForceExport = SymCopy.ForceExport;
393
1.24k
  return S2;
394
1.24k
}
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
379
7
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
7
  static_assert(std::is_trivially_destructible<T>(),
381
7
                "Symbol types must be trivially destructible");
382
7
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
7
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
7
                "SymbolUnion not aligned enough");
385
7
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
7
         "Not a Symbol");
387
7
388
7
  Symbol SymCopy = *S;
389
7
390
7
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
7
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
7
  S2->ForceExport = SymCopy.ForceExport;
393
7
  return S2;
394
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
379
39
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
39
  static_assert(std::is_trivially_destructible<T>(),
381
39
                "Symbol types must be trivially destructible");
382
39
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
39
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
39
                "SymbolUnion not aligned enough");
385
39
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
39
         "Not a Symbol");
387
39
388
39
  Symbol SymCopy = *S;
389
39
390
39
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
39
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
39
  S2->ForceExport = SymCopy.ForceExport;
393
39
  return S2;
394
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
379
2
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
2
  static_assert(std::is_trivially_destructible<T>(),
381
2
                "Symbol types must be trivially destructible");
382
2
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
2
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
2
                "SymbolUnion not aligned enough");
385
2
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
2
         "Not a Symbol");
387
2
388
2
  Symbol SymCopy = *S;
389
2
390
2
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
2
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
2
  S2->ForceExport = SymCopy.ForceExport;
393
2
  return S2;
394
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
379
111
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
111
  static_assert(std::is_trivially_destructible<T>(),
381
111
                "Symbol types must be trivially destructible");
382
111
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
111
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
111
                "SymbolUnion not aligned enough");
385
111
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
111
         "Not a Symbol");
387
111
388
111
  Symbol SymCopy = *S;
389
111
390
111
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
111
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
111
  S2->ForceExport = SymCopy.ForceExport;
393
111
  return S2;
394
111
}
lld::wasm::DefinedData* lld::wasm::replaceSymbol<lld::wasm::DefinedData, llvm::StringRef&, unsigned int&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&)
Line
Count
Source
379
331
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
331
  static_assert(std::is_trivially_destructible<T>(),
381
331
                "Symbol types must be trivially destructible");
382
331
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
331
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
331
                "SymbolUnion not aligned enough");
385
331
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
331
         "Not a Symbol");
387
331
388
331
  Symbol SymCopy = *S;
389
331
390
331
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
331
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
331
  S2->ForceExport = SymCopy.ForceExport;
393
331
  return S2;
394
331
}
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
379
110
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
110
  static_assert(std::is_trivially_destructible<T>(),
381
110
                "Symbol types must be trivially destructible");
382
110
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
110
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
110
                "SymbolUnion not aligned enough");
385
110
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
110
         "Not a Symbol");
387
110
388
110
  Symbol SymCopy = *S;
389
110
390
110
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
110
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
110
  S2->ForceExport = SymCopy.ForceExport;
393
110
  return S2;
394
110
}
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
379
451
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
451
  static_assert(std::is_trivially_destructible<T>(),
381
451
                "Symbol types must be trivially destructible");
382
451
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
451
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
451
                "SymbolUnion not aligned enough");
385
451
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
451
         "Not a Symbol");
387
451
388
451
  Symbol SymCopy = *S;
389
451
390
451
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
451
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
451
  S2->ForceExport = SymCopy.ForceExport;
393
451
  return S2;
394
451
}
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
379
67
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
67
  static_assert(std::is_trivially_destructible<T>(),
381
67
                "Symbol types must be trivially destructible");
382
67
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
67
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
67
                "SymbolUnion not aligned enough");
385
67
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
67
         "Not a Symbol");
387
67
388
67
  Symbol SymCopy = *S;
389
67
390
67
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
67
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
67
  S2->ForceExport = SymCopy.ForceExport;
393
67
  return S2;
394
67
}
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
379
4
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
4
  static_assert(std::is_trivially_destructible<T>(),
381
4
                "Symbol types must be trivially destructible");
382
4
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
4
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
4
                "SymbolUnion not aligned enough");
385
4
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
4
         "Not a Symbol");
387
4
388
4
  Symbol SymCopy = *S;
389
4
390
4
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
4
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
4
  S2->ForceExport = SymCopy.ForceExport;
393
4
  return S2;
394
4
}
lld::wasm::DefinedEvent* lld::wasm::replaceSymbol<lld::wasm::DefinedEvent, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, lld::wasm::InputEvent*&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, lld::wasm::InputEvent*&&&)
Line
Count
Source
379
1
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
1
  static_assert(std::is_trivially_destructible<T>(),
381
1
                "Symbol types must be trivially destructible");
382
1
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
1
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
1
                "SymbolUnion not aligned enough");
385
1
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
1
         "Not a Symbol");
387
1
388
1
  Symbol SymCopy = *S;
389
1
390
1
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
1
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
1
  S2->ForceExport = SymCopy.ForceExport;
393
1
  return S2;
394
1
}
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
379
69
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
69
  static_assert(std::is_trivially_destructible<T>(),
381
69
                "Symbol types must be trivially destructible");
382
69
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
69
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
69
                "SymbolUnion not aligned enough");
385
69
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
69
         "Not a Symbol");
387
69
388
69
  Symbol SymCopy = *S;
389
69
390
69
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
69
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
69
  S2->ForceExport = SymCopy.ForceExport;
393
69
  return S2;
394
69
}
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
379
9
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
9
  static_assert(std::is_trivially_destructible<T>(),
381
9
                "Symbol types must be trivially destructible");
382
9
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
9
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
9
                "SymbolUnion not aligned enough");
385
9
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
9
         "Not a Symbol");
387
9
388
9
  Symbol SymCopy = *S;
389
9
390
9
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
9
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
9
  S2->ForceExport = SymCopy.ForceExport;
393
9
  return S2;
394
9
}
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
379
11
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
11
  static_assert(std::is_trivially_destructible<T>(),
381
11
                "Symbol types must be trivially destructible");
382
11
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
11
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
11
                "SymbolUnion not aligned enough");
385
11
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
11
         "Not a Symbol");
387
11
388
11
  Symbol SymCopy = *S;
389
11
390
11
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
11
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
11
  S2->ForceExport = SymCopy.ForceExport;
393
11
  return S2;
394
11
}
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
379
35
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
380
35
  static_assert(std::is_trivially_destructible<T>(),
381
35
                "Symbol types must be trivially destructible");
382
35
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
383
35
  static_assert(alignof(T) <= alignof(SymbolUnion),
384
35
                "SymbolUnion not aligned enough");
385
35
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
386
35
         "Not a Symbol");
387
35
388
35
  Symbol SymCopy = *S;
389
35
390
35
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
391
35
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
392
35
  S2->ForceExport = SymCopy.ForceExport;
393
35
  return S2;
394
35
}
395
396
} // namespace wasm
397
398
// Returns a symbol name for an error message.
399
std::string toString(const wasm::Symbol &Sym);
400
std::string toString(wasm::Symbol::Kind Kind);
401
std::string maybeDemangleSymbol(StringRef Name);
402
403
} // namespace lld
404
405
#endif