Coverage Report

Created: 2019-05-22 02:55

/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
// Shared string constants
21
22
// The default module name to use for symbol imports.
23
extern const char *DefaultModule;
24
25
// The name under which to import or export the wasm table.
26
extern const char *FunctionTableName;
27
28
using llvm::wasm::WasmSymbolType;
29
30
class InputFile;
31
class InputChunk;
32
class InputSegment;
33
class InputFunction;
34
class InputGlobal;
35
class InputEvent;
36
class InputSection;
37
class OutputSection;
38
39
2
#define INVALID_INDEX UINT32_MAX
40
41
// The base class for real symbol classes.
42
class Symbol {
43
public:
44
  enum Kind {
45
    DefinedFunctionKind,
46
    DefinedDataKind,
47
    DefinedGlobalKind,
48
    DefinedEventKind,
49
    SectionKind,
50
    OutputSectionKind,
51
    UndefinedFunctionKind,
52
    UndefinedDataKind,
53
    UndefinedGlobalKind,
54
    LazyKind,
55
  };
56
57
9.16k
  Kind kind() const { return SymbolKind; }
58
59
1.32k
  bool isDefined() const { return !isLazy() && 
!isUndefined()1.30k
; }
60
61
2.95k
  bool isUndefined() const {
62
2.95k
    return SymbolKind == UndefinedFunctionKind ||
63
2.95k
           
SymbolKind == UndefinedDataKind2.86k
||
SymbolKind == UndefinedGlobalKind2.83k
;
64
2.95k
  }
65
66
1.39k
  bool isLazy() const { return SymbolKind == LazyKind; }
67
68
  bool isLocal() const;
69
  bool isWeak() const;
70
  bool isHidden() const;
71
72
  // True if this is an undefined weak symbol. This only works once
73
  // all input files have been added.
74
562
  bool isUndefWeak() const {
75
562
    // See comment on lazy symbols for details.
76
562
    return isWeak() && 
(7
isUndefined()7
||
isLazy()3
);
77
562
  }
78
79
  // Returns the symbol name.
80
538
  StringRef getName() const { return Name; }
81
82
  // Returns the file from which this symbol was created.
83
66
  InputFile *getFile() const { return File; }
84
85
7
  uint32_t getFlags() const { return Flags; }
86
87
  InputChunk *getChunk() const;
88
89
  // Indicates that the section or import for this symbol will be included in
90
  // the final image.
91
  bool isLive() const;
92
93
  // Marks the symbol's InputChunk as Live, so that it will be included in the
94
  // final image.
95
  void markLive();
96
97
  void setHidden(bool IsHidden);
98
99
  // Get/set the index in the output symbol table.  This is only used for
100
  // relocatable output.
101
  uint32_t getOutputSymbolIndex() const;
102
  void setOutputSymbolIndex(uint32_t Index);
103
104
  WasmSymbolType getWasmType() const;
105
  bool isExported() const;
106
107
  // True if the symbol was used for linking and thus need to be added to the
108
  // output file's symbol table. This is true for all symbols except for
109
  // unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that
110
  // are unreferenced except by other bitcode objects.
111
  unsigned IsUsedInRegularObj : 1;
112
113
  // True if ths symbol is explicity marked for export (i.e. via the -e/--export
114
  // command line flag)
115
  unsigned ForceExport : 1;
116
117
  // True if this symbol is specified by --trace-symbol option.
118
  unsigned Traced : 1;
119
120
  const WasmSignature* getSignature() const;
121
122
0
  bool isInGOT() const { return GOTIndex != INVALID_INDEX; }
123
124
0
  uint32_t getGOTIndex() const {
125
0
    assert(GOTIndex != INVALID_INDEX);
126
0
    return GOTIndex;
127
0
  }
128
129
  void setGOTIndex(uint32_t Index);
130
0
  bool hasGOTIndex() const { return GOTIndex != INVALID_INDEX; }
131
132
protected:
133
  Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
134
      : IsUsedInRegularObj(false), ForceExport(false), Traced(false),
135
        Name(Name), SymbolKind(K), Flags(Flags), File(F),
136
983
        Referenced(!Config->GcSections) {}
137
138
  StringRef Name;
139
  Kind SymbolKind;
140
  uint32_t Flags;
141
  InputFile *File;
142
  uint32_t OutputSymbolIndex = INVALID_INDEX;
143
  uint32_t GOTIndex = INVALID_INDEX;
144
  bool Referenced;
145
};
146
147
class FunctionSymbol : public Symbol {
148
public:
149
1.21k
  static bool classof(const Symbol *S) {
150
1.21k
    return S->kind() == DefinedFunctionKind ||
151
1.21k
           
S->kind() == UndefinedFunctionKind459
;
152
1.21k
  }
153
154
  // Get/set the table index
155
  void setTableIndex(uint32_t Index);
156
  uint32_t getTableIndex() const;
157
  bool hasTableIndex() const;
158
159
  // Get/set the function index
160
  uint32_t getFunctionIndex() const;
161
  void setFunctionIndex(uint32_t Index);
162
  bool hasFunctionIndex() const;
163
164
  const WasmSignature *Signature;
165
166
protected:
167
  FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
168
                 const WasmSignature *Sig)
