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