/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/IR/GlobalVariable.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the declaration of the GlobalVariable class, which |
11 | | // represents a single global variable (or constant) in the VM. |
12 | | // |
13 | | // Global variables are constant pointers that refer to hunks of space that are |
14 | | // allocated by either the VM, or by the linker in a static compiler. A global |
15 | | // variable may have an initial value, which is copied into the executables .data |
16 | | // area. Global Constants are required to have initializers. |
17 | | // |
18 | | //===----------------------------------------------------------------------===// |
19 | | |
20 | | #ifndef LLVM_IR_GLOBALVARIABLE_H |
21 | | #define LLVM_IR_GLOBALVARIABLE_H |
22 | | |
23 | | #include "llvm/ADT/PointerUnion.h" |
24 | | #include "llvm/ADT/Twine.h" |
25 | | #include "llvm/ADT/ilist_node.h" |
26 | | #include "llvm/IR/Attributes.h" |
27 | | #include "llvm/IR/GlobalObject.h" |
28 | | #include "llvm/IR/OperandTraits.h" |
29 | | #include "llvm/IR/Value.h" |
30 | | #include <cassert> |
31 | | #include <cstddef> |
32 | | |
33 | | namespace llvm { |
34 | | |
35 | | class Constant; |
36 | | class Module; |
37 | | |
38 | | template <typename ValueSubClass> class SymbolTableListTraits; |
39 | | class DIGlobalVariable; |
40 | | class DIGlobalVariableExpression; |
41 | | |
42 | | class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> { |
43 | | friend class SymbolTableListTraits<GlobalVariable>; |
44 | | |
45 | | AttributeSet Attrs; |
46 | | bool isConstantGlobal : 1; // Is this a global constant? |
47 | | bool isExternallyInitializedConstant : 1; // Is this a global whose value |
48 | | // can change from its initial |
49 | | // value before global |
50 | | // initializers are run? |
51 | | |
52 | | public: |
53 | | /// GlobalVariable ctor - If a parent module is specified, the global is |
54 | | /// automatically inserted into the end of the specified modules global list. |
55 | | GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, |
56 | | Constant *Initializer = nullptr, const Twine &Name = "", |
57 | | ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, |
58 | | bool isExternallyInitialized = false); |
59 | | /// GlobalVariable ctor - This creates a global and inserts it before the |
60 | | /// specified other global. |
61 | | GlobalVariable(Module &M, Type *Ty, bool isConstant, |
62 | | LinkageTypes Linkage, Constant *Initializer, |
63 | | const Twine &Name = "", GlobalVariable *InsertBefore = nullptr, |
64 | | ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, |
65 | | bool isExternallyInitialized = false); |
66 | | GlobalVariable(const GlobalVariable &) = delete; |
67 | | GlobalVariable &operator=(const GlobalVariable &) = delete; |
68 | | |
69 | 128k | ~GlobalVariable() { |
70 | 128k | dropAllReferences(); |
71 | 128k | |
72 | 128k | // FIXME: needed by operator delete |
73 | 128k | setGlobalVariableNumOperands(1); |
74 | 128k | } |
75 | | |
76 | | // allocate space for exactly one operand |
77 | 863k | void *operator new(size_t s) { |
78 | 863k | return User::operator new(s, 1); |
79 | 863k | } |
80 | | |
81 | | /// Provide fast operand accessors |
82 | | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); |
83 | | |
84 | | /// Definitions have initializers, declarations don't. |
85 | | /// |
86 | 34.4M | inline bool hasInitializer() const { return !isDeclaration(); } |
87 | | |
88 | | /// hasDefinitiveInitializer - Whether the global variable has an initializer, |
89 | | /// and any other instances of the global (this can happen due to weak |
90 | | /// linkage) are guaranteed to have the same initializer. |
91 | | /// |
92 | | /// Note that if you want to transform a global, you must use |
93 | | /// hasUniqueInitializer() instead, because of the *_odr linkage type. |
94 | | /// |
95 | | /// Example: |
96 | | /// |
97 | | /// @a = global SomeType* null - Initializer is both definitive and unique. |
98 | | /// |
99 | | /// @b = global weak SomeType* null - Initializer is neither definitive nor |
100 | | /// unique. |
101 | | /// |
102 | | /// @c = global weak_odr SomeType* null - Initializer is definitive, but not |
103 | | /// unique. |
104 | 27.0M | inline bool hasDefinitiveInitializer() const { |
105 | 27.0M | return hasInitializer() && |
106 | 27.0M | // The initializer of a global variable may change to something arbitrary |
107 | 27.0M | // at link time. |
108 | 23.6M | !isInterposable() && |
109 | 27.0M | // The initializer of a global variable with the externally_initialized |
110 | 27.0M | // marker may change at runtime before C++ initializers are evaluated. |
111 | 5.92M | !isExternallyInitialized(); |
112 | 27.0M | } |
113 | | |
114 | | /// hasUniqueInitializer - Whether the global variable has an initializer, and |
115 | | /// any changes made to the initializer will turn up in the final executable. |
116 | 1.99k | inline bool hasUniqueInitializer() const { |
117 | 1.99k | return |
118 | 1.99k | // We need to be sure this is the definition that will actually be used |
119 | 1.99k | isStrongDefinitionForLinker() && |
120 | 1.99k | // It is not safe to modify initializers of global variables with the |
121 | 1.99k | // external_initializer marker since the value may be changed at runtime |
122 | 1.99k | // before C++ initializers are evaluated. |
123 | 1.99k | !isExternallyInitialized(); |
124 | 1.99k | } |
125 | | |
126 | | /// getInitializer - Return the initializer for this global variable. It is |
127 | | /// illegal to call this method if the global is external, because we cannot |
128 | | /// tell what the value is initialized to! |
129 | | /// |
130 | 4.88M | inline const Constant *getInitializer() const { |
131 | 4.88M | assert(hasInitializer() && "GV doesn't have initializer!"); |
132 | 4.88M | return static_cast<Constant*>(Op<0>().get()); |
133 | 4.88M | } |
134 | 4.13M | inline Constant *getInitializer() { |
135 | 4.13M | assert(hasInitializer() && "GV doesn't have initializer!"); |
136 | 4.13M | return static_cast<Constant*>(Op<0>().get()); |
137 | 4.13M | } |
138 | | /// setInitializer - Sets the initializer for this global variable, removing |
139 | | /// any existing initializer if InitVal==NULL. If this GV has type T*, the |
140 | | /// initializer must have type T. |
141 | | void setInitializer(Constant *InitVal); |
142 | | |
143 | | /// If the value is a global constant, its value is immutable throughout the |
144 | | /// runtime execution of the program. Assigning a value into the constant |
145 | | /// leads to undefined behavior. |
146 | | /// |
147 | 61.3M | bool isConstant() const { return isConstantGlobal; } |
148 | 159k | void setConstant(bool Val) { isConstantGlobal = Val; } |
149 | | |
150 | 7.98M | bool isExternallyInitialized() const { |
151 | 7.98M | return isExternallyInitializedConstant; |
152 | 7.98M | } |
153 | 26.3k | void setExternallyInitialized(bool Val) { |
154 | 26.3k | isExternallyInitializedConstant = Val; |
155 | 26.3k | } |
156 | | |
157 | | /// copyAttributesFrom - copy all additional attributes (those not needed to |
158 | | /// create a GlobalVariable) from the GlobalVariable Src to this one. |
159 | | void copyAttributesFrom(const GlobalVariable *Src); |
160 | | |
161 | | /// removeFromParent - This method unlinks 'this' from the containing module, |
162 | | /// but does not delete it. |
163 | | /// |
164 | | void removeFromParent(); |
165 | | |
166 | | /// eraseFromParent - This method unlinks 'this' from the containing module |
167 | | /// and deletes it. |
168 | | /// |
169 | | void eraseFromParent(); |
170 | | |
171 | | /// Drop all references in preparation to destroy the GlobalVariable. This |
172 | | /// drops not only the reference to the initializer but also to any metadata. |
173 | | void dropAllReferences(); |
174 | | |
175 | | /// Attach a DIGlobalVariableExpression. |
176 | | void addDebugInfo(DIGlobalVariableExpression *GV); |
177 | | |
178 | | /// Fill the vector with all debug info attachements. |
179 | | void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const; |
180 | | |
181 | | /// Add attribute to this global. |
182 | 0 | void addAttribute(Attribute::AttrKind Kind) { |
183 | 0 | Attrs = Attrs.addAttribute(getContext(), Kind); |
184 | 0 | } |
185 | | |
186 | | /// Add attribute to this global. |
187 | 44 | void addAttribute(StringRef Kind, StringRef Val = StringRef()) { |
188 | 44 | Attrs = Attrs.addAttribute(getContext(), Kind, Val); |
189 | 44 | } |
190 | | |
191 | | /// Return true if the attribute exists. |
192 | 0 | bool hasAttribute(Attribute::AttrKind Kind) const { |
193 | 0 | return Attrs.hasAttribute(Kind); |
194 | 0 | } |
195 | | |
196 | | /// Return true if the attribute exists. |
197 | 0 | bool hasAttribute(StringRef Kind) const { |
198 | 0 | return Attrs.hasAttribute(Kind); |
199 | 0 | } |
200 | | |
201 | | /// Return true if any attributes exist. |
202 | 9.41k | bool hasAttributes() const { |
203 | 9.41k | return Attrs.hasAttributes(); |
204 | 9.41k | } |
205 | | |
206 | | /// Return the attribute object. |
207 | 0 | Attribute getAttribute(Attribute::AttrKind Kind) const { |
208 | 0 | return Attrs.getAttribute(Kind); |
209 | 0 | } |
210 | | |
211 | | /// Return the attribute object. |
212 | 0 | Attribute getAttribute(StringRef Kind) const { |
213 | 0 | return Attrs.getAttribute(Kind); |
214 | 0 | } |
215 | | |
216 | | /// Return the attribute set for this global |
217 | 3.00M | AttributeSet getAttributes() const { |
218 | 3.00M | return Attrs; |
219 | 3.00M | } |
220 | | |
221 | | /// Return attribute set as list with index. |
222 | | /// FIXME: This may not be required once ValueEnumerators |
223 | | /// in bitcode-writer can enumerate attribute-set. |
224 | 1.55k | AttributeList getAttributesAsList(unsigned index) const { |
225 | 1.55k | if (!hasAttributes()) |
226 | 1.53k | return AttributeList(); |
227 | 24 | std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}}; |
228 | 24 | return AttributeList::get(getContext(), AS); |
229 | 1.55k | } |
230 | | |
231 | | /// Set attribute list for this global |
232 | 3.68k | void setAttributes(AttributeSet A) { |
233 | 3.68k | Attrs = A; |
234 | 3.68k | } |
235 | | |
236 | | /// Check if section name is present |
237 | 715k | bool hasImplicitSection() const { |
238 | 715k | return getAttributes().hasAttribute("bss-section") || |
239 | 715k | getAttributes().hasAttribute("data-section") || |
240 | 715k | getAttributes().hasAttribute("rodata-section"); |
241 | 715k | } |
242 | | |
243 | | // Methods for support type inquiry through isa, cast, and dyn_cast: |
244 | 225M | static bool classof(const Value *V) { |
245 | 225M | return V->getValueID() == Value::GlobalVariableVal; |
246 | 225M | } |
247 | | }; |
248 | | |
249 | | template <> |
250 | | struct OperandTraits<GlobalVariable> : |
251 | | public OptionalOperandTraits<GlobalVariable> { |
252 | | }; |
253 | | |
254 | | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value) |
255 | | |
256 | | } // end namespace llvm |
257 | | |
258 | | #endif // LLVM_IR_GLOBALVARIABLE_H |