169
520
      : Symbol(Name, K, Flags, F), Signature(Sig) {}
170
171
  uint32_t TableIndex = INVALID_INDEX;
172
  uint32_t FunctionIndex = INVALID_INDEX;
173
};
174
175
class DefinedFunction : public FunctionSymbol {
176
public:
177
  DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
178
                  InputFunction *Function);
179
180
2.18k
  static bool classof(const Symbol *S) {
181
2.18k
    return S->kind() == DefinedFunctionKind;
182
2.18k
  }
183
184
  InputFunction *Function;
185
};
186
187
class UndefinedFunction : public FunctionSymbol {
188
public:
189
  UndefinedFunction(StringRef Name, StringRef ImportName,
190
                    StringRef ImportModule, uint32_t Flags,
191
                    InputFile *File = nullptr,
192
                    const WasmSignature *Type = nullptr)
193
      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type),
194
65
        ImportName(ImportName), ImportModule(ImportModule) {}
195
196
227
  static bool classof(const Symbol *S) {
197
227
    return S->kind() == UndefinedFunctionKind;
198
227
  }
199
200
  StringRef ImportName;
201
  StringRef ImportModule;
202
};
203
204
// Section symbols for output sections are different from those for input
205
// section.  These are generated by the linker and point the OutputSection
206
// rather than an InputSection.
207
class OutputSectionSymbol : public Symbol {
208
public:
209
  OutputSectionSymbol(const OutputSection *S)
210
      : Symbol("", OutputSectionKind, llvm::wasm::WASM_SYMBOL_BINDING_LOCAL,
211
               nullptr),
212
0
        Section(S) {}
213
214
0
  static bool classof(const Symbol *S) {
215
0
    return S->kind() == OutputSectionKind;
216
0
  }
217
218
  const OutputSection *Section;
219
};
220
221
class SectionSymbol : public Symbol {
222
public:
223
  SectionSymbol(uint32_t Flags, const InputSection *S, InputFile *F = nullptr)
224
16
      : Symbol("", SectionKind, Flags, F), Section(S) {}
225
226
213
  static bool classof(const Symbol *S) { return S->kind() == SectionKind; }
227
228
  const OutputSectionSymbol *getOutputSectionSymbol() const;
229
230
  const InputSection *Section;
231
};
232
233
class DataSymbol : public Symbol {
234
public:
235
596
  static bool classof(const Symbol *S) {
236
596
    return S->kind() == DefinedDataKind || 
S->kind() == UndefinedDataKind254
;
237
596
  }
238
239
protected:
240
  DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
241
327
      : Symbol(Name, K, Flags, F) {}
242
};
243
244
class DefinedData : public DataSymbol {
245
public:
246
  // Constructor for regular data symbols originating from input files.
247
  DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
248
              InputSegment *Segment, uint32_t Offset, uint32_t Size)
