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