/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/include/lld/Core/Atom.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Core/Atom.h - A node in linking graph --------------------*- 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_CORE_ATOM_H |
10 | | #define LLD_CORE_ATOM_H |
11 | | |
12 | | #include "lld/Common/LLVM.h" |
13 | | #include "llvm/ADT/StringRef.h" |
14 | | |
15 | | namespace lld { |
16 | | |
17 | | class File; |
18 | | |
19 | | template<typename T> |
20 | | class OwningAtomPtr; |
21 | | |
22 | | /// |
23 | | /// The linker has a Graph Theory model of linking. An object file is seen |
24 | | /// as a set of Atoms with References to other Atoms. Each Atom is a node |
25 | | /// and each Reference is an edge. An Atom can be a DefinedAtom which has |
26 | | /// content or a UndefinedAtom which is a placeholder and represents an |
27 | | /// undefined symbol (extern declaration). |
28 | | /// |
29 | | class Atom { |
30 | | template<typename T> friend class OwningAtomPtr; |
31 | | |
32 | | public: |
33 | | /// Whether this atom is defined or a proxy for an undefined symbol |
34 | | enum Definition { |
35 | | definitionRegular, ///< Normal C/C++ function or global variable. |
36 | | definitionAbsolute, ///< Asm-only (foo = 10). Not tied to any content. |
37 | | definitionUndefined, ///< Only in .o files to model reference to undef. |
38 | | definitionSharedLibrary ///< Only in shared libraries to model export. |
39 | | }; |
40 | | |
41 | | /// The scope in which this atom is acessible to other atoms. |
42 | | enum Scope { |
43 | | scopeTranslationUnit, ///< Accessible only to atoms in the same translation |
44 | | /// unit (e.g. a C static). |
45 | | scopeLinkageUnit, ///< Accessible to atoms being linked but not visible |
46 | | /// to runtime loader (e.g. visibility=hidden). |
47 | | scopeGlobal ///< Accessible to all atoms and visible to runtime |
48 | | /// loader (e.g. visibility=default). |
49 | | }; |
50 | | |
51 | | /// file - returns the File that produced/owns this Atom |
52 | | virtual const File& file() const = 0; |
53 | | |
54 | | /// name - The name of the atom. For a function atom, it is the (mangled) |
55 | | /// name of the function. |
56 | | virtual StringRef name() const = 0; |
57 | | |
58 | | /// definition - Whether this atom is a definition or represents an undefined |
59 | | /// symbol. |
60 | 6.54k | Definition definition() const { return _definition; } |
61 | | |
62 | 0 | static bool classof(const Atom *a) { return true; } |
63 | | |
64 | | protected: |
65 | | /// Atom is an abstract base class. Only subclasses can access constructor. |
66 | 1.72k | explicit Atom(Definition def) : _definition(def) {} |
67 | | |
68 | | /// The memory for Atom objects is always managed by the owning File |
69 | | /// object. Therefore, no one but the owning File object should call |
70 | | /// delete on an Atom. In fact, some File objects may bulk allocate |
71 | | /// an array of Atoms, so they cannot be individually deleted by anyone. |
72 | 1.87k | virtual ~Atom() = default; |
73 | | |
74 | | private: |
75 | | Definition _definition; |
76 | | }; |
77 | | |
78 | | /// Class which owns an atom pointer and runs the atom destructor when the |
79 | | /// owning pointer goes out of scope. |
80 | | template<typename T> |
81 | | class OwningAtomPtr { |
82 | | private: |
83 | | OwningAtomPtr(const OwningAtomPtr &) = delete; |
84 | | void operator=(const OwningAtomPtr &) = delete; |
85 | | |
86 | | public: |
87 | 73 | OwningAtomPtr() = default; lld::OwningAtomPtr<lld::DefinedAtom>::OwningAtomPtr() Line | Count | Source | 87 | 60 | OwningAtomPtr() = default; |
lld::OwningAtomPtr<lld::UndefinedAtom>::OwningAtomPtr() Line | Count | Source | 87 | 7 | OwningAtomPtr() = default; |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::OwningAtomPtr() Line | Count | Source | 87 | 6 | OwningAtomPtr() = default; |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::OwningAtomPtr() |
88 | 3.50k | OwningAtomPtr(T *atom) : atom(atom) { } lld::OwningAtomPtr<lld::DefinedAtom>::OwningAtomPtr(lld::DefinedAtom*) Line | Count | Source | 88 | 1.58k | OwningAtomPtr(T *atom) : atom(atom) { } |
lld::OwningAtomPtr<lld::UndefinedAtom>::OwningAtomPtr(lld::UndefinedAtom*) Line | Count | Source | 88 | 376 | OwningAtomPtr(T *atom) : atom(atom) { } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::OwningAtomPtr(lld::SharedLibraryAtom*) Line | Count | Source | 88 | 304 | OwningAtomPtr(T *atom) : atom(atom) { } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::OwningAtomPtr(lld::AbsoluteAtom*) lld::OwningAtomPtr<lld::Atom>::OwningAtomPtr(lld::Atom*) Line | Count | Source | 88 | 1.23k | OwningAtomPtr(T *atom) : atom(atom) { } |
|
89 | | |
90 | 14.0k | ~OwningAtomPtr() { |
91 | 14.0k | if (atom) |
92 | 1.14k | runDestructor(atom); |
93 | 14.0k | } lld::OwningAtomPtr<lld::DefinedAtom>::~OwningAtomPtr() Line | Count | Source | 90 | 8.20k | ~OwningAtomPtr() { | 91 | 8.20k | if (atom) | 92 | 859 | runDestructor(atom); | 93 | 8.20k | } |
lld::OwningAtomPtr<lld::UndefinedAtom>::~OwningAtomPtr() Line | Count | Source | 90 | 1.18k | ~OwningAtomPtr() { | 91 | 1.18k | if (atom) | 92 | 45 | runDestructor(atom); | 93 | 1.18k | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::~OwningAtomPtr() Line | Count | Source | 90 | 649 | ~OwningAtomPtr() { | 91 | 649 | if (atom) | 92 | 139 | runDestructor(atom); | 93 | 649 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::~OwningAtomPtr() lld::OwningAtomPtr<lld::Atom>::~OwningAtomPtr() Line | Count | Source | 90 | 3.95k | ~OwningAtomPtr() { | 91 | 3.95k | if (atom) | 92 | 99 | runDestructor(atom); | 93 | 3.95k | } |
|
94 | | |
95 | 1.39k | void runDestructor(Atom *atom) { |
96 | 1.39k | atom->~Atom(); |
97 | 1.39k | } lld::OwningAtomPtr<lld::DefinedAtom>::runDestructor(lld::Atom*) Line | Count | Source | 95 | 891 | void runDestructor(Atom *atom) { | 96 | 891 | atom->~Atom(); | 97 | 891 | } |
lld::OwningAtomPtr<lld::UndefinedAtom>::runDestructor(lld::Atom*) Line | Count | Source | 95 | 45 | void runDestructor(Atom *atom) { | 96 | 45 | atom->~Atom(); | 97 | 45 | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::runDestructor(lld::Atom*) Line | Count | Source | 95 | 139 | void runDestructor(Atom *atom) { | 96 | 139 | atom->~Atom(); | 97 | 139 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::runDestructor(lld::Atom*) lld::OwningAtomPtr<lld::Atom>::runDestructor(lld::Atom*) Line | Count | Source | 95 | 324 | void runDestructor(Atom *atom) { | 96 | 324 | atom->~Atom(); | 97 | 324 | } |
|
98 | | |
99 | 10.4k | OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) { |
100 | 10.4k | ptr.atom = nullptr; |
101 | 10.4k | } lld::OwningAtomPtr<lld::DefinedAtom>::OwningAtomPtr(lld::OwningAtomPtr<lld::DefinedAtom>&&) Line | Count | Source | 99 | 6.56k | OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) { | 100 | 6.56k | ptr.atom = nullptr; | 101 | 6.56k | } |
lld::OwningAtomPtr<lld::UndefinedAtom>::OwningAtomPtr(lld::OwningAtomPtr<lld::UndefinedAtom>&&) Line | Count | Source | 99 | 805 | OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) { | 100 | 805 | ptr.atom = nullptr; | 101 | 805 | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::OwningAtomPtr(lld::OwningAtomPtr<lld::SharedLibraryAtom>&&) Line | Count | Source | 99 | 339 | OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) { | 100 | 339 | ptr.atom = nullptr; | 101 | 339 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::OwningAtomPtr(lld::OwningAtomPtr<lld::AbsoluteAtom>&&) lld::OwningAtomPtr<lld::Atom>::OwningAtomPtr(lld::OwningAtomPtr<lld::Atom>&&) Line | Count | Source | 99 | 2.72k | OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) { | 100 | 2.72k | ptr.atom = nullptr; | 101 | 2.72k | } |
|
102 | | |
103 | 2.52k | void operator=(OwningAtomPtr&& ptr) { |
104 | 2.52k | if (atom) |
105 | 257 | runDestructor(atom); |
106 | 2.52k | atom = ptr.atom; |
107 | 2.52k | ptr.atom = nullptr; |
108 | 2.52k | } lld::OwningAtomPtr<lld::DefinedAtom>::operator=(lld::OwningAtomPtr<lld::DefinedAtom>&&) Line | Count | Source | 103 | 1.92k | void operator=(OwningAtomPtr&& ptr) { | 104 | 1.92k | if (atom) | 105 | 32 | runDestructor(atom); | 106 | 1.92k | atom = ptr.atom; | 107 | 1.92k | ptr.atom = nullptr; | 108 | 1.92k | } |
lld::OwningAtomPtr<lld::Atom>::operator=(lld::OwningAtomPtr<lld::Atom>&&) Line | Count | Source | 103 | 601 | void operator=(OwningAtomPtr&& ptr) { | 104 | 601 | if (atom) | 105 | 225 | runDestructor(atom); | 106 | 601 | atom = ptr.atom; | 107 | 601 | ptr.atom = nullptr; | 108 | 601 | } |
|
109 | | |
110 | 10.0k | T *const &get() const { |
111 | 10.0k | return atom; |
112 | 10.0k | } lld::OwningAtomPtr<lld::DefinedAtom>::get() const Line | Count | Source | 110 | 8.37k | T *const &get() const { | 111 | 8.37k | return atom; | 112 | 8.37k | } |
lld::OwningAtomPtr<lld::UndefinedAtom>::get() const Line | Count | Source | 110 | 93 | T *const &get() const { | 111 | 93 | return atom; | 112 | 93 | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::get() const Line | Count | Source | 110 | 205 | T *const &get() const { | 111 | 205 | return atom; | 112 | 205 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::get() const lld::OwningAtomPtr<lld::Atom>::get() const Line | Count | Source | 110 | 1.36k | T *const &get() const { | 111 | 1.36k | return atom; | 112 | 1.36k | } |
|
113 | | |
114 | 6.70k | T *&get() { |
115 | 6.70k | return atom; |
116 | 6.70k | } lld::OwningAtomPtr<lld::DefinedAtom>::get() Line | Count | Source | 114 | 3.57k | T *&get() { | 115 | 3.57k | return atom; | 116 | 3.57k | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::get() Line | Count | Source | 114 | 326 | T *&get() { | 115 | 326 | return atom; | 116 | 326 | } |
lld::OwningAtomPtr<lld::UndefinedAtom>::get() Line | Count | Source | 114 | 659 | T *&get() { | 115 | 659 | return atom; | 116 | 659 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::get() lld::OwningAtomPtr<lld::Atom>::get() Line | Count | Source | 114 | 2.14k | T *&get() { | 115 | 2.14k | return atom; | 116 | 2.14k | } |
|
117 | | |
118 | 2.15k | T *release() { |
119 | 2.15k | auto *v = atom; |
120 | 2.15k | atom = nullptr; |
121 | 2.15k | return v; |
122 | 2.15k | } lld::OwningAtomPtr<lld::UndefinedAtom>::release() Line | Count | Source | 118 | 338 | T *release() { | 119 | 338 | auto *v = atom; | 120 | 338 | atom = nullptr; | 121 | 338 | return v; | 122 | 338 | } |
lld::OwningAtomPtr<lld::DefinedAtom>::release() Line | Count | Source | 118 | 756 | T *release() { | 119 | 756 | auto *v = atom; | 120 | 756 | atom = nullptr; | 121 | 756 | return v; | 122 | 756 | } |
lld::OwningAtomPtr<lld::SharedLibraryAtom>::release() Line | Count | Source | 118 | 143 | T *release() { | 119 | 143 | auto *v = atom; | 120 | 143 | atom = nullptr; | 121 | 143 | return v; | 122 | 143 | } |
Unexecuted instantiation: lld::OwningAtomPtr<lld::AbsoluteAtom>::release() lld::OwningAtomPtr<lld::Atom>::release() Line | Count | Source | 118 | 913 | T *release() { | 119 | 913 | auto *v = atom; | 120 | 913 | atom = nullptr; | 121 | 913 | return v; | 122 | 913 | } |
|
123 | | |
124 | | private: |
125 | | T *atom = nullptr; |
126 | | }; |
127 | | |
128 | | } // end namespace lld |
129 | | |
130 | | #endif // LLD_CORE_ATOM_H |