249
      : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
250
54
        Offset(Offset), Size(Size) {}
251
252
  // Constructor for linker synthetic data symbols.
253
  DefinedData(StringRef Name, uint32_t Flags)
254
265
      : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {}
255
256
811
  static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; }
257
258
  // Returns the output virtual address of a defined data symbol.
259
  uint32_t getVirtualAddress() const;
260
  void setVirtualAddress(uint32_t VA);
261
262
  // Returns the offset of a defined data symbol within its OutputSegment.
263
  uint32_t getOutputSegmentOffset() const;
264
  uint32_t getOutputSegmentIndex() const;
265
14
  uint32_t getSize() const { return Size; }
266
267
  InputSegment *Segment = nullptr;
268
269
protected:
270
  uint32_t Offset = 0;
271
  uint32_t Size = 0;
272
};
273
274
class UndefinedData : public DataSymbol {
275
public:
276
  UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
277
8
      : DataSymbol(Name, UndefinedDataKind, Flags, File) {}
278
0
  static bool classof(const Symbol *S) {
279
0
    return S->kind() == UndefinedDataKind;
280
0
  }
281
};
282
283
class GlobalSymbol : public Symbol {
284
public:
285
60
  static bool classof(const Symbol *S) {
286
60
    return S->kind() == DefinedGlobalKind || 
S->kind() == UndefinedGlobalKind43
;
287
60
  }
288
289
5
  const WasmGlobalType *getGlobalType() const { return GlobalType; }
290
291
  // Get/set the global index
292
  uint32_t getGlobalIndex() const;
293
  void setGlobalIndex(uint32_t Index);
294
  bool hasGlobalIndex() const;
295
296
protected:
297
  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
298
               const WasmGlobalType *GlobalType)
299
97
      : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
300
301
  const WasmGlobalType *GlobalType;
302
  uint32_t GlobalIndex = INVALID_INDEX;
303
};
304
305
class DefinedGlobal : public GlobalSymbol {
306
public:
307
  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
308
                InputGlobal *Global);
309
310
1.39k
  static bool classof(const Symbol *S) {
311
1.39k
    return S->kind() == DefinedGlobalKind;
312
1.39k
  }
313
314
  InputGlobal *Global;
315
};
316
317
class UndefinedGlobal : public GlobalSymbol {
318
public:
319
  UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule,
320
                  uint32_t Flags, InputFile *File = nullptr,
321
                  const WasmGlobalType *Type = nullptr)
322
      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type),
323
5
        ImportName(ImportName), ImportModule(ImportModule) {}
324
325
207
  static bool classof(const Symbol *S) {
326
207
    return S->kind() == UndefinedGlobalKind;
327
207
  }
328
329
  StringRef ImportName;
330
  StringRef ImportModule;
331
};
332
333
// Wasm events are features that suspend the current execution and transfer the
334
// control flow to a corresponding handler. Currently the only supported event
335
// kind is exceptions.
336
//
337
// Event tags are values to distinguish different events. For exceptions, they
338
// can be used to distinguish different language's exceptions, i.e., all C++
339
// exceptions have the same tag. Wasm can generate code capable of doing
340
// different handling actions based on the tag of caught exceptions.
341
//
342
// A single EventSymbol object represents a single tag. C++ exception event
343
// symbol is a weak symbol generated in every object file in which exceptions
344
// are used, and has name '__cpp_exception' for linking.
345
class EventSymbol : public Symbol {
346
public:
347
21
  static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
348
349
0
  const WasmEventType *getEventType() const { return EventType; }
350
351
  // Get/set the event index
352
  uint32_t getEventIndex() const;
353
  void setEventIndex(uint32_t Index);
354
  bool hasEventIndex() const;
355
356
  const WasmSignature *Signature;
357
358
protected:
359
  EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
360
              const WasmEventType *EventType, const WasmSignature *Sig)
