1 //===- RecordVisitor.cpp --------------------------------------------------===// 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 /// Implements the TAPI Record Visitor. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/TextAPI/RecordVisitor.h" 14 15 using namespace llvm; 16 using namespace llvm::MachO; 17 18 RecordVisitor::~RecordVisitor() {} 19 void RecordVisitor::visitObjCInterface(const ObjCInterfaceRecord &) {} 20 void RecordVisitor::visitObjCCategory(const ObjCCategoryRecord &) {} 21 22 static bool shouldSkipRecord(const Record &R, const bool RecordUndefs) { 23 if (R.isExported()) 24 return false; 25 26 // Skip non exported symbols unless for flat namespace libraries. 27 return !(RecordUndefs && R.isUndefined()); 28 } 29 30 void SymbolConverter::visitGlobal(const GlobalRecord &GR) { 31 auto [SymName, SymKind, InterfaceType] = parseSymbol(GR.getName()); 32 if (shouldSkipRecord(GR, RecordUndefs)) 33 return; 34 Symbols->addGlobal(SymKind, SymName, GR.getFlags(), Targ); 35 36 if (InterfaceType == ObjCIFSymbolKind::None) { 37 Symbols->addGlobal(SymKind, SymName, GR.getFlags(), Targ); 38 return; 39 } 40 41 // It is impossible to hold a complete ObjCInterface with a single 42 // GlobalRecord, so continue to treat this symbol a generic global. 43 Symbols->addGlobal(EncodeKind::GlobalSymbol, GR.getName(), GR.getFlags(), 44 Targ); 45 } 46 47 void SymbolConverter::addIVars(const ArrayRef<ObjCIVarRecord *> IVars, 48 StringRef ContainerName) { 49 for (auto *IV : IVars) { 50 if (shouldSkipRecord(*IV, RecordUndefs)) 51 continue; 52 std::string Name = 53 ObjCIVarRecord::createScopedName(ContainerName, IV->getName()); 54 Symbols->addGlobal(EncodeKind::ObjectiveCInstanceVariable, Name, 55 IV->getFlags(), Targ); 56 } 57 } 58 59 void SymbolConverter::visitObjCInterface(const ObjCInterfaceRecord &ObjCR) { 60 if (!shouldSkipRecord(ObjCR, RecordUndefs)) { 61 if (ObjCR.isCompleteInterface()) { 62 Symbols->addGlobal(EncodeKind::ObjectiveCClass, ObjCR.getName(), 63 ObjCR.getFlags(), Targ); 64 if (ObjCR.hasExceptionAttribute()) 65 Symbols->addGlobal(EncodeKind::ObjectiveCClassEHType, ObjCR.getName(), 66 ObjCR.getFlags(), Targ); 67 } else { 68 // Because there is not a complete interface, visit individual symbols 69 // instead. 70 if (ObjCR.isExportedSymbol(ObjCIFSymbolKind::EHType)) 71 Symbols->addGlobal(EncodeKind::GlobalSymbol, 72 (ObjC2EHTypePrefix + ObjCR.getName()).str(), 73 ObjCR.getFlags(), Targ); 74 if (ObjCR.isExportedSymbol(ObjCIFSymbolKind::Class)) 75 Symbols->addGlobal(EncodeKind::GlobalSymbol, 76 (ObjC2ClassNamePrefix + ObjCR.getName()).str(), 77 ObjCR.getFlags(), Targ); 78 if (ObjCR.isExportedSymbol(ObjCIFSymbolKind::MetaClass)) 79 Symbols->addGlobal(EncodeKind::GlobalSymbol, 80 (ObjC2MetaClassNamePrefix + ObjCR.getName()).str(), 81 ObjCR.getFlags(), Targ); 82 } 83 } 84 85 addIVars(ObjCR.getObjCIVars(), ObjCR.getName()); 86 for (const auto *Cat : ObjCR.getObjCCategories()) 87 addIVars(Cat->getObjCIVars(), ObjCR.getName()); 88 } 89 90 void SymbolConverter::visitObjCCategory(const ObjCCategoryRecord &Cat) { 91 addIVars(Cat.getObjCIVars(), Cat.getSuperClassName()); 92 } 93