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