361
0
      : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {}
362
363
  const WasmEventType *EventType;
364
  uint32_t EventIndex = INVALID_INDEX;
365
};
366
367
class DefinedEvent : public EventSymbol {
368
public:
369
  DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
370
               InputEvent *Event);
371
372
1.37k
  static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
373
374
  InputEvent *Event;
375
};
376
377
// LazySymbol represents a symbol that is not yet in the link, but we know where
378
// to find it if needed. If the resolver finds both Undefined and Lazy for the
379
// same name, it will ask the Lazy to load a file.
380
//
381
// A special complication is the handling of weak undefined symbols. They should
382
// not load a file, but we have to remember we have seen both the weak undefined
383
// and the lazy. We represent that with a lazy symbol with a weak binding. This
384
// means that code looking for undefined symbols normally also has to take lazy
385
// symbols into consideration.
386
class LazySymbol : public Symbol {
387
public:
388
  LazySymbol(StringRef Name, uint32_t Flags, InputFile *File,
389
             const llvm::object::Archive::Symbol &Sym)
390
23
      : Symbol(Name, LazyKind, Flags, File), ArchiveSymbol(Sym) {}
391
392
102
  static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
393
  void fetch();
394
395
  // Lazy symbols can have a signature because they can replace an
396
  // UndefinedFunction which which case we need to be able to preserve the
397
  // signture.
398
  // TODO(sbc): This repetition of the signature field is inelegant.  Revisit
399
  // the use of class hierarchy to represent symbol taxonomy.
400
  const WasmSignature *Signature = nullptr;
401
402
private:
403
  llvm::object::Archive::Symbol ArchiveSymbol;
404
};
405
406
// linker-generated symbols
407
struct WasmSym {
408
  // __stack_pointer
409
  // Global that holds the address of the top of the explicit value stack in
410
  // linear memory.
411
  static GlobalSymbol *StackPointer;
412
413
  // __data_end
414
  // Symbol marking the end of the data and bss.
415
  static DefinedData *DataEnd;
416
417
  // __heap_base
418
  // Symbol marking the end of the data, bss and explicit stack.  Any linear
419
  // memory following this address is not used by the linked code and can
420
  // therefore be used as a backing store for brk()/malloc() implementations.
421
  static DefinedData *HeapBase;
422
423
  // __wasm_call_ctors
424
  // Function that directly calls all ctors in priority order.
425
  static DefinedFunction *CallCtors;
426
427
  // __wasm_apply_relocs
428
  // Function that applies relocations to data segment post-instantiation.
429
  static DefinedFunction *ApplyRelocs;
430
431
  // __dso_handle
432
  // Symbol used in calls to __cxa_atexit to determine current DLL
433
  static DefinedData *DsoHandle;
434
435
  // __table_base
436
  // Used in PIC code for offset of indirect function table
437
  static UndefinedGlobal *TableBase;
438
439
  // __memory_base
440
  // Used in PIC code for offset of global data
441
  static UndefinedGlobal *MemoryBase;
442
};
443
444
// A buffer class that is large enough to hold any Symbol-derived
445
// object. We allocate memory using this class and instantiate a symbol
446
// using the placement new.
447
union SymbolUnion {
448
  alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
449
  alignas(DefinedData) char B[sizeof(DefinedData)];
450
  alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
451
  alignas(DefinedEvent) char D[sizeof(DefinedEvent)];
452
  alignas(LazySymbol) char E[sizeof(LazySymbol)];
453
  alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)];
454
  alignas(UndefinedData) char G[sizeof(UndefinedData)];
455
  alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)];
456
  alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
457
};
458
459
void printTraceSymbol(Symbol *Sym);
460
461
template <typename T, typename... ArgT>
462
933
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
933
  static_assert(std::is_trivially_destructible<T>(),
464
933
                "Symbol types must be trivially destructible");
465
933
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
933
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
933
                "SymbolUnion not aligned enough");
