15f757f3fSDimitry Andric //===- llvm/TextAPI/RecordSlice.h - TAPI RecordSlice ------------*- C++ -*-===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric ///
95f757f3fSDimitry Andric /// \file
105f757f3fSDimitry Andric /// \brief Implements the TAPI Record Collection Type.
115f757f3fSDimitry Andric ///
125f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
135f757f3fSDimitry Andric 
145f757f3fSDimitry Andric #ifndef LLVM_TEXTAPI_RECORDSLICE_H
155f757f3fSDimitry Andric #define LLVM_TEXTAPI_RECORDSLICE_H
165f757f3fSDimitry Andric 
175f757f3fSDimitry Andric #include "llvm/Support/Allocator.h"
185f757f3fSDimitry Andric #include "llvm/TextAPI/InterfaceFile.h"
195f757f3fSDimitry Andric #include "llvm/TextAPI/PackedVersion.h"
205f757f3fSDimitry Andric #include "llvm/TextAPI/Record.h"
21*cb14a3feSDimitry Andric #include "llvm/TextAPI/RecordVisitor.h"
225f757f3fSDimitry Andric 
235f757f3fSDimitry Andric namespace llvm {
245f757f3fSDimitry Andric namespace MachO {
255f757f3fSDimitry Andric 
265f757f3fSDimitry Andric // Define collection of records for a library that are tied to a darwin target
275f757f3fSDimitry Andric // triple.
285f757f3fSDimitry Andric class RecordsSlice {
295f757f3fSDimitry Andric public:
RecordsSlice(const llvm::Triple & T)305f757f3fSDimitry Andric   RecordsSlice(const llvm::Triple &T) : TargetTriple(T), TAPITarget(T) {}
315f757f3fSDimitry Andric   /// Get target triple.
getTriple()325f757f3fSDimitry Andric   const llvm::Triple &getTriple() const { return TargetTriple; }
335f757f3fSDimitry Andric   /// Get TAPI converted target.
getTarget()345f757f3fSDimitry Andric   const Target &getTarget() const { return TAPITarget; }
355f757f3fSDimitry Andric 
365f757f3fSDimitry Andric   /// Add unspecified record to slice.
375f757f3fSDimitry Andric   ///
385f757f3fSDimitry Andric   /// Assign specific record type based on properties and symbol name.
395f757f3fSDimitry Andric   ///
405f757f3fSDimitry Andric   /// \param Name The name of symbol.
415f757f3fSDimitry Andric   /// \param Flags The flags that describe attributes of the symbol.
425f757f3fSDimitry Andric   /// \param GV The kind of global, if this represents a non obj-c global
435f757f3fSDimitry Andric   /// symbol.
445f757f3fSDimitry Andric   /// \param Linkage The linkage of symbol.
455f757f3fSDimitry Andric   /// \return The non-owning pointer to added record in slice.
465f757f3fSDimitry Andric   Record *addRecord(StringRef Name, SymbolFlags Flags,
475f757f3fSDimitry Andric                     GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown,
485f757f3fSDimitry Andric                     RecordLinkage Linkage = RecordLinkage::Unknown);
495f757f3fSDimitry Andric 
505f757f3fSDimitry Andric   /// Add non-ObjC global record.
515f757f3fSDimitry Andric   ///
525f757f3fSDimitry Andric   /// \param Name The name of symbol.
535f757f3fSDimitry Andric   /// \param Flags The flags that describe attributes of the symbol.
545f757f3fSDimitry Andric   /// \param GV The kind of global.
555f757f3fSDimitry Andric   /// \param Linkage The linkage of symbol.
565f757f3fSDimitry Andric   /// \return The non-owning pointer to added record in slice.
575f757f3fSDimitry Andric   GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
585f757f3fSDimitry Andric                           GlobalRecord::Kind GV,
595f757f3fSDimitry Andric                           SymbolFlags Flags = SymbolFlags::None);
605f757f3fSDimitry Andric 
615f757f3fSDimitry Andric   /// Add ObjC Class record.
625f757f3fSDimitry Andric   ///
635f757f3fSDimitry Andric   /// \param Name The name of class, not symbol.
645f757f3fSDimitry Andric   /// \param Linkage The linkage of symbol.
655f757f3fSDimitry Andric   /// \param HasEHType Whether symbol represents an eh_type.
665f757f3fSDimitry Andric   /// \return The non-owning pointer to added record in slice.
675f757f3fSDimitry Andric   ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
685f757f3fSDimitry Andric                                         bool HasEHType = false);
695f757f3fSDimitry Andric 
705f757f3fSDimitry Andric   /// Add ObjC IVar record.
715f757f3fSDimitry Andric   ///
725f757f3fSDimitry Andric   /// \param Name The name of ivar, not symbol.
735f757f3fSDimitry Andric   /// \param Linkage The linkage of symbol.
745f757f3fSDimitry Andric   /// \return The non-owning pointer to added record in slice.
755f757f3fSDimitry Andric   ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, StringRef Name,
765f757f3fSDimitry Andric                               RecordLinkage Linkage);
775f757f3fSDimitry Andric 
785f757f3fSDimitry Andric   /// Add ObjC Category record.
795f757f3fSDimitry Andric   ///
805f757f3fSDimitry Andric   /// \param ClassToExtend The name of class that is being extended by the
815f757f3fSDimitry Andric   /// category, not symbol.
825f757f3fSDimitry Andric   /// \param Category The name of category.
835f757f3fSDimitry Andric   /// \return The non-owning pointer to added record in slice.
845f757f3fSDimitry Andric   ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
855f757f3fSDimitry Andric                                       StringRef Category);
865f757f3fSDimitry Andric 
875f757f3fSDimitry Andric   /// Find ObjC Class.
885f757f3fSDimitry Andric   ///
895f757f3fSDimitry Andric   /// \param Name name of class, not full symbol name.
905f757f3fSDimitry Andric   /// \return The non-owning pointer to record in slice.
915f757f3fSDimitry Andric   ObjCInterfaceRecord *findObjCInterface(StringRef Name) const;
925f757f3fSDimitry Andric 
935f757f3fSDimitry Andric   /// Find ObjC Category.
945f757f3fSDimitry Andric   ///
955f757f3fSDimitry Andric   /// \param ClassToExtend The name of class, not full symbol name.
965f757f3fSDimitry Andric   /// \param Categories The name of category.
975f757f3fSDimitry Andric   /// \return The non-owning pointer to record in slice.
985f757f3fSDimitry Andric   ObjCCategoryRecord *findObjCCategory(StringRef ClassToExtend,
995f757f3fSDimitry Andric                                        StringRef Category) const;
1005f757f3fSDimitry Andric 
1015f757f3fSDimitry Andric   /// Find ObjC Container. This is commonly used for assigning for looking up
1025f757f3fSDimitry Andric   /// instance variables that are assigned to either a category or class.
1035f757f3fSDimitry Andric   ///
1045f757f3fSDimitry Andric   /// \param IsIVar If true, the name is the name of the IVar, otherwise it will
1055f757f3fSDimitry Andric   /// be looked up as the name of the container.
1065f757f3fSDimitry Andric   /// \param Name Either the name of ivar or name of container.
1075f757f3fSDimitry Andric   /// \return The non-owning pointer to record in
1085f757f3fSDimitry Andric   /// slice.
1095f757f3fSDimitry Andric   ObjCContainerRecord *findContainer(bool IsIVar, StringRef Name) const;
1105f757f3fSDimitry Andric 
1115f757f3fSDimitry Andric   /// Find ObjC instance variable.
1125f757f3fSDimitry Andric   ///
1135f757f3fSDimitry Andric   /// \param IsScopedName This is used to determine how to parse the name.
1145f757f3fSDimitry Andric   /// \param Name Either the full name of the symbol or just the ivar.
1155f757f3fSDimitry Andric   /// \return The non-owning pointer to record in slice.
1165f757f3fSDimitry Andric   ObjCIVarRecord *findObjCIVar(bool IsScopedName, StringRef Name) const;
1175f757f3fSDimitry Andric 
1185f757f3fSDimitry Andric   /// Find non-objc global.
1195f757f3fSDimitry Andric   ///
1205f757f3fSDimitry Andric   /// \param Name The name of symbol.
1215f757f3fSDimitry Andric   /// \param GV The Kind of global to find.
1225f757f3fSDimitry Andric   /// \return The non-owning pointer to record in slice.
1235f757f3fSDimitry Andric   GlobalRecord *
1245f757f3fSDimitry Andric   findGlobal(StringRef Name,
1255f757f3fSDimitry Andric              GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown) const;
1265f757f3fSDimitry Andric 
1275f757f3fSDimitry Andric   // Determine if library attributes were assigned.
hasBinaryAttrs()1285f757f3fSDimitry Andric   bool hasBinaryAttrs() const { return BA.get(); }
1295f757f3fSDimitry Andric 
1305f757f3fSDimitry Andric   // Determine if record slice is unassigned.
empty()1315f757f3fSDimitry Andric   bool empty() const {
1325f757f3fSDimitry Andric     return !hasBinaryAttrs() && Globals.empty() && Classes.empty() &&
1335f757f3fSDimitry Andric            Categories.empty();
1345f757f3fSDimitry Andric   }
1355f757f3fSDimitry Andric 
136*cb14a3feSDimitry Andric   // Visit all records known to RecordsSlice.
137*cb14a3feSDimitry Andric   void visit(RecordVisitor &V) const;
138*cb14a3feSDimitry Andric 
1395f757f3fSDimitry Andric   struct BinaryAttrs {
1405f757f3fSDimitry Andric     std::vector<StringRef> AllowableClients;
1415f757f3fSDimitry Andric     std::vector<StringRef> RexportedLibraries;
1425f757f3fSDimitry Andric     std::vector<StringRef> RPaths;
1435f757f3fSDimitry Andric     StringRef ParentUmbrella;
1445f757f3fSDimitry Andric     StringRef InstallName;
1455f757f3fSDimitry Andric     StringRef UUID;
1465f757f3fSDimitry Andric     StringRef Path;
1475f757f3fSDimitry Andric     FileType File = FileType::Invalid;
1485f757f3fSDimitry Andric     llvm::MachO::PackedVersion CurrentVersion;
1495f757f3fSDimitry Andric     llvm::MachO::PackedVersion CompatVersion;
1505f757f3fSDimitry Andric     uint8_t SwiftABI = 0;
1515f757f3fSDimitry Andric     bool TwoLevelNamespace = false;
1525f757f3fSDimitry Andric     bool AppExtensionSafe = false;
1535f757f3fSDimitry Andric     bool OSLibNotForSharedCache = false;
1545f757f3fSDimitry Andric   };
1555f757f3fSDimitry Andric 
1565f757f3fSDimitry Andric   /// Return reference to BinaryAttrs.
1575f757f3fSDimitry Andric   BinaryAttrs &getBinaryAttrs();
1585f757f3fSDimitry Andric 
1595f757f3fSDimitry Andric   /// Store any strings owned by RecordSlice into allocator and return back
1605f757f3fSDimitry Andric   /// reference to that.
1615f757f3fSDimitry Andric   StringRef copyString(StringRef String);
1625f757f3fSDimitry Andric 
1635f757f3fSDimitry Andric private:
1645f757f3fSDimitry Andric   const llvm::Triple TargetTriple;
1655f757f3fSDimitry Andric   // Hold tapi converted triple to avoid unecessary casts.
1665f757f3fSDimitry Andric   const Target TAPITarget;
1675f757f3fSDimitry Andric 
1685f757f3fSDimitry Andric   /// BumpPtrAllocator to store generated/copied strings.
1695f757f3fSDimitry Andric   llvm::BumpPtrAllocator StringAllocator;
1705f757f3fSDimitry Andric 
1715f757f3fSDimitry Andric   /// Promote linkage of requested record. It is no-op if linkage type is lower
1725f757f3fSDimitry Andric   /// than the current assignment.
1735f757f3fSDimitry Andric   ///
1745f757f3fSDimitry Andric   /// \param R The record to update.
1755f757f3fSDimitry Andric   /// \param L Linkage type to update to.
updateLinkage(Record * R,RecordLinkage L)1765f757f3fSDimitry Andric   void updateLinkage(Record *R, RecordLinkage L) {
1775f757f3fSDimitry Andric     R->Linkage = std::max(R->Linkage, L);
1785f757f3fSDimitry Andric   }
1795f757f3fSDimitry Andric 
180*cb14a3feSDimitry Andric   /// Update set flags of requested record.
181*cb14a3feSDimitry Andric   ///
182*cb14a3feSDimitry Andric   /// \param R The global record to update.
183*cb14a3feSDimitry Andric   /// \param F Flags to update to.
updateFlags(GlobalRecord * R,SymbolFlags F)184*cb14a3feSDimitry Andric   void updateFlags(GlobalRecord *R, SymbolFlags F) { R->Flags = F; }
185*cb14a3feSDimitry Andric 
1865f757f3fSDimitry Andric   RecordMap<GlobalRecord> Globals;
1875f757f3fSDimitry Andric   RecordMap<ObjCInterfaceRecord> Classes;
1885f757f3fSDimitry Andric   RecordMap<ObjCCategoryRecord, std::pair<StringRef, StringRef>> Categories;
1895f757f3fSDimitry Andric 
1905f757f3fSDimitry Andric   std::unique_ptr<BinaryAttrs> BA{nullptr};
1915f757f3fSDimitry Andric };
1925f757f3fSDimitry Andric 
193*cb14a3feSDimitry Andric using Records = llvm::SmallVector<std::shared_ptr<RecordsSlice>, 4>;
194*cb14a3feSDimitry Andric std::unique_ptr<InterfaceFile> convertToInterfaceFile(const Records &Slices);
195*cb14a3feSDimitry Andric 
1965f757f3fSDimitry Andric } // namespace MachO
1975f757f3fSDimitry Andric } // namespace llvm
1985f757f3fSDimitry Andric #endif // LLVM_TEXTAPI_RECORDSLICE_H
199