Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:01

0001 //===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains the declaration of the GlobalVariable class, which
0010 // represents a single global variable (or constant) in the VM.
0011 //
0012 // Global variables are constant pointers that refer to hunks of space that are
0013 // allocated by either the VM, or by the linker in a static compiler.  A global
0014 // variable may have an initial value, which is copied into the executables .data
0015 // area.  Global Constants are required to have initializers.
0016 //
0017 //===----------------------------------------------------------------------===//
0018 
0019 #ifndef LLVM_IR_GLOBALVARIABLE_H
0020 #define LLVM_IR_GLOBALVARIABLE_H
0021 
0022 #include "llvm/ADT/Twine.h"
0023 #include "llvm/ADT/ilist_node.h"
0024 #include "llvm/IR/Attributes.h"
0025 #include "llvm/IR/GlobalObject.h"
0026 #include "llvm/IR/OperandTraits.h"
0027 #include "llvm/IR/Value.h"
0028 #include <cassert>
0029 #include <cstddef>
0030 
0031 namespace llvm {
0032 
0033 class Constant;
0034 class Module;
0035 
0036 template <typename ValueSubClass, typename... Args> class SymbolTableListTraits;
0037 class DIGlobalVariableExpression;
0038 
0039 class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
0040   friend class SymbolTableListTraits<GlobalVariable>;
0041 
0042   constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
0043 
0044   AttributeSet Attrs;
0045 
0046   // Is this a global constant?
0047   bool isConstantGlobal : 1;
0048   // Is this a global whose value can change from its initial value before
0049   // global initializers are run?
0050   bool isExternallyInitializedConstant : 1;
0051 
0052 private:
0053   static const unsigned CodeModelBits = LastCodeModelBit - LastAlignmentBit;
0054   static const unsigned CodeModelMask = (1 << CodeModelBits) - 1;
0055   static const unsigned CodeModelShift = LastAlignmentBit + 1;
0056 
0057 public:
0058   /// GlobalVariable ctor - If a parent module is specified, the global is
0059   /// automatically inserted into the end of the specified modules global list.
0060   GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
0061                  Constant *Initializer = nullptr, const Twine &Name = "",
0062                  ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
0063                  bool isExternallyInitialized = false);
0064   /// GlobalVariable ctor - This creates a global and inserts it before the
0065   /// specified other global.
0066   GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage,
0067                  Constant *Initializer, const Twine &Name = "",
0068                  GlobalVariable *InsertBefore = nullptr,
0069                  ThreadLocalMode = NotThreadLocal,
0070                  std::optional<unsigned> AddressSpace = std::nullopt,
0071                  bool isExternallyInitialized = false);
0072   GlobalVariable(const GlobalVariable &) = delete;
0073   GlobalVariable &operator=(const GlobalVariable &) = delete;
0074 
0075 private:
0076   /// Set the number of operands on a GlobalVariable.
0077   ///
0078   /// GlobalVariable always allocates space for a single operands, but
0079   /// doesn't always use it.
0080   void setGlobalVariableNumOperands(unsigned NumOps) {
0081     assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands");
0082     NumUserOperands = NumOps;
0083   }
0084 
0085 public:
0086   ~GlobalVariable() {
0087     dropAllReferences();
0088 
0089     // Number of operands can be set to 0 after construction and initialization.
0090     // Make sure that number of operands is reset to 1, as this is needed in
0091     // User::operator delete
0092     setGlobalVariableNumOperands(1);
0093   }
0094 
0095   // allocate space for exactly one operand
0096   void *operator new(size_t s) { return User::operator new(s, AllocMarker); }
0097 
0098   // delete space for exactly one operand as created in the corresponding new operator
0099   void operator delete(void *ptr) { User::operator delete(ptr); }
0100 
0101   /// Provide fast operand accessors
0102   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0103 
0104   /// Definitions have initializers, declarations don't.
0105   ///
0106   inline bool hasInitializer() const { return !isDeclaration(); }
0107 
0108   /// hasDefinitiveInitializer - Whether the global variable has an initializer,
0109   /// and any other instances of the global (this can happen due to weak
0110   /// linkage) are guaranteed to have the same initializer.
0111   ///
0112   /// Note that if you want to transform a global, you must use
0113   /// hasUniqueInitializer() instead, because of the *_odr linkage type.
0114   ///
0115   /// Example:
0116   ///
0117   /// @a = global SomeType* null - Initializer is both definitive and unique.
0118   ///
0119   /// @b = global weak SomeType* null - Initializer is neither definitive nor
0120   /// unique.
0121   ///
0122   /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
0123   /// unique.
0124   inline bool hasDefinitiveInitializer() const {
0125     return hasInitializer() &&
0126       // The initializer of a global variable may change to something arbitrary
0127       // at link time.
0128       !isInterposable() &&
0129       // The initializer of a global variable with the externally_initialized
0130       // marker may change at runtime before C++ initializers are evaluated.
0131       !isExternallyInitialized();
0132   }
0133 
0134   /// hasUniqueInitializer - Whether the global variable has an initializer, and
0135   /// any changes made to the initializer will turn up in the final executable.
0136   inline bool hasUniqueInitializer() const {
0137     return
0138         // We need to be sure this is the definition that will actually be used
0139         isStrongDefinitionForLinker() &&
0140         // It is not safe to modify initializers of global variables with the
0141         // external_initializer marker since the value may be changed at runtime
0142         // before C++ initializers are evaluated.
0143         !isExternallyInitialized();
0144   }
0145 
0146   /// getInitializer - Return the initializer for this global variable.  It is
0147   /// illegal to call this method if the global is external, because we cannot
0148   /// tell what the value is initialized to!
0149   ///
0150   inline const Constant *getInitializer() const {
0151     assert(hasInitializer() && "GV doesn't have initializer!");
0152     return static_cast<Constant*>(Op<0>().get());
0153   }
0154   inline Constant *getInitializer() {
0155     assert(hasInitializer() && "GV doesn't have initializer!");
0156     return static_cast<Constant*>(Op<0>().get());
0157   }
0158   /// setInitializer - Sets the initializer for this global variable, removing
0159   /// any existing initializer if InitVal==NULL. The initializer must have the
0160   /// type getValueType().
0161   void setInitializer(Constant *InitVal);
0162 
0163   /// replaceInitializer - Sets the initializer for this global variable, and
0164   /// sets the value type of the global to the type of the initializer. The
0165   /// initializer must not be null.  This may affect the global's alignment if
0166   /// it isn't explicitly set.
0167   void replaceInitializer(Constant *InitVal);
0168 
0169   /// If the value is a global constant, its value is immutable throughout the
0170   /// runtime execution of the program.  Assigning a value into the constant
0171   /// leads to undefined behavior.
0172   ///
0173   bool isConstant() const { return isConstantGlobal; }
0174   void setConstant(bool Val) { isConstantGlobal = Val; }
0175 
0176   bool isExternallyInitialized() const {
0177     return isExternallyInitializedConstant;
0178   }
0179   void setExternallyInitialized(bool Val) {
0180     isExternallyInitializedConstant = Val;
0181   }
0182 
0183   /// copyAttributesFrom - copy all additional attributes (those not needed to
0184   /// create a GlobalVariable) from the GlobalVariable Src to this one.
0185   void copyAttributesFrom(const GlobalVariable *Src);
0186 
0187   /// removeFromParent - This method unlinks 'this' from the containing module,
0188   /// but does not delete it.
0189   ///
0190   void removeFromParent();
0191 
0192   /// eraseFromParent - This method unlinks 'this' from the containing module
0193   /// and deletes it.
0194   ///
0195   void eraseFromParent();
0196 
0197   /// Drop all references in preparation to destroy the GlobalVariable. This
0198   /// drops not only the reference to the initializer but also to any metadata.
0199   void dropAllReferences();
0200 
0201   /// Attach a DIGlobalVariableExpression.
0202   void addDebugInfo(DIGlobalVariableExpression *GV);
0203 
0204   /// Fill the vector with all debug info attachements.
0205   void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const;
0206 
0207   /// Add attribute to this global.
0208   void addAttribute(Attribute::AttrKind Kind) {
0209     Attrs = Attrs.addAttribute(getContext(), Kind);
0210   }
0211 
0212   /// Add attribute to this global.
0213   void addAttribute(StringRef Kind, StringRef Val = StringRef()) {
0214     Attrs = Attrs.addAttribute(getContext(), Kind, Val);
0215   }
0216 
0217   /// Return true if the attribute exists.
0218   bool hasAttribute(Attribute::AttrKind Kind) const {
0219     return Attrs.hasAttribute(Kind);
0220   }
0221 
0222   /// Return true if the attribute exists.
0223   bool hasAttribute(StringRef Kind) const {
0224     return Attrs.hasAttribute(Kind);
0225   }
0226 
0227   /// Return true if any attributes exist.
0228   bool hasAttributes() const {
0229     return Attrs.hasAttributes();
0230   }
0231 
0232   /// Return the attribute object.
0233   Attribute getAttribute(Attribute::AttrKind Kind) const {
0234     return Attrs.getAttribute(Kind);
0235   }
0236 
0237   /// Return the attribute object.
0238   Attribute getAttribute(StringRef Kind) const {
0239     return Attrs.getAttribute(Kind);
0240   }
0241 
0242   /// Return the attribute set for this global
0243   AttributeSet getAttributes() const {
0244     return Attrs;
0245   }
0246 
0247   /// Return attribute set as list with index.
0248   /// FIXME: This may not be required once ValueEnumerators
0249   /// in bitcode-writer can enumerate attribute-set.
0250   AttributeList getAttributesAsList(unsigned index) const {
0251     if (!hasAttributes())
0252       return AttributeList();
0253     std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}};
0254     return AttributeList::get(getContext(), AS);
0255   }
0256 
0257   /// Set attribute list for this global
0258   void setAttributes(AttributeSet A) {
0259     Attrs = A;
0260   }
0261 
0262   /// Check if section name is present
0263   bool hasImplicitSection() const {
0264     return getAttributes().hasAttribute("bss-section") ||
0265            getAttributes().hasAttribute("data-section") ||
0266            getAttributes().hasAttribute("relro-section") ||
0267            getAttributes().hasAttribute("rodata-section");
0268   }
0269 
0270   /// Get the custom code model raw value of this global.
0271   ///
0272   unsigned getCodeModelRaw() const {
0273     unsigned Data = getGlobalValueSubClassData();
0274     return (Data >> CodeModelShift) & CodeModelMask;
0275   }
0276 
0277   /// Get the custom code model of this global if it has one.
0278   ///
0279   /// If this global does not have a custom code model, the empty instance
0280   /// will be returned.
0281   std::optional<CodeModel::Model> getCodeModel() const {
0282     unsigned CodeModelData = getCodeModelRaw();
0283     if (CodeModelData > 0)
0284       return static_cast<CodeModel::Model>(CodeModelData - 1);
0285     return {};
0286   }
0287 
0288   /// Change the code model for this global.
0289   ///
0290   void setCodeModel(CodeModel::Model CM);
0291 
0292   // Methods for support type inquiry through isa, cast, and dyn_cast:
0293   static bool classof(const Value *V) {
0294     return V->getValueID() == Value::GlobalVariableVal;
0295   }
0296 };
0297 
0298 template <>
0299 struct OperandTraits<GlobalVariable> :
0300   public OptionalOperandTraits<GlobalVariable> {
0301 };
0302 
0303 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
0304 
0305 } // end namespace llvm
0306 
0307 #endif // LLVM_IR_GLOBALVARIABLE_H