468
933
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
933
         "Not a Symbol");
470
933
471
933
  Symbol SymCopy = *S;
472
933
473
933
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
933
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
933
  S2->ForceExport = SymCopy.ForceExport;
476
933
  S2->Traced = SymCopy.Traced;
477
933
478
933
  // Print out a log message if --trace-symbol was specified.
479
933
  // This is for debugging.
480
933
  if (S2->Traced)
481
4
    printTraceSymbol(S2);
482
933
483
933
  return S2;
484
933
}
lld::wasm::UndefinedFunction* lld::wasm::replaceSymbol<lld::wasm::UndefinedFunction, llvm::StringRef, llvm::StringRef, char const*&, int, lld::wasm::InputFile*, llvm::wasm::WasmSignature const*&>(lld::wasm::Symbol*, llvm::StringRef&&, llvm::StringRef&&, char const*&&&, int&&, lld::wasm::InputFile*&&, llvm::wasm::WasmSignature const*&&&)
Line
Count
Source
462
23
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
23
  static_assert(std::is_trivially_destructible<T>(),
464
23
                "Symbol types must be trivially destructible");
465
23
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
23
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
23
                "SymbolUnion not aligned enough");
468
23
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
23
         "Not a Symbol");
470
23
471
23
  Symbol SymCopy = *S;
472
23
473
23
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
23
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
23
  S2->ForceExport = SymCopy.ForceExport;
476
23
  S2->Traced = SymCopy.Traced;
477
23
478
23
  // Print out a log message if --trace-symbol was specified.
479
23
  // This is for debugging.
480
23
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
23
483
23
  return S2;
484
23
}
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
462
1
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
1
  static_assert(std::is_trivially_destructible<T>(),
464
1
                "Symbol types must be trivially destructible");
465
1
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
1
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
1
                "SymbolUnion not aligned enough");
468
1
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
1
         "Not a Symbol");
470
1
471
1
  Symbol SymCopy = *S;
472
1
473
1
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
1
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
1
  S2->ForceExport = SymCopy.ForceExport;
476
1
  S2->Traced = SymCopy.Traced;
477
1
478
1
  // Print out a log message if --trace-symbol was specified.
479
1
  // This is for debugging.
480
1
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
1
483
1
  return S2;
484
1
}
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
462
335
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
335
  static_assert(std::is_trivially_destructible<T>(),
464
335
                "Symbol types must be trivially destructible");
465
335
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
335
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
335
                "SymbolUnion not aligned enough");
468
335
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
335
         "Not a Symbol");
470
335
471
335
  Symbol SymCopy = *S;
472
335
473
335
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
335
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
335
  S2->ForceExport = SymCopy.ForceExport;
476
335
  S2->Traced = SymCopy.Traced;
477
335
478
335
  // Print out a log message if --trace-symbol was specified.
479
335
  // This is for debugging.
480
335
  if (S2->Traced)
481
3
    printTraceSymbol(S2);
482
335
483
335
  return S2;
484
335
}
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
462
43
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
43
  static_assert(std::is_trivially_destructible<T>(),
464
43
                "Symbol types must be trivially destructible");
465
43
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
43
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
43
                "SymbolUnion not aligned enough");
468
43
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
43
         "Not a Symbol");
470
43
471
43
  Symbol SymCopy = *S;
472
43
473
43
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
43
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
43
  S2->ForceExport = SymCopy.ForceExport;
476
43
  S2->Traced = SymCopy.Traced;
477
43
478
43
  // Print out a log message if --trace-symbol was specified.
479
43
  // This is for debugging.
480
43
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
43
483
43
  return S2;
484
43
}
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
462
4
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
4
  static_assert(std::is_trivially_destructible<T>(),
464
4
                "Symbol types must be trivially destructible");
465
4
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
4
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
4
                "SymbolUnion not aligned enough");
468
4
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
4
         "Not a Symbol");
470
4
471
4
  Symbol SymCopy = *S;
472
4
473
4
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
4
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
4
  S2->ForceExport = SymCopy.ForceExport;
