1111// ===----------------------------------------------------------------------===//
1212
1313#include " llvm/TextAPI/RecordsSlice.h"
14+ #include " llvm/ADT/SetVector.h"
1415#include " llvm/TextAPI/Record.h"
1516#include " llvm/TextAPI/Symbol.h"
1617#include < utility>
@@ -142,8 +143,10 @@ GlobalRecord *RecordsSlice::addGlobal(StringRef Name, RecordLinkage Linkage,
142143 if (Result.second )
143144 Result.first ->second =
144145 std::make_unique<GlobalRecord>(Name, Linkage, Flags, GV);
145- else
146+ else {
146147 updateLinkage (Result.first ->second .get (), Linkage);
148+ updateFlags (Result.first ->second .get (), Flags);
149+ }
147150 return Result.first ->second .get ();
148151}
149152
@@ -164,6 +167,19 @@ ObjCInterfaceRecord *RecordsSlice::addObjCInterface(StringRef Name,
164167
165168 return Result.first ->second .get ();
166169}
170+ SymbolFlags Record::mergeFlags (SymbolFlags Flags, RecordLinkage Linkage) {
171+ // Add Linkage properties into Flags.
172+ switch (Linkage) {
173+ case RecordLinkage::Rexported:
174+ Flags |= SymbolFlags::Rexported;
175+ return Flags;
176+ case RecordLinkage::Undefined:
177+ Flags |= SymbolFlags::Undefined;
178+ return Flags;
179+ default :
180+ return Flags;
181+ }
182+ }
167183
168184bool ObjCInterfaceRecord::addObjCCategory (ObjCCategoryRecord *Record) {
169185 auto Result = Categories.insert ({Name, Record});
@@ -188,11 +204,26 @@ ObjCCategoryRecord *RecordsSlice::addObjCCategory(StringRef ClassToExtend,
188204 return Result.first ->second .get ();
189205}
190206
207+ std::vector<ObjCIVarRecord *> ObjCContainerRecord::getObjCIVars () const {
208+ std::vector<ObjCIVarRecord *> Records;
209+ llvm::for_each (IVars,
210+ [&](auto &Record) { Records.push_back (Record.second .get ()); });
211+ return Records;
212+ }
213+
214+ std::vector<ObjCCategoryRecord *>
215+ ObjCInterfaceRecord::getObjCCategories () const {
216+ std::vector<ObjCCategoryRecord *> Records;
217+ llvm::for_each (Categories,
218+ [&](auto &Record) { Records.push_back (Record.second ); });
219+ return Records;
220+ }
221+
191222ObjCIVarRecord *ObjCContainerRecord::addObjCIVar (StringRef IVar,
192223 RecordLinkage Linkage) {
193224 auto Result = IVars.insert ({IVar, nullptr });
194225 if (Result.second )
195- Result.first ->second = std::make_unique<ObjCIVarRecord>(Name , Linkage);
226+ Result.first ->second = std::make_unique<ObjCIVarRecord>(IVar , Linkage);
196227 return Result.first ->second .get ();
197228}
198229
@@ -222,3 +253,88 @@ RecordsSlice::BinaryAttrs &RecordsSlice::getBinaryAttrs() {
222253 BA = std::make_unique<BinaryAttrs>();
223254 return *BA;
224255}
256+
257+ void RecordsSlice::visit (RecordVisitor &V) const {
258+ for (auto &G : Globals)
259+ V.visitGlobal (*G.second );
260+ for (auto &C : Classes)
261+ V.visitObjCInterface (*C.second );
262+ for (auto &Cat : Categories)
263+ V.visitObjCCategory (*Cat.second );
264+ }
265+
266+ static std::unique_ptr<InterfaceFile>
267+ createInterfaceFile (const Records &Slices, StringRef InstallName) {
268+ // Pickup symbols first.
269+ auto Symbols = std::make_unique<SymbolSet>();
270+ for (auto &S : Slices) {
271+ if (S->empty ())
272+ continue ;
273+ auto &BA = S->getBinaryAttrs ();
274+ if (BA.InstallName != InstallName)
275+ continue ;
276+
277+ SymbolConverter Converter (Symbols.get (), S->getTarget (),
278+ !BA.TwoLevelNamespace );
279+ S->visit (Converter);
280+ }
281+
282+ auto File = std::make_unique<InterfaceFile>(std::move (Symbols));
283+ File->setInstallName (InstallName);
284+ // Assign other attributes.
285+ for (auto &S : Slices) {
286+ if (S->empty ())
287+ continue ;
288+ auto &BA = S->getBinaryAttrs ();
289+ if (BA.InstallName != InstallName)
290+ continue ;
291+ const Target &Targ = S->getTarget ();
292+ File->addTarget (Targ);
293+ if (File->getFileType () == FileType::Invalid)
294+ File->setFileType (BA.File );
295+ if (BA.AppExtensionSafe && !File->isApplicationExtensionSafe ())
296+ File->setApplicationExtensionSafe ();
297+ if (BA.TwoLevelNamespace && !File->isTwoLevelNamespace ())
298+ File->setTwoLevelNamespace ();
299+ if (BA.OSLibNotForSharedCache && !File->isOSLibNotForSharedCache ())
300+ File->setOSLibNotForSharedCache ();
301+ if (File->getCurrentVersion ().empty ())
302+ File->setCurrentVersion (BA.CurrentVersion );
303+ if (File->getCompatibilityVersion ().empty ())
304+ File->setCompatibilityVersion (BA.CompatVersion );
305+ if (File->getSwiftABIVersion () == 0 )
306+ File->setSwiftABIVersion (BA.SwiftABI );
307+ if (File->getPath ().empty ())
308+ File->setPath (BA.Path );
309+ if (!BA.ParentUmbrella .empty ())
310+ File->addParentUmbrella (Targ, BA.ParentUmbrella );
311+ for (const auto &Client : BA.AllowableClients )
312+ File->addAllowableClient (Client, Targ);
313+ for (const auto &Lib : BA.RexportedLibraries )
314+ File->addReexportedLibrary (Lib, Targ);
315+ }
316+
317+ return File;
318+ }
319+
320+ std::unique_ptr<InterfaceFile>
321+ llvm::MachO::convertToInterfaceFile (const Records &Slices) {
322+ std::unique_ptr<InterfaceFile> File;
323+ if (Slices.empty ())
324+ return File;
325+
326+ SetVector<StringRef> InstallNames;
327+ for (auto &S : Slices) {
328+ auto Name = S->getBinaryAttrs ().InstallName ;
329+ if (Name.empty ())
330+ continue ;
331+ InstallNames.insert (Name);
332+ }
333+
334+ File = createInterfaceFile (Slices, *InstallNames.begin ());
335+ for (auto it = std::next (InstallNames.begin ()); it != InstallNames.end ();
336+ ++it)
337+ File->addDocument (createInterfaceFile (Slices, *it));
338+
339+ return File;
340+ }
0 commit comments