| //===- lld/Core/Alias.h - Alias atoms -------------------------------------===// |
| // |
| // The LLVM Linker |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// \brief Provide alias atoms. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLD_CORE_ALIAS_H |
| #define LLD_CORE_ALIAS_H |
| |
| #include "lld/Core/LLVM.h" |
| #include "lld/Core/Simple.h" |
| #include "llvm/ADT/Optional.h" |
| #include <string> |
| |
| namespace lld { |
| |
| // An AliasAtom is a zero-size atom representing an alias for other atom. It has |
| // a LayoutAfter reference to the target atom, so that this atom and the target |
| // atom will be laid out at the same location in the final result. Initially |
| // the target atom is an undefined atom. Resolver will replace it with a defined |
| // one. |
| // |
| // It does not have attributes itself. Most member function calls are forwarded |
| // to the target atom. |
| class AliasAtom : public SimpleDefinedAtom { |
| public: |
| AliasAtom(const File &file, StringRef name) |
| : SimpleDefinedAtom(file), _name(name) {} |
| |
| StringRef name() const override { return _name; } |
| uint64_t size() const override { return 0; } |
| ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } |
| |
| Scope scope() const override { |
| getTarget(); |
| return _target ? _target->scope() : scopeLinkageUnit; |
| } |
| |
| Merge merge() const override { |
| if (_merge.hasValue()) |
| return _merge.getValue(); |
| getTarget(); |
| return _target ? _target->merge() : mergeNo; |
| } |
| |
| void setMerge(Merge val) { _merge = val; } |
| |
| ContentType contentType() const override { |
| getTarget(); |
| return _target ? _target->contentType() : typeUnknown; |
| } |
| |
| Interposable interposable() const override { |
| getTarget(); |
| return _target ? _target->interposable() : interposeNo; |
| } |
| |
| SectionChoice sectionChoice() const override { |
| getTarget(); |
| return _target ? _target->sectionChoice() : sectionBasedOnContent; |
| } |
| |
| StringRef customSectionName() const override { |
| getTarget(); |
| return _target ? _target->customSectionName() : StringRef(""); |
| } |
| |
| DeadStripKind deadStrip() const override { return _deadStrip; } |
| void setDeadStrip(DeadStripKind val) { _deadStrip = val; } |
| |
| private: |
| void getTarget() const { |
| if (_target) |
| return; |
| for (const Reference *r : *this) { |
| if (r->kindNamespace() == lld::Reference::KindNamespace::all && |
| r->kindValue() == lld::Reference::kindLayoutAfter) { |
| _target = dyn_cast<DefinedAtom>(r->target()); |
| return; |
| } |
| } |
| } |
| |
| std::string _name; |
| mutable const DefinedAtom *_target = nullptr; |
| llvm::Optional<Merge> _merge = DefinedAtom::mergeNo; |
| DeadStripKind _deadStrip = DefinedAtom::deadStripNormal; |
| }; |
| |
| } // end namespace lld |
| |
| #endif |