476
4
  S2->Traced = SymCopy.Traced;
477
4
478
4
  // Print out a log message if --trace-symbol was specified.
479
4
  // This is for debugging.
480
4
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
4
483
4
  return S2;
484
4
}
Unexecuted instantiation: 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*&&&)
lld::wasm::UndefinedFunction* lld::wasm::replaceSymbol<lld::wasm::UndefinedFunction, llvm::StringRef&, llvm::StringRef&, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, llvm::wasm::WasmSignature const*&>(lld::wasm::Symbol*, llvm::StringRef&&&, llvm::StringRef&&&, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, llvm::wasm::WasmSignature const*&&&)
Line
Count
Source
462
42
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
42
  static_assert(std::is_trivially_destructible<T>(),
464
42
                "Symbol types must be trivially destructible");
465
42
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
42
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
42
                "SymbolUnion not aligned enough");
468
42
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
42
         "Not a Symbol");
470
42
471
42
  Symbol SymCopy = *S;
472
42
473
42
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
42
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
42
  S2->ForceExport = SymCopy.ForceExport;
476
42
  S2->Traced = SymCopy.Traced;
477
42
478
42
  // Print out a log message if --trace-symbol was specified.
479
42
  // This is for debugging.
480
42
  if (S2->Traced)
481
1
    printTraceSymbol(S2);
482
42
483
42
  return S2;
484
42
}
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
462
90
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
90
  static_assert(std::is_trivially_destructible<T>(),
464
90
                "Symbol types must be trivially destructible");
465
90
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
90
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
90
                "SymbolUnion not aligned enough");
468
90
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
90
         "Not a Symbol");
470
90
471
90
  Symbol SymCopy = *S;
472
90
473
90
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
90
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
90
  S2->ForceExport = SymCopy.ForceExport;
476
90
  S2->Traced = SymCopy.Traced;
477
90
478
90
  // Print out a log message if --trace-symbol was specified.
479
90
  // This is for debugging.
480
90
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
90
483
90
  return S2;
484
90
}
lld::wasm::DefinedData* lld::wasm::replaceSymbol<lld::wasm::DefinedData, llvm::StringRef&, unsigned int&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int&&&)
Line
Count
Source
462
265
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
265
  static_assert(std::is_trivially_destructible<T>(),
464
265
                "Symbol types must be trivially destructible");
465
265
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
265
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
265
                "SymbolUnion not aligned enough");
468
265
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
265
         "Not a Symbol");
470
265
471
265
  Symbol SymCopy = *S;
472
265
473
265
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
265
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
265
  S2->ForceExport = SymCopy.ForceExport;
476
265
  S2->Traced = SymCopy.Traced;
477
265
478
265
  // Print out a log message if --trace-symbol was specified.
479
265
  // This is for debugging.
480
265
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
265
483
265
  return S2;
484
265
}
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
462
88
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
88
  static_assert(std::is_trivially_destructible<T>(),
464
88
                "Symbol types must be trivially destructible");
465
88
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
88
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
88
                "SymbolUnion not aligned enough");
468
88
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
88
         "Not a Symbol");
470
88
471
88
  Symbol SymCopy = *S;
472
88
473
88
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
88
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
88
  S2->ForceExport = SymCopy.ForceExport;
476
88
  S2->Traced = SymCopy.Traced;
477
88
478
88
  // Print out a log message if --trace-symbol was specified.
479
88
  // This is for debugging.
480
88
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
88
483
88
  return S2;
484
88
}
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
462
7
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
7
  static_assert(std::is_trivially_destructible<T>(),
464
7
                "Symbol types must be trivially destructible");
465
7
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
7
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
7
                "SymbolUnion not aligned enough");
468
7
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
7
         "Not a Symbol");
470
7
471
7
  Symbol SymCopy = *S;
472
7
473
7
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
7
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
7
  S2->ForceExport = SymCopy.ForceExport;
