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