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
31namespace llvm {
32
33class Constant;
34class Module;
35
36template <typename ValueSubClass> class SymbolTableListTraits;
37class DIGlobalVariable;
38class DIGlobalVariableExpression;
39
40class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
41  friend class SymbolTableListTraits<GlobalVariable>;
42
43  AttributeSet Attrs;
44  bool isConstantGlobal : 1;                   // Is this a global constant?
45  bool isExternallyInitializedConstant : 1;    // Is this a global whose value
46                                               // can change from its initial
47                                               // value before global
48                                               // initializers are run?
49
50public:
51  /// GlobalVariable ctor - If a parent module is specified, the global is
52  /// automatically inserted into the end of the specified modules global list.
53  GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
54                 Constant *Initializer = nullptr, const Twine &Name = "",
55                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
56                 bool isExternallyInitialized = false);
57  /// GlobalVariable ctor - This creates a global and inserts it before the
58  /// specified other global.
59  GlobalVariable(Module &M, Type *Ty, bool isConstant,
60                 LinkageTypes Linkage, Constant *Initializer,
61                 const Twine &Name = "", GlobalVariable *InsertBefore = nullptr,
62                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
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
255template <>
256struct OperandTraits<GlobalVariable> :
257  public OptionalOperandTraits<GlobalVariable> {
258};
259
260DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
261
262} // end namespace llvm
263
264#endif // LLVM_IR_GLOBALVARIABLE_H
265