Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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