476
7
  S2->Traced = SymCopy.Traced;
477
7
478
7
  // Print out a log message if --trace-symbol was specified.
479
7
  // This is for debugging.
480
7
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
7
483
7
  return S2;
484
7
}
lld::wasm::UndefinedGlobal* lld::wasm::replaceSymbol<lld::wasm::UndefinedGlobal, llvm::StringRef&, llvm::StringRef&, llvm::StringRef&, unsigned int&, lld::wasm::InputFile*&, llvm::wasm::WasmGlobalType const*&>(lld::wasm::Symbol*, llvm::StringRef&&&, llvm::StringRef&&&, llvm::StringRef&&&, unsigned int&&&, lld::wasm::InputFile*&&&, llvm::wasm::WasmGlobalType const*&&&)
Line
Count
Source
462
5
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
5
  static_assert(std::is_trivially_destructible<T>(),
464
5
                "Symbol types must be trivially destructible");
465
5
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
5
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
5
                "SymbolUnion not aligned enough");
468
5
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
5
         "Not a Symbol");
470
5
471
5
  Symbol SymCopy = *S;
472
5
473
5
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
5
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
5
  S2->ForceExport = SymCopy.ForceExport;
476
5
  S2->Traced = SymCopy.Traced;
477
5
478
5
  // Print out a log message if --trace-symbol was specified.
479
5
  // This is for debugging.
480
5
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
5
483
5
  return S2;
484
5
}
lld::wasm::LazySymbol* lld::wasm::replaceSymbol<lld::wasm::LazySymbol, llvm::StringRef&, int, lld::wasm::ArchiveFile*&, llvm::object::Archive::Symbol const&>(lld::wasm::Symbol*, llvm::StringRef&&&, int&&, lld::wasm::ArchiveFile*&&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
462
23
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
23
  static_assert(std::is_trivially_destructible<T>(),
464
23
                "Symbol types must be trivially destructible");
465
23
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
23
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
23
                "SymbolUnion not aligned enough");
468
23
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
23
         "Not a Symbol");
470
23
471
23
  Symbol SymCopy = *S;
472
23
473
23
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
23
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
23
  S2->ForceExport = SymCopy.ForceExport;
476
23
  S2->Traced = SymCopy.Traced;
477
23
478
23
  // Print out a log message if --trace-symbol was specified.
479
23
  // This is for debugging.
480
23
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
23
483
23
  return S2;
484
23
}
Unexecuted instantiation: lld::wasm::LazySymbol* lld::wasm::replaceSymbol<lld::wasm::LazySymbol, llvm::StringRef&, unsigned int const&, lld::wasm::ArchiveFile*&, llvm::object::Archive::Symbol const&>(lld::wasm::Symbol*, llvm::StringRef&&&, unsigned int const&&&, lld::wasm::ArchiveFile*&&&, llvm::object::Archive::Symbol const&&&)
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
462
7
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
463
7
  static_assert(std::is_trivially_destructible<T>(),
464
7
                "Symbol types must be trivially destructible");
465
7
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
466
7
  static_assert(alignof(T) <= alignof(SymbolUnion),
467
7
                "SymbolUnion not aligned enough");
468
7
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
469
7
         "Not a Symbol");
470
7
471
7
  Symbol SymCopy = *S;
472
7
473
7
  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
474
7
  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
475
7
  S2->ForceExport = SymCopy.ForceExport;
476
7
  S2->Traced = SymCopy.Traced;
477
7
478
7
  // Print out a log message if --trace-symbol was specified.
479
7
  // This is for debugging.
480
7
  if (S2->Traced)
481
0
    printTraceSymbol(S2);
482
7
483
7
  return S2;
484
7
}
485
486
} // namespace wasm
487
488
// Returns a symbol name for an error message.
489
std::string toString(const wasm::Symbol &Sym);
490
std::string toString(wasm::Symbol::Kind Kind);
491
std::string maybeDemangleSymbol(StringRef Name);
492
493
} // namespace lld
494
495
#endif