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