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 | |
22 | namespace llvm { |
23 | |
24 | class Comdat; |
25 | class Metadata; |
26 | |
27 | class GlobalObject : public GlobalValue { |
28 | public: |
29 | // VCallVisibility - values for visibility metadata attached to vtables. This |
30 | // describes the scope in which a virtual call could end up being dispatched |
31 | // through this vtable. |
32 | enum VCallVisibility { |
33 | // Type is potentially visible to external code. |
34 | VCallVisibilityPublic = 0, |
35 | // Type is only visible to code which will be in the current Module after |
36 | // LTO internalization. |
37 | VCallVisibilityLinkageUnit = 1, |
38 | // Type is only visible to code in the current Module. |
39 | VCallVisibilityTranslationUnit = 2, |
40 | }; |
41 | |
42 | protected: |
43 | GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, |
44 | LinkageTypes Linkage, const Twine &Name, |
45 | unsigned AddressSpace = 0) |
46 | : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace) { |
47 | setGlobalValueSubClassData(0); |
48 | } |
49 | ~GlobalObject(); |
50 | |
51 | Comdat *ObjComdat = nullptr; |
52 | enum { |
53 | LastAlignmentBit = 5, |
54 | LastCodeModelBit = 8, |
55 | HasSectionHashEntryBit, |
56 | |
57 | GlobalObjectBits, |
58 | }; |
59 | static const unsigned GlobalObjectSubClassDataBits = |
60 | GlobalValueSubClassDataBits - GlobalObjectBits; |
61 | |
62 | private: |
63 | static const unsigned AlignmentBits = LastAlignmentBit + 1; |
64 | static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; |
65 | static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; |
66 | |
67 | public: |
68 | GlobalObject(const GlobalObject &) = delete; |
69 | |
70 | /// FIXME: Remove this function once transition to Align is over. |
71 | uint64_t getAlignment() const { |
72 | MaybeAlign Align = getAlign(); |
73 | return Align ? Align->value() : 0; |
74 | } |
75 | |
76 | /// Returns the alignment of the given variable or function. |
77 | /// |
78 | /// Note that for functions this is the alignment of the code, not the |
79 | /// alignment of a function pointer. |
80 | MaybeAlign getAlign() const { |
81 | unsigned Data = getGlobalValueSubClassData(); |
82 | unsigned AlignmentData = Data & AlignmentMask; |
83 | return decodeMaybeAlign(Value: AlignmentData); |
84 | } |
85 | |
86 | /// Sets the alignment attribute of the GlobalObject. |
87 | void setAlignment(Align Align); |
88 | |
89 | /// Sets the alignment attribute of the GlobalObject. |
90 | /// This method will be deprecated as the alignment property should always be |
91 | /// defined. |
92 | void setAlignment(MaybeAlign Align); |
93 | |
94 | unsigned getGlobalObjectSubClassData() const { |
95 | unsigned ValueData = getGlobalValueSubClassData(); |
96 | return ValueData >> GlobalObjectBits; |
97 | } |
98 | |
99 | void setGlobalObjectSubClassData(unsigned Val) { |
100 | unsigned OldData = getGlobalValueSubClassData(); |
101 | setGlobalValueSubClassData((OldData & GlobalObjectMask) | |
102 | (Val << GlobalObjectBits)); |
103 | assert(getGlobalObjectSubClassData() == Val && "representation error" ); |
104 | } |
105 | |
106 | /// Check if this global has a custom object file section. |
107 | /// |
108 | /// This is more efficient than calling getSection() and checking for an empty |
109 | /// string. |
110 | bool hasSection() const { |
111 | return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); |
112 | } |
113 | |
114 | /// Get the custom section of this global if it has one. |
115 | /// |
116 | /// If this global does not have a custom section, this will be empty and the |
117 | /// default object file section (.text, .data, etc) will be used. |
118 | StringRef getSection() const { |
119 | return hasSection() ? getSectionImpl() : StringRef(); |
120 | } |
121 | |
122 | /// Change the section for this global. |
123 | /// |
124 | /// Setting the section to the empty string tells LLVM to choose an |
125 | /// appropriate default object file section. |
126 | void setSection(StringRef S); |
127 | |
128 | bool hasComdat() const { return getComdat() != nullptr; } |
129 | const Comdat *getComdat() const { return ObjComdat; } |
130 | Comdat *getComdat() { return ObjComdat; } |
131 | void setComdat(Comdat *C); |
132 | |
133 | using Value::addMetadata; |
134 | using Value::clearMetadata; |
135 | using Value::eraseMetadata; |
136 | using Value::eraseMetadataIf; |
137 | using Value::getAllMetadata; |
138 | using Value::getMetadata; |
139 | using Value::hasMetadata; |
140 | using Value::setMetadata; |
141 | |
142 | /// Copy metadata from Src, adjusting offsets by Offset. |
143 | void copyMetadata(const GlobalObject *Src, unsigned Offset); |
144 | |
145 | void addTypeMetadata(unsigned Offset, Metadata *TypeID); |
146 | void setVCallVisibilityMetadata(VCallVisibility Visibility); |
147 | VCallVisibility getVCallVisibility() const; |
148 | |
149 | /// Returns true if the alignment of the value can be unilaterally |
150 | /// increased. |
151 | /// |
152 | /// Note that for functions this is the alignment of the code, not the |
153 | /// alignment of a function pointer. |
154 | bool canIncreaseAlignment() const; |
155 | |
156 | protected: |
157 | void copyAttributesFrom(const GlobalObject *Src); |
158 | |
159 | public: |
160 | // Methods for support type inquiry through isa, cast, and dyn_cast: |
161 | static bool classof(const Value *V) { |
162 | return V->getValueID() == Value::FunctionVal || |
163 | V->getValueID() == Value::GlobalVariableVal || |
164 | V->getValueID() == Value::GlobalIFuncVal; |
165 | } |
166 | |
167 | private: |
168 | void setGlobalObjectFlag(unsigned Bit, bool Val) { |
169 | unsigned Mask = 1 << Bit; |
170 | setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | |
171 | (Val ? Mask : 0u)); |
172 | } |
173 | |
174 | StringRef getSectionImpl() const; |
175 | }; |
176 | |
177 | } // end namespace llvm |
178 | |
179 | #endif // LLVM_IR_GLOBALOBJECT_H |
180 | |