blob: d01abdc3b625da94b10134e4b64cb0cdde851ec9 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/GlobalObject.h - Class to represent global objects -*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020020#include "llvm/Support/Alignment.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010021#include <string>
22#include <utility>
23
24namespace llvm {
25
26class Comdat;
27class MDNode;
28class Metadata;
29
30class GlobalObject : public GlobalValue {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020031public:
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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010045protected:
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,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010057 HasSectionHashEntryBit,
58
59 GlobalObjectBits,
60 };
61 static const unsigned GlobalObjectSubClassDataBits =
62 GlobalValueSubClassDataBits - GlobalObjectBits;
63
64private:
65 static const unsigned AlignmentBits = LastAlignmentBit + 1;
66 static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
67 static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1;
68
69public:
70 GlobalObject(const GlobalObject &) = delete;
71
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020072 /// FIXME: Remove this function once transition to Align is over.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010073 unsigned getAlignment() const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020074 MaybeAlign Align = getAlign();
75 return Align ? Align->value() : 0;
76 }
77
78 /// Returns the alignment of the given variable or function.
79 ///
80 /// Note that for functions this is the alignment of the code, not the
81 /// alignment of a function pointer.
82 MaybeAlign getAlign() const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083 unsigned Data = getGlobalValueSubClassData();
84 unsigned AlignmentData = Data & AlignmentMask;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020085 return decodeMaybeAlign(AlignmentData);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010086 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020087
88 void setAlignment(MaybeAlign Align);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089
90 unsigned getGlobalObjectSubClassData() const {
91 unsigned ValueData = getGlobalValueSubClassData();
92 return ValueData >> GlobalObjectBits;
93 }
94
95 void setGlobalObjectSubClassData(unsigned Val) {
96 unsigned OldData = getGlobalValueSubClassData();
97 setGlobalValueSubClassData((OldData & GlobalObjectMask) |
98 (Val << GlobalObjectBits));
99 assert(getGlobalObjectSubClassData() == Val && "representation error");
100 }
101
102 /// Check if this global has a custom object file section.
103 ///
104 /// This is more efficient than calling getSection() and checking for an empty
105 /// string.
106 bool hasSection() const {
107 return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit);
108 }
109
110 /// Get the custom section of this global if it has one.
111 ///
112 /// If this global does not have a custom section, this will be empty and the
113 /// default object file section (.text, .data, etc) will be used.
114 StringRef getSection() const {
115 return hasSection() ? getSectionImpl() : StringRef();
116 }
117
118 /// Change the section for this global.
119 ///
120 /// Setting the section to the empty string tells LLVM to choose an
121 /// appropriate default object file section.
122 void setSection(StringRef S);
123
124 bool hasComdat() const { return getComdat() != nullptr; }
125 const Comdat *getComdat() const { return ObjComdat; }
126 Comdat *getComdat() { return ObjComdat; }
127 void setComdat(Comdat *C) { ObjComdat = C; }
128
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200129 using Value::addMetadata;
130 using Value::clearMetadata;
131 using Value::eraseMetadata;
132 using Value::getAllMetadata;
133 using Value::getMetadata;
134 using Value::hasMetadata;
135 using Value::setMetadata;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100136
137 /// Copy metadata from Src, adjusting offsets by Offset.
138 void copyMetadata(const GlobalObject *Src, unsigned Offset);
139
140 void addTypeMetadata(unsigned Offset, Metadata *TypeID);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200141 void setVCallVisibilityMetadata(VCallVisibility Visibility);
142 VCallVisibility getVCallVisibility() const;
143
144 /// Returns true if the alignment of the value can be unilaterally
145 /// increased.
146 ///
147 /// Note that for functions this is the alignment of the code, not the
148 /// alignment of a function pointer.
149 bool canIncreaseAlignment() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100150
151protected:
152 void copyAttributesFrom(const GlobalObject *Src);
153
154public:
155 // Methods for support type inquiry through isa, cast, and dyn_cast:
156 static bool classof(const Value *V) {
157 return V->getValueID() == Value::FunctionVal ||
158 V->getValueID() == Value::GlobalVariableVal;
159 }
160
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100161private:
162 void setGlobalObjectFlag(unsigned Bit, bool Val) {
163 unsigned Mask = 1 << Bit;
164 setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
165 (Val ? Mask : 0u));
166 }
167
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100168 StringRef getSectionImpl() const;
169};
170
171} // end namespace llvm
172
173#endif // LLVM_IR_GLOBALOBJECT_H