Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:37

0001 //===- llvm/TextAPI/Record.h - TAPI Record ----------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// \brief Implements the TAPI Record Types.
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 // Defines lightweight source location for records.
0031 struct RecordLoc {
0032   RecordLoc() = default;
0033   RecordLoc(std::string File, unsigned Line)
0034       : File(std::move(File)), Line(Line) {}
0035 
0036   /// Whether there is source location tied to the RecordLoc object.
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 // Defines a list of linkage types.
0048 enum class RecordLinkage : uint8_t {
0049   // Unknown linkage.
0050   Unknown = 0,
0051 
0052   // Local, hidden or private extern linkage.
0053   Internal = 1,
0054 
0055   // Undefined linkage, it represents usage of external interface.
0056   Undefined = 2,
0057 
0058   // Re-exported linkage, record is defined in external interface.
0059   Rexported = 3,
0060 
0061   // Exported linkage.
0062   Exported = 4,
0063 };
0064 
0065 /// Define Record. They represent API's in binaries that could be linkable
0066 /// symbols.
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 // Defines broadly non-objc records, categorized as variables or functions.
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 // Define Objective-C instance variable records.
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 // Defines Objective-C record types that have assigned methods, properties,
0161 // instance variable (ivars) and protocols.
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 // Define Objective-C category types. They don't generate linkable symbols, but
0177 // they have assigned ivars that do.
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 // Define Objective-C Interfaces or class types.
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   /// Linkage level for each symbol represented in ObjCInterfaceRecord.
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   // Non-owning containers of categories that extend the class.
0231   llvm::MapVector<StringRef, ObjCCategoryRecord *> Categories;
0232 };
0233 
0234 } // end namespace MachO.
0235 } // end namespace llvm.
0236 
0237 #endif // LLVM_TEXTAPI_RECORD_H