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