Coverage Report

Created: 2019-07-24 05:18

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