1249259Sdim//===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===//
2249259Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6249259Sdim//
7249259Sdim//===----------------------------------------------------------------------===//
8249259Sdim//
9249259Sdim// This file contains the declaration of the GlobalVariable class, which
10249259Sdim// represents a single global variable (or constant) in the VM.
11249259Sdim//
12249259Sdim// Global variables are constant pointers that refer to hunks of space that are
13249259Sdim// allocated by either the VM, or by the linker in a static compiler.  A global
14249259Sdim// variable may have an initial value, which is copied into the executables .data
15249259Sdim// area.  Global Constants are required to have initializers.
16249259Sdim//
17249259Sdim//===----------------------------------------------------------------------===//
18249259Sdim
19249259Sdim#ifndef LLVM_IR_GLOBALVARIABLE_H
20249259Sdim#define LLVM_IR_GLOBALVARIABLE_H
21249259Sdim
22314564Sdim#include "llvm/ADT/PointerUnion.h"
23249259Sdim#include "llvm/ADT/Twine.h"
24249259Sdim#include "llvm/ADT/ilist_node.h"
25321369Sdim#include "llvm/IR/Attributes.h"
26276479Sdim#include "llvm/IR/GlobalObject.h"
27249259Sdim#include "llvm/IR/OperandTraits.h"
28314564Sdim#include "llvm/IR/Value.h"
29314564Sdim#include <cassert>
30314564Sdim#include <cstddef>
31249259Sdim
32249259Sdimnamespace llvm {
33249259Sdim
34314564Sdimclass Constant;
35249259Sdimclass Module;
36314564Sdim
37296417Sdimtemplate <typename ValueSubClass> class SymbolTableListTraits;
38314564Sdimclass DIGlobalVariable;
39314564Sdimclass DIGlobalVariableExpression;
40249259Sdim
41276479Sdimclass GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
42296417Sdim  friend class SymbolTableListTraits<GlobalVariable>;
43249259Sdim
44321369Sdim  AttributeSet Attrs;
45249259Sdim  bool isConstantGlobal : 1;                   // Is this a global constant?
46249259Sdim  bool isExternallyInitializedConstant : 1;    // Is this a global whose value
47249259Sdim                                               // can change from its initial
48249259Sdim                                               // value before global
49249259Sdim                                               // initializers are run?
50314564Sdim
51249259Sdimpublic:
52249259Sdim  /// GlobalVariable ctor - If a parent module is specified, the global is
53249259Sdim  /// automatically inserted into the end of the specified modules global list.
54249259Sdim  GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
55276479Sdim                 Constant *Initializer = nullptr, const Twine &Name = "",
56249259Sdim                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
57249259Sdim                 bool isExternallyInitialized = false);
58249259Sdim  /// GlobalVariable ctor - This creates a global and inserts it before the
59249259Sdim  /// specified other global.
60249259Sdim  GlobalVariable(Module &M, Type *Ty, bool isConstant,
61249259Sdim                 LinkageTypes Linkage, Constant *Initializer,
62276479Sdim                 const Twine &Name = "", GlobalVariable *InsertBefore = nullptr,
63249259Sdim                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
64249259Sdim                 bool isExternallyInitialized = false);
65314564Sdim  GlobalVariable(const GlobalVariable &) = delete;
66314564Sdim  GlobalVariable &operator=(const GlobalVariable &) = delete;
67249259Sdim
68321369Sdim  ~GlobalVariable() {
69309124Sdim    dropAllReferences();
70249259Sdim  }
71249259Sdim
72314564Sdim  // allocate space for exactly one operand
73314564Sdim  void *operator new(size_t s) {
74314564Sdim    return User::operator new(s, 1);
75314564Sdim  }
76314564Sdim
77341825Sdim  // delete space for exactly one operand as created in the corresponding new operator
78341825Sdim  void operator delete(void *ptr){
79341825Sdim    assert(ptr != nullptr && "must not be nullptr");
80341825Sdim    User *Obj = static_cast<User *>(ptr);
81341825Sdim    // Number of operands can be set to 0 after construction and initialization. Make sure
82341825Sdim    // that number of operands is reset to 1, as this is needed in User::operator delete
83341825Sdim    Obj->setGlobalVariableNumOperands(1);
84341825Sdim    User::operator delete(Obj);
85341825Sdim  }
86341825Sdim
87249259Sdim  /// Provide fast operand accessors
88249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
89249259Sdim
90261991Sdim  /// Definitions have initializers, declarations don't.
91249259Sdim  ///
92249259Sdim  inline bool hasInitializer() const { return !isDeclaration(); }
93249259Sdim
94249259Sdim  /// hasDefinitiveInitializer - Whether the global variable has an initializer,
95249259Sdim  /// and any other instances of the global (this can happen due to weak
96249259Sdim  /// linkage) are guaranteed to have the same initializer.
97249259Sdim  ///
98249259Sdim  /// Note that if you want to transform a global, you must use
99249259Sdim  /// hasUniqueInitializer() instead, because of the *_odr linkage type.
100249259Sdim  ///
101249259Sdim  /// Example:
102249259Sdim  ///
103249259Sdim  /// @a = global SomeType* null - Initializer is both definitive and unique.
104249259Sdim  ///
105249259Sdim  /// @b = global weak SomeType* null - Initializer is neither definitive nor
106249259Sdim  /// unique.
107249259Sdim  ///
108249259Sdim  /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
109249259Sdim  /// unique.
110249259Sdim  inline bool hasDefinitiveInitializer() const {
111249259Sdim    return hasInitializer() &&
112309124Sdim      // The initializer of a global variable may change to something arbitrary
113309124Sdim      // at link time.
114309124Sdim      !isInterposable() &&
115249259Sdim      // The initializer of a global variable with the externally_initialized
116249259Sdim      // marker may change at runtime before C++ initializers are evaluated.
117249259Sdim      !isExternallyInitialized();
118249259Sdim  }
119249259Sdim
120249259Sdim  /// hasUniqueInitializer - Whether the global variable has an initializer, and
121249259Sdim  /// any changes made to the initializer will turn up in the final executable.
122249259Sdim  inline bool hasUniqueInitializer() const {
123296417Sdim    return
124296417Sdim        // We need to be sure this is the definition that will actually be used
125296417Sdim        isStrongDefinitionForLinker() &&
126296417Sdim        // It is not safe to modify initializers of global variables with the
127296417Sdim        // external_initializer marker since the value may be changed at runtime
128296417Sdim        // before C++ initializers are evaluated.
129296417Sdim        !isExternallyInitialized();
130249259Sdim  }
131249259Sdim
132249259Sdim  /// getInitializer - Return the initializer for this global variable.  It is
133249259Sdim  /// illegal to call this method if the global is external, because we cannot
134249259Sdim  /// tell what the value is initialized to!
135249259Sdim  ///
136249259Sdim  inline const Constant *getInitializer() const {
137249259Sdim    assert(hasInitializer() && "GV doesn't have initializer!");
138249259Sdim    return static_cast<Constant*>(Op<0>().get());
139249259Sdim  }
140249259Sdim  inline Constant *getInitializer() {
141249259Sdim    assert(hasInitializer() && "GV doesn't have initializer!");
142249259Sdim    return static_cast<Constant*>(Op<0>().get());
143249259Sdim  }
144249259Sdim  /// setInitializer - Sets the initializer for this global variable, removing
145249259Sdim  /// any existing initializer if InitVal==NULL.  If this GV has type T*, the
146249259Sdim  /// initializer must have type T.
147249259Sdim  void setInitializer(Constant *InitVal);
148249259Sdim
149249259Sdim  /// If the value is a global constant, its value is immutable throughout the
150249259Sdim  /// runtime execution of the program.  Assigning a value into the constant
151249259Sdim  /// leads to undefined behavior.
152249259Sdim  ///
153249259Sdim  bool isConstant() const { return isConstantGlobal; }
154249259Sdim  void setConstant(bool Val) { isConstantGlobal = Val; }
155249259Sdim
156249259Sdim  bool isExternallyInitialized() const {
157249259Sdim    return isExternallyInitializedConstant;
158249259Sdim  }
159249259Sdim  void setExternallyInitialized(bool Val) {
160249259Sdim    isExternallyInitializedConstant = Val;
161249259Sdim  }
162249259Sdim
163249259Sdim  /// copyAttributesFrom - copy all additional attributes (those not needed to
164249259Sdim  /// create a GlobalVariable) from the GlobalVariable Src to this one.
165321369Sdim  void copyAttributesFrom(const GlobalVariable *Src);
166249259Sdim
167249259Sdim  /// removeFromParent - This method unlinks 'this' from the containing module,
168249259Sdim  /// but does not delete it.
169249259Sdim  ///
170321369Sdim  void removeFromParent();
171249259Sdim
172249259Sdim  /// eraseFromParent - This method unlinks 'this' from the containing module
173249259Sdim  /// and deletes it.
174249259Sdim  ///
175321369Sdim  void eraseFromParent();
176249259Sdim
177309124Sdim  /// Drop all references in preparation to destroy the GlobalVariable. This
178309124Sdim  /// drops not only the reference to the initializer but also to any metadata.
179309124Sdim  void dropAllReferences();
180309124Sdim
181314564Sdim  /// Attach a DIGlobalVariableExpression.
182314564Sdim  void addDebugInfo(DIGlobalVariableExpression *GV);
183314564Sdim
184314564Sdim  /// Fill the vector with all debug info attachements.
185314564Sdim  void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const;
186314564Sdim
187321369Sdim  /// Add attribute to this global.
188321369Sdim  void addAttribute(Attribute::AttrKind Kind) {
189321369Sdim    Attrs = Attrs.addAttribute(getContext(), Kind);
190321369Sdim  }
191321369Sdim
192321369Sdim  /// Add attribute to this global.
193321369Sdim  void addAttribute(StringRef Kind, StringRef Val = StringRef()) {
194321369Sdim    Attrs = Attrs.addAttribute(getContext(), Kind, Val);
195321369Sdim  }
196321369Sdim
197321369Sdim  /// Return true if the attribute exists.
198321369Sdim  bool hasAttribute(Attribute::AttrKind Kind) const {
199321369Sdim    return Attrs.hasAttribute(Kind);
200321369Sdim  }
201321369Sdim
202321369Sdim  /// Return true if the attribute exists.
203321369Sdim  bool hasAttribute(StringRef Kind) const {
204321369Sdim    return Attrs.hasAttribute(Kind);
205321369Sdim  }
206321369Sdim
207321369Sdim  /// Return true if any attributes exist.
208321369Sdim  bool hasAttributes() const {
209321369Sdim    return Attrs.hasAttributes();
210321369Sdim  }
211321369Sdim
212321369Sdim  /// Return the attribute object.
213321369Sdim  Attribute getAttribute(Attribute::AttrKind Kind) const {
214321369Sdim    return Attrs.getAttribute(Kind);
215321369Sdim  }
216321369Sdim
217321369Sdim  /// Return the attribute object.
218321369Sdim  Attribute getAttribute(StringRef Kind) const {
219321369Sdim    return Attrs.getAttribute(Kind);
220321369Sdim  }
221321369Sdim
222321369Sdim  /// Return the attribute set for this global
223321369Sdim  AttributeSet getAttributes() const {
224321369Sdim    return Attrs;
225321369Sdim  }
226321369Sdim
227321369Sdim  /// Return attribute set as list with index.
228321369Sdim  /// FIXME: This may not be required once ValueEnumerators
229321369Sdim  /// in bitcode-writer can enumerate attribute-set.
230321369Sdim  AttributeList getAttributesAsList(unsigned index) const {
231321369Sdim    if (!hasAttributes())
232321369Sdim      return AttributeList();
233321369Sdim    std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}};
234321369Sdim    return AttributeList::get(getContext(), AS);
235321369Sdim  }
236321369Sdim
237321369Sdim  /// Set attribute list for this global
238321369Sdim  void setAttributes(AttributeSet A) {
239321369Sdim    Attrs = A;
240321369Sdim  }
241321369Sdim
242321369Sdim  /// Check if section name is present
243321369Sdim  bool hasImplicitSection() const {
244321369Sdim    return getAttributes().hasAttribute("bss-section") ||
245321369Sdim           getAttributes().hasAttribute("data-section") ||
246360784Sdim           getAttributes().hasAttribute("relro-section") ||
247321369Sdim           getAttributes().hasAttribute("rodata-section");
248321369Sdim  }
249321369Sdim
250249259Sdim  // Methods for support type inquiry through isa, cast, and dyn_cast:
251321369Sdim  static bool classof(const Value *V) {
252249259Sdim    return V->getValueID() == Value::GlobalVariableVal;
253249259Sdim  }
254249259Sdim};
255249259Sdim
256249259Sdimtemplate <>
257249259Sdimstruct OperandTraits<GlobalVariable> :
258249259Sdim  public OptionalOperandTraits<GlobalVariable> {
259249259Sdim};
260249259Sdim
261249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
262249259Sdim
263314564Sdim} // end namespace llvm
264249259Sdim
265314564Sdim#endif // LLVM_IR_GLOBALVARIABLE_H
266