File indexing completed on 2026-05-10 08:44:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_TEXTAPI_RECORD_H
0015 #define LLVM_TEXTAPI_RECORD_H
0016
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/Support/Casting.h"
0020 #include "llvm/TextAPI/Symbol.h"
0021 #include <string>
0022
0023 namespace llvm {
0024 namespace MachO {
0025
0026 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
0027
0028 class RecordsSlice;
0029
0030
0031 struct RecordLoc {
0032 RecordLoc() = default;
0033 RecordLoc(std::string File, unsigned Line)
0034 : File(std::move(File)), Line(Line) {}
0035
0036
0037 bool isValid() const { return !File.empty(); }
0038
0039 bool operator==(const RecordLoc &O) const {
0040 return std::tie(File, Line) == std::tie(O.File, O.Line);
0041 }
0042
0043 const std::string File;
0044 const unsigned Line = 0;
0045 };
0046
0047
0048 enum class RecordLinkage : uint8_t {
0049
0050 Unknown = 0,
0051
0052
0053 Internal = 1,
0054
0055
0056 Undefined = 2,
0057
0058
0059 Rexported = 3,
0060
0061
0062 Exported = 4,
0063 };
0064
0065
0066
0067 class Record {
0068 public:
0069 Record() = default;
0070 Record(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags)
0071 : Name(Name), Linkage(Linkage), Flags(mergeFlags(Flags, Linkage)),
0072 Verified(false) {}
0073
0074 bool isWeakDefined() const {
0075 return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined;
0076 }
0077
0078 bool isWeakReferenced() const {
0079 return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced;
0080 }
0081
0082 bool isThreadLocalValue() const {
0083 return (Flags & SymbolFlags::ThreadLocalValue) ==
0084 SymbolFlags::ThreadLocalValue;
0085 }
0086
0087 bool isData() const {
0088 return (Flags & SymbolFlags::Data) == SymbolFlags::Data;
0089 }
0090
0091 bool isText() const {
0092 return (Flags & SymbolFlags::Text) == SymbolFlags::Text;
0093 }
0094
0095 bool isInternal() const { return Linkage == RecordLinkage::Internal; }
0096 bool isUndefined() const { return Linkage == RecordLinkage::Undefined; }
0097 bool isExported() const { return Linkage >= RecordLinkage::Rexported; }
0098 bool isRexported() const { return Linkage == RecordLinkage::Rexported; }
0099
0100 bool isVerified() const { return Verified; }
0101 void setVerify(bool V = true) { Verified = V; }
0102
0103 StringRef getName() const { return Name; }
0104 SymbolFlags getFlags() const { return Flags; }
0105
0106 private:
0107 SymbolFlags mergeFlags(SymbolFlags Flags, RecordLinkage Linkage);
0108
0109 protected:
0110 StringRef Name;
0111 RecordLinkage Linkage;
0112 SymbolFlags Flags;
0113 bool Verified;
0114
0115 friend class RecordsSlice;
0116 };
0117
0118
0119 class GlobalRecord : public Record {
0120 public:
0121 enum class Kind : uint8_t {
0122 Unknown = 0,
0123 Variable = 1,
0124 Function = 2,
0125 };
0126
0127 GlobalRecord(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags,
0128 Kind GV, bool Inlined)
0129 : Record({Name, Linkage, Flags}), GV(GV), Inlined(Inlined) {}
0130
0131 bool isFunction() const { return GV == Kind::Function; }
0132 bool isVariable() const { return GV == Kind::Variable; }
0133 void setKind(const Kind &V) {
0134 if (GV == Kind::Unknown)
0135 GV = V;
0136 }
0137 bool isInlined() const { return Inlined; }
0138
0139 private:
0140 Kind GV;
0141 bool Inlined = false;
0142 };
0143
0144
0145 class ObjCIVarRecord : public Record {
0146 public:
0147 ObjCIVarRecord(StringRef Name, RecordLinkage Linkage)
0148 : Record({Name, Linkage, SymbolFlags::Data}) {}
0149
0150 static std::string createScopedName(StringRef SuperClass, StringRef IVar) {
0151 return (SuperClass + "." + IVar).str();
0152 }
0153 };
0154
0155 template <typename V, typename K = StringRef,
0156 typename std::enable_if<std::is_base_of<Record, V>::value>::type * =
0157 nullptr>
0158 using RecordMap = llvm::MapVector<K, std::unique_ptr<V>>;
0159
0160
0161
0162 class ObjCContainerRecord : public Record {
0163 public:
0164 ObjCContainerRecord(StringRef Name, RecordLinkage Linkage)
0165 : Record({Name, Linkage, SymbolFlags::Data}) {}
0166
0167 ObjCIVarRecord *addObjCIVar(StringRef IVar, RecordLinkage Linkage);
0168 ObjCIVarRecord *findObjCIVar(StringRef IVar) const;
0169 std::vector<ObjCIVarRecord *> getObjCIVars() const;
0170 RecordLinkage getLinkage() const { return Linkage; }
0171
0172 private:
0173 RecordMap<ObjCIVarRecord> IVars;
0174 };
0175
0176
0177
0178 class ObjCCategoryRecord : public ObjCContainerRecord {
0179 public:
0180 ObjCCategoryRecord(StringRef ClassToExtend, StringRef Name)
0181 : ObjCContainerRecord(Name, RecordLinkage::Unknown),
0182 ClassToExtend(ClassToExtend) {}
0183
0184 StringRef getSuperClassName() const { return ClassToExtend; }
0185
0186 private:
0187 StringRef ClassToExtend;
0188 };
0189
0190
0191 class ObjCInterfaceRecord : public ObjCContainerRecord {
0192 public:
0193 ObjCInterfaceRecord(StringRef Name, RecordLinkage Linkage,
0194 ObjCIFSymbolKind SymType)
0195 : ObjCContainerRecord(Name, Linkage) {
0196 updateLinkageForSymbols(SymType, Linkage);
0197 }
0198
0199 bool hasExceptionAttribute() const {
0200 return Linkages.EHType != RecordLinkage::Unknown;
0201 }
0202 bool isCompleteInterface() const {
0203 return Linkages.Class >= RecordLinkage::Rexported &&
0204 Linkages.MetaClass >= RecordLinkage::Rexported;
0205 }
0206 bool isExportedSymbol(ObjCIFSymbolKind CurrType) const {
0207 return getLinkageForSymbol(CurrType) >= RecordLinkage::Rexported;
0208 }
0209
0210 RecordLinkage getLinkageForSymbol(ObjCIFSymbolKind CurrType) const;
0211 void updateLinkageForSymbols(ObjCIFSymbolKind SymType, RecordLinkage Link);
0212
0213 bool addObjCCategory(ObjCCategoryRecord *Record);
0214 std::vector<ObjCCategoryRecord *> getObjCCategories() const;
0215
0216 private:
0217
0218 struct Linkages {
0219 RecordLinkage Class = RecordLinkage::Unknown;
0220 RecordLinkage MetaClass = RecordLinkage::Unknown;
0221 RecordLinkage EHType = RecordLinkage::Unknown;
0222 bool operator==(const Linkages &other) const {
0223 return std::tie(Class, MetaClass, EHType) ==
0224 std::tie(other.Class, other.MetaClass, other.EHType);
0225 }
0226 bool operator!=(const Linkages &other) const { return !(*this == other); }
0227 };
0228 Linkages Linkages;
0229
0230
0231 llvm::MapVector<StringRef, ObjCCategoryRecord *> Categories;
0232 };
0233
0234 }
0235 }
0236
0237 #endif