93 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// Implements the TAPI Record Visitor.10///11//===----------------------------------------------------------------------===//12 13#include "llvm/TextAPI/RecordVisitor.h"14 15using namespace llvm;16using namespace llvm::MachO;17 18RecordVisitor::~RecordVisitor() = default;19void RecordVisitor::visitObjCInterface(const ObjCInterfaceRecord &) {}20void RecordVisitor::visitObjCCategory(const ObjCCategoryRecord &) {}21 22static 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 30void 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 single42 // GlobalRecord, so continue to treat this symbol a generic global.43 Symbols->addGlobal(EncodeKind::GlobalSymbol, GR.getName(), GR.getFlags(),44 Targ);45}46 47void 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 59void 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 symbols69 // 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 90void SymbolConverter::visitObjCCategory(const ObjCCategoryRecord &Cat) {91 addIVars(Cat.getObjCIVars(), Cat.getSuperClassName());92}93