1//===- llvm/TextAPI/Record.h - TAPI Record ----------------------*- 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/// \file 10/// \brief Implements the TAPI Record Types. 11/// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_TEXTAPI_RECORD_H 15#define LLVM_TEXTAPI_RECORD_H 16 17#include "llvm/ADT/MapVector.h" 18#include "llvm/ADT/StringRef.h" 19#include "llvm/Support/Casting.h" 20#include "llvm/TextAPI/Symbol.h" 21#include <string> 22 23namespace llvm { 24namespace MachO { 25 26LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 27 28class RecordsSlice; 29 30// Defines a list of linkage types. 31enum class RecordLinkage : uint8_t { 32 // Unknown linkage. 33 Unknown = 0, 34 35 // Local, hidden or private extern linkage. 36 Internal = 1, 37 38 // Undefined linkage, it represents usage of external interface. 39 Undefined = 2, 40 41 // Re-exported linkage, record is defined in external interface. 42 Rexported = 3, 43 44 // Exported linkage. 45 Exported = 4, 46}; 47 48/// Define Record. They represent API's in binaries that could be linkable 49/// symbols. 50class Record { 51public: 52 Record() = default; 53 Record(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags) 54 : Name(Name), Linkage(Linkage), Flags(mergeFlags(Flags, Linkage)) {} 55 56 bool isWeakDefined() const { 57 return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined; 58 } 59 60 bool isWeakReferenced() const { 61 return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced; 62 } 63 64 bool isThreadLocalValue() const { 65 return (Flags & SymbolFlags::ThreadLocalValue) == 66 SymbolFlags::ThreadLocalValue; 67 } 68 69 bool isData() const { 70 return (Flags & SymbolFlags::Data) == SymbolFlags::Data; 71 } 72 73 bool isText() const { 74 return (Flags & SymbolFlags::Text) == SymbolFlags::Text; 75 } 76 77 bool isInternal() const { return Linkage == RecordLinkage::Internal; } 78 bool isUndefined() const { return Linkage == RecordLinkage::Undefined; } 79 bool isExported() const { return Linkage >= RecordLinkage::Rexported; } 80 bool isRexported() const { return Linkage == RecordLinkage::Rexported; } 81 82 StringRef getName() const { return Name; } 83 SymbolFlags getFlags() const { return Flags; } 84 85private: 86 SymbolFlags mergeFlags(SymbolFlags Flags, RecordLinkage Linkage); 87 88protected: 89 StringRef Name; 90 RecordLinkage Linkage; 91 SymbolFlags Flags; 92 93 friend class RecordsSlice; 94}; 95 96// Defines broadly non-objc records, categorized as variables or functions. 97class GlobalRecord : public Record { 98public: 99 enum class Kind : uint8_t { 100 Unknown = 0, 101 Variable = 1, 102 Function = 2, 103 }; 104 105 GlobalRecord(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags, 106 Kind GV) 107 : Record({Name, Linkage, Flags}), GV(GV) {} 108 109 bool isFunction() const { return GV == Kind::Function; } 110 bool isVariable() const { return GV == Kind::Variable; } 111 void setKind(const Kind &V) { 112 if (GV == Kind::Unknown) 113 GV = V; 114 } 115 116private: 117 Kind GV; 118}; 119 120// Define Objective-C instance variable records. 121class ObjCIVarRecord : public Record { 122public: 123 ObjCIVarRecord(StringRef Name, RecordLinkage Linkage) 124 : Record({Name, Linkage, SymbolFlags::Data}) {} 125 126 static std::string createScopedName(StringRef SuperClass, StringRef IVar) { 127 return (SuperClass + "." + IVar).str(); 128 } 129}; 130 131template <typename V, typename K = StringRef, 132 typename std::enable_if<std::is_base_of<Record, V>::value>::type * = 133 nullptr> 134using RecordMap = llvm::MapVector<K, std::unique_ptr<V>>; 135 136// Defines Objective-C record types that have assigned methods, properties, 137// instance variable (ivars) and protocols. 138class ObjCContainerRecord : public Record { 139public: 140 ObjCContainerRecord(StringRef Name, RecordLinkage Linkage) 141 : Record({Name, Linkage, SymbolFlags::Data}) {} 142 143 ObjCIVarRecord *addObjCIVar(StringRef IVar, RecordLinkage Linkage); 144 ObjCIVarRecord *findObjCIVar(StringRef IVar) const; 145 std::vector<ObjCIVarRecord *> getObjCIVars() const; 146 147private: 148 RecordMap<ObjCIVarRecord> IVars; 149}; 150 151// Define Objective-C category types. They don't generate linkable symbols, but 152// they have assigned ivars that do. 153class ObjCCategoryRecord : public ObjCContainerRecord { 154public: 155 ObjCCategoryRecord(StringRef ClassToExtend, StringRef Name) 156 : ObjCContainerRecord(Name, RecordLinkage::Unknown), 157 ClassToExtend(ClassToExtend) {} 158 159private: 160 StringRef ClassToExtend; 161}; 162 163// Define Objective-C Interfaces or class types. 164class ObjCInterfaceRecord : public ObjCContainerRecord { 165public: 166 ObjCInterfaceRecord(StringRef Name, RecordLinkage Linkage, 167 bool HasEHType = false) 168 : ObjCContainerRecord(Name, Linkage), HasEHType(HasEHType) {} 169 170 bool hasExceptionAttribute() const { return HasEHType; } 171 bool addObjCCategory(ObjCCategoryRecord *Record); 172 std::vector<ObjCCategoryRecord *> getObjCCategories() const; 173 174private: 175 bool HasEHType; 176 // Non-owning containers of categories that extend the class. 177 llvm::MapVector<StringRef, ObjCCategoryRecord *> Categories; 178}; 179 180} // end namespace MachO. 181} // end namespace llvm. 182 183#endif // LLVM_TEXTAPI_RECORD_H 184