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 24 namespace llvm { 25 26 class Comdat; 27 class MDNode; 28 class Metadata; 29 30 class GlobalObject : public GlobalValue { 31 public: 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 45 protected: 46 GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, 47 LinkageTypes Linkage, const Twine &Name, 48 unsigned AddressSpace = 0) GlobalValue(Ty,VTy,Ops,NumOps,Linkage,Name,AddressSpace)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 65 private: 66 static const unsigned AlignmentBits = LastAlignmentBit + 1; 67 static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; 68 static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; 69 70 public: 71 GlobalObject(const GlobalObject &) = delete; 72 getAlignment()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 getGlobalObjectSubClassData()85 unsigned getGlobalObjectSubClassData() const { 86 unsigned ValueData = getGlobalValueSubClassData(); 87 return ValueData >> GlobalObjectBits; 88 } 89 setGlobalObjectSubClassData(unsigned Val)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. hasSection()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. getSection()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 hasComdat()119 bool hasComdat() const { return getComdat() != nullptr; } getComdat()120 const Comdat *getComdat() const { return ObjComdat; } getComdat()121 Comdat *getComdat() { return ObjComdat; } setComdat(Comdat * C)122 void setComdat(Comdat *C) { ObjComdat = C; } 123 124 /// Check if this has any metadata. hasMetadata()125 bool hasMetadata() const { return hasMetadataHashEntry(); } 126 127 /// Check if this has any metadata of the given kind. hasMetadata(unsigned KindID)128 bool hasMetadata(unsigned KindID) const { 129 return getMetadata(KindID) != nullptr; 130 } hasMetadata(StringRef Kind)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 184 protected: 185 void copyAttributesFrom(const GlobalObject *Src); 186 187 public: 188 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const Value * V)189 static bool classof(const Value *V) { 190 return V->getValueID() == Value::FunctionVal || 191 V->getValueID() == Value::GlobalVariableVal; 192 } 193 194 void clearMetadata(); 195 196 private: setGlobalObjectFlag(unsigned Bit,bool Val)197 void setGlobalObjectFlag(unsigned Bit, bool Val) { 198 unsigned Mask = 1 << Bit; 199 setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | 200 (Val ? Mask : 0u)); 201 } 202 hasMetadataHashEntry()203 bool hasMetadataHashEntry() const { 204 return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); 205 } setHasMetadataHashEntry(bool HasEntry)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