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) GlobalValue(Ty,VTy,Ops,NumOps,Linkage,Name,AddressSpace)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. getAlignment()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. getAlign()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 getGlobalObjectSubClassData()88 unsigned getGlobalObjectSubClassData() const { 89 unsigned ValueData = getGlobalValueSubClassData(); 90 return ValueData >> GlobalObjectBits; 91 } 92 setGlobalObjectSubClassData(unsigned Val)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. hasSection()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. getSection()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 hasComdat()122 bool hasComdat() const { return getComdat() != nullptr; } getComdat()123 const Comdat *getComdat() const { return ObjComdat; } getComdat()124 Comdat *getComdat() { return ObjComdat; } setComdat(Comdat * C)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: classof(const Value * V)154 static bool classof(const Value *V) { 155 return V->getValueID() == Value::FunctionVal || 156 V->getValueID() == Value::GlobalVariableVal; 157 } 158 159 private: setGlobalObjectFlag(unsigned Bit,bool Val)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