GlobalObject.h revision 360784
1//===-- llvm/GlobalObject.h - Class to represent global objects -*- 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 represents an independent object. That is, a function or a global
10// variable, but not an alias.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_GLOBALOBJECT_H
15#define LLVM_IR_GLOBALOBJECT_H
16
17#include "llvm/ADT/StringRef.h"
18#include "llvm/IR/GlobalValue.h"
19#include "llvm/IR/Value.h"
20#include "llvm/Support/Alignment.h"
21#include <string>
22#include <utility>
23
24namespace llvm {
25
26class Comdat;
27class MDNode;
28class Metadata;
29
30class GlobalObject : public GlobalValue {
31public:
32  // VCallVisibility - values for visibility metadata attached to vtables. This
33  // describes the scope in which a virtual call could end up being dispatched
34  // through this vtable.
35  enum VCallVisibility {
36    // Type is potentially visible to external code.
37    VCallVisibilityPublic = 0,
38    // Type is only visible to code which will be in the current Module after
39    // LTO internalization.
40    VCallVisibilityLinkageUnit = 1,
41    // Type is only visible to code in the current Module.
42    VCallVisibilityTranslationUnit = 2,
43  };
44
45protected:
46  GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
47               LinkageTypes Linkage, const Twine &Name,
48               unsigned AddressSpace = 0)
49      : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace),
50        ObjComdat(nullptr) {
51    setGlobalValueSubClassData(0);
52  }
53
54  Comdat *ObjComdat;
55  enum {
56    LastAlignmentBit = 4,
57    HasMetadataHashEntryBit,
58    HasSectionHashEntryBit,
59
60    GlobalObjectBits,
61  };
62  static const unsigned GlobalObjectSubClassDataBits =
63      GlobalValueSubClassDataBits - GlobalObjectBits;
64
65private:
66  static const unsigned AlignmentBits = LastAlignmentBit + 1;
67  static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
68  static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1;
69
70public:
71  GlobalObject(const GlobalObject &) = delete;
72
73  unsigned getAlignment() const {
74    unsigned Data = getGlobalValueSubClassData();
75    unsigned AlignmentData = Data & AlignmentMask;
76    MaybeAlign Align = decodeMaybeAlign(AlignmentData);
77    return Align ? Align->value() : 0;
78  }
79
80  /// FIXME: Remove this setter once the migration to MaybeAlign is over.
81  LLVM_ATTRIBUTE_DEPRECATED(void setAlignment(unsigned Align),
82                            "Please use `void setAlignment(MaybeAlign Align)`");
83  void setAlignment(MaybeAlign Align);
84
85  unsigned getGlobalObjectSubClassData() const {
86    unsigned ValueData = getGlobalValueSubClassData();
87    return ValueData >> GlobalObjectBits;
88  }
89
90  void setGlobalObjectSubClassData(unsigned Val) {
91    unsigned OldData = getGlobalValueSubClassData();
92    setGlobalValueSubClassData((OldData & GlobalObjectMask) |
93                               (Val << GlobalObjectBits));
94    assert(getGlobalObjectSubClassData() == Val && "representation error");
95  }
96
97  /// Check if this global has a custom object file section.
98  ///
99  /// This is more efficient than calling getSection() and checking for an empty
100  /// string.
101  bool hasSection() const {
102    return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit);
103  }
104
105  /// Get the custom section of this global if it has one.
106  ///
107  /// If this global does not have a custom section, this will be empty and the
108  /// default object file section (.text, .data, etc) will be used.
109  StringRef getSection() const {
110    return hasSection() ? getSectionImpl() : StringRef();
111  }
112
113  /// Change the section for this global.
114  ///
115  /// Setting the section to the empty string tells LLVM to choose an
116  /// appropriate default object file section.
117  void setSection(StringRef S);
118
119  bool hasComdat() const { return getComdat() != nullptr; }
120  const Comdat *getComdat() const { return ObjComdat; }
121  Comdat *getComdat() { return ObjComdat; }
122  void setComdat(Comdat *C) { ObjComdat = C; }
123
124  /// Check if this has any metadata.
125  bool hasMetadata() const { return hasMetadataHashEntry(); }
126
127  /// Check if this has any metadata of the given kind.
128  bool hasMetadata(unsigned KindID) const {
129    return getMetadata(KindID) != nullptr;
130  }
131  bool hasMetadata(StringRef Kind) const {
132    return getMetadata(Kind) != nullptr;
133  }
134
135  /// Get the current metadata attachments for the given kind, if any.
136  ///
137  /// These functions require that the function have at most a single attachment
138  /// of the given kind, and return \c nullptr if such an attachment is missing.
139  /// @{
140  MDNode *getMetadata(unsigned KindID) const;
141  MDNode *getMetadata(StringRef Kind) const;
142  /// @}
143
144  /// Appends all attachments with the given ID to \c MDs in insertion order.
145  /// If the global has no attachments with the given ID, or if ID is invalid,
146  /// leaves MDs unchanged.
147  /// @{
148  void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const;
149  void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const;
150  /// @}
151
152  /// Set a particular kind of metadata attachment.
153  ///
154  /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
155  /// replacing it if it already exists.
156  /// @{
157  void setMetadata(unsigned KindID, MDNode *MD);
158  void setMetadata(StringRef Kind, MDNode *MD);
159  /// @}
160
161  /// Add a metadata attachment.
162  /// @{
163  void addMetadata(unsigned KindID, MDNode &MD);
164  void addMetadata(StringRef Kind, MDNode &MD);
165  /// @}
166
167  /// Appends all attachments for the global to \c MDs, sorting by attachment
168  /// ID. Attachments with the same ID appear in insertion order.
169  void
170  getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
171
172  /// Erase all metadata attachments with the given kind.
173  ///
174  /// \returns true if any metadata was removed.
175  bool eraseMetadata(unsigned KindID);
176
177  /// Copy metadata from Src, adjusting offsets by Offset.
178  void copyMetadata(const GlobalObject *Src, unsigned Offset);
179
180  void addTypeMetadata(unsigned Offset, Metadata *TypeID);
181  void addVCallVisibilityMetadata(VCallVisibility Visibility);
182  VCallVisibility getVCallVisibility() const;
183
184protected:
185  void copyAttributesFrom(const GlobalObject *Src);
186
187public:
188  // Methods for support type inquiry through isa, cast, and dyn_cast:
189  static bool classof(const Value *V) {
190    return V->getValueID() == Value::FunctionVal ||
191           V->getValueID() == Value::GlobalVariableVal;
192  }
193
194  void clearMetadata();
195
196private:
197  void setGlobalObjectFlag(unsigned Bit, bool Val) {
198    unsigned Mask = 1 << Bit;
199    setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
200                               (Val ? Mask : 0u));
201  }
202
203  bool hasMetadataHashEntry() const {
204    return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit);
205  }
206  void setHasMetadataHashEntry(bool HasEntry) {
207    setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry);
208  }
209
210  StringRef getSectionImpl() const;
211};
212
213} // end namespace llvm
214
215#endif // LLVM_IR_GLOBALOBJECT_H
216