1 | //===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- 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 | // This file contains the declaration of the GlobalVariable class, which |
10 | // represents a single global variable (or constant) in the VM. |
11 | // |
12 | // Global variables are constant pointers that refer to hunks of space that are |
13 | // allocated by either the VM, or by the linker in a static compiler. A global |
14 | // variable may have an initial value, which is copied into the executables .data |
15 | // area. Global Constants are required to have initializers. |
16 | // |
17 | //===----------------------------------------------------------------------===// |
18 | |
19 | #ifndef LLVM_IR_GLOBALVARIABLE_H |
20 | #define LLVM_IR_GLOBALVARIABLE_H |
21 | |
22 | #include "llvm/ADT/Twine.h" |
23 | #include "llvm/ADT/ilist_node.h" |
24 | #include "llvm/IR/Attributes.h" |
25 | #include "llvm/IR/GlobalObject.h" |
26 | #include "llvm/IR/OperandTraits.h" |
27 | #include "llvm/IR/Value.h" |
28 | #include <cassert> |
29 | #include <cstddef> |
30 | |
31 | namespace llvm { |
32 | |
33 | class Constant; |
34 | class Module; |
35 | |
36 | template <typename ValueSubClass, typename... Args> class SymbolTableListTraits; |
37 | class DIGlobalVariableExpression; |
38 | |
39 | class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> { |
40 | friend class SymbolTableListTraits<GlobalVariable>; |
41 | |
42 | AttributeSet Attrs; |
43 | |
44 | // Is this a global constant? |
45 | bool isConstantGlobal : 1; |
46 | // Is this a global whose value can change from its initial value before |
47 | // global initializers are run? |
48 | bool isExternallyInitializedConstant : 1; |
49 | |
50 | private: |
51 | static const unsigned CodeModelBits = LastCodeModelBit - LastAlignmentBit; |
52 | static const unsigned CodeModelMask = (1 << CodeModelBits) - 1; |
53 | static const unsigned CodeModelShift = LastAlignmentBit + 1; |
54 | |
55 | public: |
56 | /// GlobalVariable ctor - If a parent module is specified, the global is |
57 | /// automatically inserted into the end of the specified modules global list. |
58 | GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, |
59 | Constant *Initializer = nullptr, const Twine &Name = "" , |
60 | ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, |
61 | bool isExternallyInitialized = false); |
62 | /// GlobalVariable ctor - This creates a global and inserts it before the |
63 | /// specified other global. |
64 | GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage, |
65 | Constant *Initializer, const Twine &Name = "" , |
66 | GlobalVariable *InsertBefore = nullptr, |
67 | ThreadLocalMode = NotThreadLocal, |
68 | std::optional<unsigned> AddressSpace = std::nullopt, |
69 | bool isExternallyInitialized = false); |
70 | GlobalVariable(const GlobalVariable &) = delete; |
71 | GlobalVariable &operator=(const GlobalVariable &) = delete; |
72 | |
73 | ~GlobalVariable() { |
74 | dropAllReferences(); |
75 | } |
76 | |
77 | // allocate space for exactly one operand |
78 | void *operator new(size_t s) { |
79 | return User::operator new(Size: s, Us: 1); |
80 | } |
81 | |
82 | // delete space for exactly one operand as created in the corresponding new operator |
83 | void operator delete(void *ptr){ |
84 | assert(ptr != nullptr && "must not be nullptr" ); |
85 | User *Obj = static_cast<User *>(ptr); |
86 | // Number of operands can be set to 0 after construction and initialization. Make sure |
87 | // that number of operands is reset to 1, as this is needed in User::operator delete |
88 | Obj->setGlobalVariableNumOperands(1); |
89 | User::operator delete(Usr: Obj); |
90 | } |
91 | |
92 | /// Provide fast operand accessors |
93 | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); |
94 | |
95 | /// Definitions have initializers, declarations don't. |
96 | /// |
97 | inline bool hasInitializer() const { return !isDeclaration(); } |
98 | |
99 | /// hasDefinitiveInitializer - Whether the global variable has an initializer, |
100 | /// and any other instances of the global (this can happen due to weak |
101 | /// linkage) are guaranteed to have the same initializer. |
102 | /// |
103 | /// Note that if you want to transform a global, you must use |
104 | /// hasUniqueInitializer() instead, because of the *_odr linkage type. |
105 | /// |
106 | /// Example: |
107 | /// |
108 | /// @a = global SomeType* null - Initializer is both definitive and unique. |
109 | /// |
110 | /// @b = global weak SomeType* null - Initializer is neither definitive nor |
111 | /// unique. |
112 | /// |
113 | /// @c = global weak_odr SomeType* null - Initializer is definitive, but not |
114 | /// unique. |
115 | inline bool hasDefinitiveInitializer() const { |
116 | return hasInitializer() && |
117 | // The initializer of a global variable may change to something arbitrary |
118 | // at link time. |
119 | !isInterposable() && |
120 | // The initializer of a global variable with the externally_initialized |
121 | // marker may change at runtime before C++ initializers are evaluated. |
122 | !isExternallyInitialized(); |
123 | } |
124 | |
125 | /// hasUniqueInitializer - Whether the global variable has an initializer, and |
126 | /// any changes made to the initializer will turn up in the final executable. |
127 | inline bool hasUniqueInitializer() const { |
128 | return |
129 | // We need to be sure this is the definition that will actually be used |
130 | isStrongDefinitionForLinker() && |
131 | // It is not safe to modify initializers of global variables with the |
132 | // external_initializer marker since the value may be changed at runtime |
133 | // before C++ initializers are evaluated. |
134 | !isExternallyInitialized(); |
135 | } |
136 | |
137 | /// getInitializer - Return the initializer for this global variable. It is |
138 | /// illegal to call this method if the global is external, because we cannot |
139 | /// tell what the value is initialized to! |
140 | /// |
141 | inline const Constant *getInitializer() const { |
142 | assert(hasInitializer() && "GV doesn't have initializer!" ); |
143 | return static_cast<Constant*>(Op<0>().get()); |
144 | } |
145 | inline Constant *getInitializer() { |
146 | assert(hasInitializer() && "GV doesn't have initializer!" ); |
147 | return static_cast<Constant*>(Op<0>().get()); |
148 | } |
149 | /// setInitializer - Sets the initializer for this global variable, removing |
150 | /// any existing initializer if InitVal==NULL. If this GV has type T*, the |
151 | /// initializer must have type T. |
152 | void setInitializer(Constant *InitVal); |
153 | |
154 | /// If the value is a global constant, its value is immutable throughout the |
155 | /// runtime execution of the program. Assigning a value into the constant |
156 | /// leads to undefined behavior. |
157 | /// |
158 | bool isConstant() const { return isConstantGlobal; } |
159 | void setConstant(bool Val) { isConstantGlobal = Val; } |
160 | |
161 | bool isExternallyInitialized() const { |
162 | return isExternallyInitializedConstant; |
163 | } |
164 | void setExternallyInitialized(bool Val) { |
165 | isExternallyInitializedConstant = Val; |
166 | } |
167 | |
168 | /// copyAttributesFrom - copy all additional attributes (those not needed to |
169 | /// create a GlobalVariable) from the GlobalVariable Src to this one. |
170 | void copyAttributesFrom(const GlobalVariable *Src); |
171 | |
172 | /// removeFromParent - This method unlinks 'this' from the containing module, |
173 | /// but does not delete it. |
174 | /// |
175 | void removeFromParent(); |
176 | |
177 | /// eraseFromParent - This method unlinks 'this' from the containing module |
178 | /// and deletes it. |
179 | /// |
180 | void eraseFromParent(); |
181 | |
182 | /// Drop all references in preparation to destroy the GlobalVariable. This |
183 | /// drops not only the reference to the initializer but also to any metadata. |
184 | void dropAllReferences(); |
185 | |
186 | /// Attach a DIGlobalVariableExpression. |
187 | void addDebugInfo(DIGlobalVariableExpression *GV); |
188 | |
189 | /// Fill the vector with all debug info attachements. |
190 | void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const; |
191 | |
192 | /// Add attribute to this global. |
193 | void addAttribute(Attribute::AttrKind Kind) { |
194 | Attrs = Attrs.addAttribute(C&: getContext(), Kind); |
195 | } |
196 | |
197 | /// Add attribute to this global. |
198 | void addAttribute(StringRef Kind, StringRef Val = StringRef()) { |
199 | Attrs = Attrs.addAttribute(C&: getContext(), Kind, Value: Val); |
200 | } |
201 | |
202 | /// Return true if the attribute exists. |
203 | bool hasAttribute(Attribute::AttrKind Kind) const { |
204 | return Attrs.hasAttribute(Kind); |
205 | } |
206 | |
207 | /// Return true if the attribute exists. |
208 | bool hasAttribute(StringRef Kind) const { |
209 | return Attrs.hasAttribute(Kind); |
210 | } |
211 | |
212 | /// Return true if any attributes exist. |
213 | bool hasAttributes() const { |
214 | return Attrs.hasAttributes(); |
215 | } |
216 | |
217 | /// Return the attribute object. |
218 | Attribute getAttribute(Attribute::AttrKind Kind) const { |
219 | return Attrs.getAttribute(Kind); |
220 | } |
221 | |
222 | /// Return the attribute object. |
223 | Attribute getAttribute(StringRef Kind) const { |
224 | return Attrs.getAttribute(Kind); |
225 | } |
226 | |
227 | /// Return the attribute set for this global |
228 | AttributeSet getAttributes() const { |
229 | return Attrs; |
230 | } |
231 | |
232 | /// Return attribute set as list with index. |
233 | /// FIXME: This may not be required once ValueEnumerators |
234 | /// in bitcode-writer can enumerate attribute-set. |
235 | AttributeList getAttributesAsList(unsigned index) const { |
236 | if (!hasAttributes()) |
237 | return AttributeList(); |
238 | std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}}; |
239 | return AttributeList::get(C&: getContext(), Attrs: AS); |
240 | } |
241 | |
242 | /// Set attribute list for this global |
243 | void setAttributes(AttributeSet A) { |
244 | Attrs = A; |
245 | } |
246 | |
247 | /// Check if section name is present |
248 | bool hasImplicitSection() const { |
249 | return getAttributes().hasAttribute(Kind: "bss-section" ) || |
250 | getAttributes().hasAttribute(Kind: "data-section" ) || |
251 | getAttributes().hasAttribute(Kind: "relro-section" ) || |
252 | getAttributes().hasAttribute(Kind: "rodata-section" ); |
253 | } |
254 | |
255 | /// Get the custom code model raw value of this global. |
256 | /// |
257 | unsigned getCodeModelRaw() const { |
258 | unsigned Data = getGlobalValueSubClassData(); |
259 | return (Data >> CodeModelShift) & CodeModelMask; |
260 | } |
261 | |
262 | /// Get the custom code model of this global if it has one. |
263 | /// |
264 | /// If this global does not have a custom code model, the empty instance |
265 | /// will be returned. |
266 | std::optional<CodeModel::Model> getCodeModel() const { |
267 | unsigned CodeModelData = getCodeModelRaw(); |
268 | if (CodeModelData > 0) |
269 | return static_cast<CodeModel::Model>(CodeModelData - 1); |
270 | return {}; |
271 | } |
272 | |
273 | /// Change the code model for this global. |
274 | /// |
275 | void setCodeModel(CodeModel::Model CM); |
276 | |
277 | // Methods for support type inquiry through isa, cast, and dyn_cast: |
278 | static bool classof(const Value *V) { |
279 | return V->getValueID() == Value::GlobalVariableVal; |
280 | } |
281 | }; |
282 | |
283 | template <> |
284 | struct OperandTraits<GlobalVariable> : |
285 | public OptionalOperandTraits<GlobalVariable> { |
286 | }; |
287 | |
288 | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value) |
289 | |
290 | } // end namespace llvm |
291 | |
292 | #endif // LLVM_IR_GLOBALVARIABLE_H |
293 | |