]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lld/include/lld/Core/Atom.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lld / include / lld / Core / Atom.h
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   Definition definition() const { return _definition; }
61
62   static bool classof(const Atom *a) { return true; }
63
64 protected:
65   /// Atom is an abstract base class.  Only subclasses can access constructor.
66   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   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   OwningAtomPtr() = default;
88   OwningAtomPtr(T *atom) : atom(atom) { }
89
90   ~OwningAtomPtr() {
91     if (atom)
92       runDestructor(atom);
93   }
94
95   void runDestructor(Atom *atom) {
96     atom->~Atom();
97   }
98
99   OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) {
100     ptr.atom = nullptr;
101   }
102
103   void operator=(OwningAtomPtr&& ptr) {
104     if (atom)
105       runDestructor(atom);
106     atom = ptr.atom;
107     ptr.atom = nullptr;
108   }
109
110   T *const &get() const {
111     return atom;
112   }
113
114   T *&get() {
115     return atom;
116   }
117
118   T *release() {
119     auto *v = atom;
120     atom = nullptr;
121     return v;
122   }
123
124 private:
125   T *atom = nullptr;
126 };
127
128 } // end namespace lld
129
130 #endif // LLD_CORE_ATOM_H