LLDB mainline
Symbol.h
Go to the documentation of this file.
1//===-- Symbol.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 LLDB_SYMBOL_SYMBOL_H
10#define LLDB_SYMBOL_SYMBOL_H
11
13#include "lldb/Core/Mangled.h"
14#include "lldb/Core/Section.h"
17#include "lldb/Utility/Stream.h"
18#include "lldb/Utility/UserID.h"
20#include "lldb/lldb-private.h"
21#include "llvm/Support/JSON.h"
22
23#include <optional>
24
25namespace lldb_private {
26
27struct JSONSymbol {
28 std::optional<uint64_t> address;
29 std::optional<uint64_t> value;
30 std::optional<uint64_t> size;
31 std::optional<uint64_t> id;
32 std::optional<lldb::SymbolType> type;
33 std::string name;
34};
35
36class Symbol : public SymbolContextScope {
37public:
38 // ObjectFile readers can classify their symbol table entries and searches
39 // can be made on specific types where the symbol values will have
40 // drastically different meanings and sorting requirements.
41 Symbol();
42
43 Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type,
44 bool external, bool is_debug, bool is_trampoline, bool is_artificial,
45 const lldb::SectionSP &section_sp, lldb::addr_t value,
46 lldb::addr_t size, bool size_is_valid,
47 bool contains_linker_annotations, uint32_t flags);
48
49 Symbol(uint32_t symID, const Mangled &mangled, lldb::SymbolType type,
50 bool external, bool is_debug, bool is_trampoline, bool is_artificial,
51 const AddressRange &range, bool size_is_valid,
52 bool contains_linker_annotations, uint32_t flags);
53
54 Symbol(const Symbol &rhs);
55
56 ~Symbol() { m_addr_or_reexport.Clear(*this); }
57
58 const Symbol &operator=(const Symbol &rhs);
59
60 static llvm::Expected<Symbol> FromJSON(const JSONSymbol &symbol,
61 SectionList *section_list);
62
63 void Clear();
64
65 bool Compare(ConstString name, lldb::SymbolType type) const;
66
67 void Dump(Stream *s, Target *target, uint32_t index,
68 Mangled::NamePreference name_preference =
70
71 bool ValueIsAddress() const;
72
73 // The GetAddressRef() accessor functions should only be called if you
74 // previously call ValueIsAddress() otherwise you might get an reference to
75 // an Address object that contains an constant integer value in
76 // m_addr_range.m_base_addr.m_offset which could be incorrectly used to
77 // represent an absolute address since it has no section.
79 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
80 }
81
82 const Address &GetAddressRef() const {
83 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
84 }
85
86 // Makes sure the symbol's value is an address and returns the file address.
87 // Returns LLDB_INVALID_ADDRESS if the symbol's value isn't an address.
89
90 // Makes sure the symbol's value is an address and gets the load address
91 // using \a target if it is. Returns LLDB_INVALID_ADDRESS if the symbol's
92 // value isn't an address or if the section isn't loaded in \a target.
93 lldb::addr_t GetLoadAddress(Target *target) const;
94
95 // Access the address value. Do NOT hand out the AddressRange as an object as
96 // the byte size of the address range may not be filled in and it should be
97 // accessed via GetByteSize().
99 // Make sure the our value is an address before we hand a copy out. We use
100 // the Address inside m_addr_range to contain the value for symbols that
101 // are not address based symbols so we are using it for more than just
102 // addresses. For example undefined symbols on MacOSX have a nlist.n_value
103 // of 0 (zero) and this will get placed into
104 // m_addr_range.m_base_addr.m_offset and it will have no section. So in the
105 // GetAddress() accessor, we need to hand out an invalid address if the
106 // symbol's value isn't an address.
107 if (ValueIsAddress())
108 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
109 else
110 return Address();
111 }
112
113 /// Get the raw value of the symbol from the symbol table.
114 ///
115 /// If the symbol's value is an address, return the file address, else return
116 /// the raw value that is stored in the m_addr_range. If the base address has
117 /// no section, then getting the file address will return the correct value
118 /// as it will return the offset in the base address which is the value.
119 uint64_t GetRawValue() const {
120 return m_addr_or_reexport.GetAddressRange(*this)
121 .GetBaseAddress()
122 .GetFileAddress();
123 }
124
125 // When a symbol's value isn't an address, we need to access the raw value.
126 // This function will ensure this symbol's value isn't an address and return
127 // the integer value if this checks out, otherwise it will return
128 // "fail_value" if the symbol is an address value.
129 uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
130 if (ValueIsAddress()) {
131 // This symbol's value is an address. Use Symbol::GetAddress() to get the
132 // address.
133 return fail_value;
134 } else {
135 // The value is stored in the base address' offset
136 return m_addr_or_reexport.GetAddressRange(*this)
137 .GetBaseAddress()
138 .GetOffset();
139 }
140 }
141
144 const lldb::ModuleSP &containing_module_sp) const;
145
146 ConstString GetName() const;
147
149
151
152 uint32_t GetID() const { return m_uid; }
153
155 // TODO: See if there is a way to determine the language for a symbol
156 // somehow, for now just return our best guess
157 return GetMangled().GuessLanguage();
158 }
159
160 void SetID(uint32_t uid) { m_uid = uid; }
161
164 return m_mangled;
165 }
166
167 const Mangled &GetMangled() const {
169 return m_mangled;
170 }
171
173
175
177
179
180 /// Find the symbol this re-exported symbol resolves to.
181 ///
182 /// The library recorded on the symbol is searched first. If
183 /// \p containing_module_sp is provided, the libraries re-exported by that
184 /// module (ObjectFile::GetReExportedLibraries()) are then searched in
185 /// order. This matches the DT_FILTER / DT_AUXILIARY behavior in ELF, where
186 /// a filter library may reference multiple filtees and the dynamic linker
187 /// searches them in the order they appear in the dynamic section.
188 /// MachO provides per-symbol ReExported tag, which means every symbol knows
189 /// their final filtee and therefore no need to relies on
190 /// containing_module_sp.
192 Target &target,
193 const lldb::ModuleSP &containing_module_sp = lldb::ModuleSP()) const;
194
195 uint32_t GetSiblingIndex() const;
196
198
199 void SetType(lldb::SymbolType type) { m_type = type; }
200
201 const char *GetTypeAsString() const;
202
203 uint32_t GetFlags() const { return m_flags; }
204
205 void SetFlags(uint32_t flags) { m_flags = flags; }
206
207 void GetDescription(
208 Stream *s, lldb::DescriptionLevel level, Target *target,
209 std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
210
211 bool IsSynthetic() const { return m_is_synthetic; }
212
214
215 void SetIsSynthetic(bool b) { m_is_synthetic = b; }
216
218
220
221 bool IsDebug() const { return m_is_debug; }
222
223 void SetDebug(bool b) { m_is_debug = b; }
224
225 bool IsExternal() const { return m_is_external; }
226
227 void SetExternal(bool b) { m_is_external = b; }
228
229 bool IsTrampoline() const;
230
231 bool IsIndirect() const;
232
233 bool IsWeak() const { return m_is_weak; }
234
235 void SetIsWeak(bool b) { m_is_weak = b; }
236
237 bool GetByteSizeIsValid() const { return m_size_is_valid; }
238
240
242 m_size_is_valid = size > 0;
243 m_addr_or_reexport.GetAddressRange(*this).SetByteSize(size);
244 }
245
246 bool GetSizeIsSibling() const { return m_size_is_sibling; }
247
249
250 // If m_type is "Code" or "Function" then this will return the prologue size
251 // in bytes, else it will return zero.
252 uint32_t GetPrologueByteSize();
253
254 void SetPrologueByteSize(uint32_t prologue_byte_size) {
255 assert(m_type == lldb::eSymbolTypeCode ||
257 m_type_data = prologue_byte_size;
259 }
260
264
266
273 /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
274 ///
275 /// \see SymbolContextScope
276 void CalculateSymbolContext(SymbolContext *sc) override;
277
279
281
282 /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
283 ///
284 /// \see SymbolContextScope
285 void DumpSymbolContext(Stream *s) override;
286
288 const char *flavor,
289 bool prefer_file_cache);
290
291 bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
292 bool prefer_file_cache, Stream &strm);
293
294 bool ContainsFileAddress(lldb::addr_t file_addr) const;
295
296 static llvm::StringRef GetSyntheticSymbolPrefix() {
297 return "___lldb_unnamed_symbol_";
298 }
299
300 /// Decode a serialized version of this object from data.
301 ///
302 /// \param data
303 /// The decoder object that references the serialized data.
304 ///
305 /// \param offset_ptr
306 /// A pointer that contains the offset from which the data will be decoded
307 /// from. The offset_ptr offset value will be updated as data is read.
308 ///
309 /// \param section_list
310 /// A section list that allows lldb_private::Address objects to be filled
311 /// in. Section-relative symbol addresses are serialized as a section ID
312 /// and an offset within that section, and the section ID is looked up in
313 /// this list.
314 ///
315 /// \param strtab
316 /// All strings in cache files are put into string tables for efficiency
317 /// and cache file size reduction. Strings are stored as uint32_t string
318 /// table offsets in the cache data.
319 ///
320 /// \return
321 /// True if the symbol is successfully decoded, false otherwise, including
322 /// when a serialized section ID is not found in \a section_list.
323 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
324 const SectionList *section_list, const StringTableReader &strtab);
325
326 /// Encode this object into a data encoder object.
327 ///
328 /// This allows this object to be serialized to disk.
329 ///
330 /// \param encoder
331 /// A data encoder object that serialized bytes will be encoded into.
332 ///
333 /// \param strtab
334 /// All strings in cache files are put into string tables for efficiency
335 /// and cache file size reduction. Strings are stored as uint32_t string
336 /// table offsets in the cache data.
337 void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
338
339 bool operator==(const Symbol &rhs) const;
340
341 static const char *GetTypeAsString(lldb::SymbolType symbol_type);
342
343 static lldb::SymbolType GetTypeFromString(const char *str);
344
345protected:
346 // This is the internal guts of ResolveReExportedSymbol, it assumes
347 // reexport_name is not null, and that module_spec is valid. We track the
348 // modules we've already seen to make sure we don't get caught in a cycle.
349
351 Target &target, ConstString reexport_name,
352 lldb_private::ModuleSpec &module_spec,
353 lldb_private::ModuleList &seen_modules) const;
354
355 void SynthesizeNameIfNeeded() const;
356
357 // Initially, a ReExportInfo will only have a name: the symbol name
358 // that this Symbol will remap to, at runtime.
359 // We won't have the library that this symbol is defined in,
360 // until later, when we have other binaries loaded in the Target.
363 std::unique_ptr<FileSpec> library_up;
366 name = rhs.name;
367 if (rhs.library_up)
368 library_up = std::make_unique<FileSpec>(*rhs.library_up);
369 else
370 library_up.reset();
371 }
373 if (this != &rhs) {
374 name = rhs.name;
375 if (rhs.library_up)
376 library_up = std::make_unique<FileSpec>(*rhs.library_up);
377 else
378 library_up.reset();
379 }
380 return *this;
381 }
382 void Clear() {
383 name.Clear();
384 library_up.reset();
385 }
386 };
387
388 uint32_t m_uid = LLDB_INVALID_SYMBOL_ID; // User ID (usually the original
389 // symbol table index)
390 uint16_t m_type_data = 0; // data specific to m_type
391 uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
392 // already been calculated
393 m_is_synthetic : 1, // non-zero if this symbol is not actually in the
394 // symbol table, but synthesized from other info in
395 // the object file.
396 m_is_debug : 1, // non-zero if this symbol is debug information in a
397 // symbol
398 m_is_external : 1, // non-zero if this symbol is globally visible
399 m_size_is_sibling : 1, // m_size contains the index of this symbol's
400 // sibling
401 m_size_is_synthesized : 1, // non-zero if this symbol's size was
402 // calculated using a delta between this
403 // symbol and the next
405 m_demangled_is_synthesized : 1, // The demangled name was created should
406 // not be used for expressions or other
407 // lookups
408 m_contains_linker_annotations : 1, // The symbol name contains linker
409 // annotations, which are optional when
410 // doing name lookups
412 m_type : 6; // Values from the lldb::SymbolType enum.
413 mutable Mangled m_mangled; // uniqued symbol name/mangled name pair
414
415 // A wrapper around a `union {AddressRange, ReExportInfo}` to
416 // enforce the types being get/set match the Symbol's m_type,
417 // assert if there is a type mismatch.
420 const AddressRange &GetAddressRange(const Symbol &sym) const;
422 const ReExportInfo &GetReExportInfo(const Symbol &sym) const;
423 void SetAddressRange(Symbol &sym, const AddressRange addr_range);
424 void SetReExportInfo(Symbol &sym, const ReExportInfo reexport_info);
425
428 m_reexport_info.Clear();
429 }
430 // Proper destruction is handled by Symbol's dtor; supply a no-op
431 // impl to let the compiler know it's handled.
433
434 void Clear(const Symbol &sym) {
436 m_reexport_info.Clear();
437 else
438 m_addr_range.Clear();
439 }
440
441 private:
442 union {
443 // Contains the value, or the section offset address when the value is an
444 // address in a section, and the size (if known). For non-re-export
445 // symbols.
447
448 // Stores re-export information if this symbol is of type
449 // eSymbolTypeReExported; no address information for these symbols.
451 };
453
454 uint32_t m_flags = 0; // A copy of the flags from the original symbol table,
455 // the ObjectFile plug-in can interpret these
456};
457
458} // namespace lldb_private
459
460#if __SIZEOF_POINTER__ == 8
461static_assert(
462 sizeof(lldb_private::Symbol) == 72,
463 "Symbol is a high volume data type, size must be increased with care");
464#endif
465
466namespace llvm {
467namespace json {
468
469bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
470 llvm::json::Path path);
471
472bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
473 llvm::json::Path path);
474
475} // namespace json
476} // namespace llvm
477
478#endif // LLDB_SYMBOL_SYMBOL_H
A section + offset based address range class.
A section + offset based address class.
Definition Address.h:62
Many cache files require string tables to store data efficiently.
A uniqued constant string class.
Definition ConstString.h:40
An binary data encoding class.
Definition DataEncoder.h:42
An data extractor class.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition FileSpec.h:56
A class that handles mangled names.
Definition Mangled.h:36
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:344
A collection class for Module objects.
Definition ModuleList.h:127
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Many cache files require string tables to store data efficiently.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const SectionList *section_list, const StringTableReader &strtab)
Decode a serialized version of this object from data.
Definition Symbol.cpp:723
uint32_t GetSiblingIndex() const
Definition Symbol.cpp:242
uint16_t m_is_external
Definition Symbol.h:398
uint64_t GetIntegerValue(uint64_t fail_value=0) const
Definition Symbol.h:129
uint32_t GetID() const
Definition Symbol.h:152
lldb::addr_t GetLoadAddress(Target *target) const
Definition Symbol.cpp:608
bool ValueIsAddress() const
Definition Symbol.cpp:192
bool IsExternal() const
Definition Symbol.h:225
uint16_t m_type_data_resolved
Definition Symbol.h:391
void SetReExportedSymbolName(ConstString name)
Definition Symbol.cpp:222
void SetType(lldb::SymbolType type)
Definition Symbol.h:199
void SetSizeIsSynthesized(bool b)
Definition Symbol.h:219
void SetSizeIsSibling(bool b)
Definition Symbol.h:248
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object's symbol context into sc.
Definition Symbol.cpp:438
bool IsIndirect() const
Definition Symbol.cpp:250
bool IsDebug() const
Definition Symbol.h:221
void SynthesizeNameIfNeeded() const
Definition Symbol.cpp:701
const char * GetTypeAsString() const
Definition Symbol.cpp:434
bool IsSynthetic() const
Definition Symbol.h:211
uint16_t m_is_synthetic
Definition Symbol.h:393
uint16_t m_demangled_is_synthesized
Definition Symbol.h:405
lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache)
Definition Symbol.cpp:658
bool ContainsLinkerAnnotations() const
Definition Symbol.h:267
lldb::addr_t GetFileAddress() const
Definition Symbol.cpp:601
void DumpSymbolContext(Stream *s) override
Dump the object's symbol context to the stream s.
Definition Symbol.cpp:455
lldb::ModuleSP CalculateSymbolContextModule() override
Definition Symbol.cpp:447
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition Symbol.cpp:687
bool GetDemangledNameIsSynthesized() const
Definition Symbol.h:261
bool GetByteSizeIsValid() const
Definition Symbol.h:237
Mangled & GetMangled()
Definition Symbol.h:162
static lldb::SymbolType GetTypeFromString(const char *str)
Definition Symbol.cpp:948
uint16_t m_contains_linker_annotations
Definition Symbol.h:408
uint16_t m_size_is_valid
Definition Symbol.h:404
lldb::LanguageType GetLanguage() const
Definition Symbol.h:154
bool IsTrampoline() const
Definition Symbol.cpp:248
Address & GetAddressRef()
Definition Symbol.h:78
const Symbol & operator=(const Symbol &rhs)
Definition Symbol.cpp:98
void SetContainsLinkerAnnotations(bool b)
Definition Symbol.h:270
void SetIsWeak(bool b)
Definition Symbol.h:235
bool IsSyntheticWithAutoGeneratedName() const
Definition Symbol.cpp:692
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition Symbol.cpp:811
uint32_t GetFlags() const
Definition Symbol.h:203
bool GetSizeIsSibling() const
Definition Symbol.h:246
const Mangled & GetMangled() const
Definition Symbol.h:167
void SetPrologueByteSize(uint32_t prologue_byte_size)
Definition Symbol.h:254
ConstString GetReExportedSymbolName() const
Definition Symbol.cpp:204
bool Compare(ConstString name, lldb::SymbolType type) const
Definition Symbol.cpp:425
uint16_t m_is_debug
Definition Symbol.h:396
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition Symbol.cpp:231
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Definition Symbol.cpp:252
bool operator==(const Symbol &rhs) const
Definition Symbol.cpp:869
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition Symbol.h:296
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:470
ConstString GetName() const
Definition Symbol.cpp:615
lldb::SymbolType GetType() const
Definition Symbol.h:197
void SetFlags(uint32_t flags)
Definition Symbol.h:205
struct lldb_private::Symbol::AddrRangeOrReExport m_addr_or_reexport
Address GetAddress() const
Definition Symbol.h:98
ConstString GetNameNoArguments() const
Definition Symbol.cpp:617
uint16_t m_size_is_sibling
Definition Symbol.h:399
FileSpec GetReExportedSymbolSharedLibrary() const
Definition Symbol.cpp:211
uint16_t m_is_weak
Definition Symbol.h:411
bool IsWeak() const
Definition Symbol.h:233
void SetIsSynthetic(bool b)
Definition Symbol.h:215
bool GetSizeIsSynthesized() const
Definition Symbol.h:217
Symbol * ResolveReExportedSymbolInModuleSpec(Target &target, ConstString reexport_name, lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const
Definition Symbol.cpp:477
void SetByteSize(lldb::addr_t size)
Definition Symbol.h:241
uint32_t GetPrologueByteSize()
Definition Symbol.cpp:349
Symbol * ResolveReExportedSymbol(Target &target, const lldb::ModuleSP &containing_module_sp=lldb::ModuleSP()) const
Find the symbol this re-exported symbol resolves to.
Definition Symbol.cpp:536
uint16_t m_type_data
Definition Symbol.h:390
lldb::addr_t ResolveCallableAddress(Target &target, const lldb::ModuleSP &containing_module_sp) const
Definition Symbol.cpp:621
void SetDemangledNameIsSynthesized(bool b)
Definition Symbol.h:265
ConstString GetDisplayName() const
Definition Symbol.cpp:200
bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache, Stream &strm)
Definition Symbol.cpp:672
void SetExternal(bool b)
Definition Symbol.h:227
uint16_t m_size_is_synthesized
Definition Symbol.h:401
Symbol * CalculateSymbolContextSymbol() override
Definition Symbol.cpp:453
void SetDebug(bool b)
Definition Symbol.h:223
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:119
const Address & GetAddressRef() const
Definition Symbol.h:82
void SetID(uint32_t uid)
Definition Symbol.h:160
static llvm::Expected< Symbol > FromJSON(const JSONSymbol &symbol, SectionList *section_list)
Definition Symbol.cpp:128
void Dump(Stream *s, Target *target, uint32_t index, Mangled::NamePreference name_preference=Mangled::ePreferDemangled) const
Definition Symbol.cpp:300
#define LLDB_INVALID_SYMBOL_ID
A class that represents a running process on the host machine.
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
uint64_t offset_t
Definition lldb-types.h:86
LanguageType
Programming language type.
SymbolType
Symbol types.
@ eSymbolTypeReExported
@ eSymbolTypeResolver
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSection &section, llvm::json::Path path)
Definition Section.cpp:720
std::optional< uint64_t > address
Definition Symbol.h:28
std::optional< uint64_t > id
Definition Symbol.h:31
std::optional< lldb::SymbolType > type
Definition Symbol.h:32
std::optional< uint64_t > value
Definition Symbol.h:29
std::optional< uint64_t > size
Definition Symbol.h:30
void Clear(const Symbol &sym)
Definition Symbol.h:434
void SetReExportInfo(Symbol &sym, const ReExportInfo reexport_info)
Definition Symbol.cpp:1014
void SetAddressRange(Symbol &sym, const AddressRange addr_range)
Definition Symbol.cpp:1005
ReExportInfo & GetReExportInfo(Symbol &sym)
Definition Symbol.cpp:994
AddressRange & GetAddressRange(Symbol &sym)
Definition Symbol.cpp:982
const ReExportInfo & operator=(const ReExportInfo &rhs)
Definition Symbol.h:372
ReExportInfo(const ReExportInfo &rhs)
Definition Symbol.h:365
std::unique_ptr< FileSpec > library_up
Definition Symbol.h:363