13#include "llvm/Demangle/Demangle.h"
14#include "llvm/TextAPI/DylibReader.h"
50 return (Name.starts_with(
"_Z") || Name.starts_with(
"__Z") ||
51 Name.starts_with(
"___Z"));
58 char *
Result = llvm::itaniumDemangle(Name);
62 std::string Demangled(
Result);
67std::string DylibVerifier::getAnnotatedName(
const Record *R,
68 SymbolContext &SymCtx,
69 bool ValidSourceLoc) {
70 assert(!SymCtx.SymbolName.empty() &&
"Expected symbol name");
72 const StringRef SymbolName = SymCtx.SymbolName;
73 std::string PrettyName =
74 (Demangle && (SymCtx.Kind == EncodeKind::GlobalSymbol))
78 std::string Annotation;
79 if (R->isWeakDefined())
80 Annotation +=
"(weak-def) ";
81 if (R->isWeakReferenced())
82 Annotation +=
"(weak-ref) ";
83 if (R->isThreadLocalValue())
84 Annotation +=
"(tlv) ";
87 switch (SymCtx.ObjCIFKind) {
90 case ObjCIFSymbolKind::EHType:
91 return Annotation +
"Exception Type of " + PrettyName;
92 case ObjCIFSymbolKind::MetaClass:
93 return Annotation +
"Metaclass of " + PrettyName;
94 case ObjCIFSymbolKind::Class:
95 return Annotation +
"Class of " + PrettyName;
101 if (ValidSourceLoc) {
102 StringRef PrettyNameRef(PrettyName);
103 if ((SymCtx.Kind == EncodeKind::GlobalSymbol) &&
104 !
isCppMangled(SymbolName) && PrettyNameRef.starts_with(
"_"))
105 return Annotation + PrettyNameRef.drop_front(1).str();
106 return Annotation + PrettyName;
109 switch (SymCtx.Kind) {
110 case EncodeKind::GlobalSymbol:
111 return Annotation + PrettyName;
112 case EncodeKind::ObjectiveCInstanceVariable:
113 return Annotation +
"(ObjC IVar) " + PrettyName;
114 case EncodeKind::ObjectiveCClass:
115 return Annotation +
"(ObjC Class) " + PrettyName;
116 case EncodeKind::ObjectiveCClassEHType:
117 return Annotation +
"(ObjC Class EH) " + PrettyName;
120 llvm_unreachable(
"unexpected case for EncodeKind");
145 if (
const VarDecl *VD = cast<VarDecl>(
D))
154 case EncodeKind::GlobalSymbol:
155 return Slice->findGlobal(Name);
156 case EncodeKind::ObjectiveCInstanceVariable:
157 return Slice->findObjCIVar(Name.contains(
'.'), Name);
158 case EncodeKind::ObjectiveCClass:
159 case EncodeKind::ObjectiveCClassEHType:
160 return Slice->findObjCInterface(Name);
162 llvm_unreachable(
"unexpected end when finding record");
165void DylibVerifier::updateState(
Result State) {
169void DylibVerifier::addSymbol(
const Record *R, SymbolContext &SymCtx,
174 Exports->addGlobal(SymCtx.Kind, SymCtx.SymbolName, R->getFlags(), Targets);
177bool DylibVerifier::shouldIgnoreObsolete(
const Record *R, SymbolContext &SymCtx,
179 if (!SymCtx.FA->Avail.isObsoleted())
183 DeferredZipperedSymbols[SymCtx.SymbolName].emplace_back(ZipperedDeclSource{
188bool DylibVerifier::shouldIgnoreReexport(
const Record *R,
189 SymbolContext &SymCtx)
const {
190 StringRef SymName = SymCtx.SymbolName;
192 if (SymName.starts_with(
"$ld$"))
195 if (Reexports.empty())
199 if (!Lib.hasTarget(Ctx.
Target))
201 if (
auto Sym = Lib.getSymbol(SymCtx.Kind, SymName, SymCtx.ObjCIFKind))
202 if ((*Sym)->hasTarget(Ctx.
Target))
208bool DylibVerifier::shouldIgnoreInternalZipperedSymbol(
209 const Record *R,
const SymbolContext &SymCtx)
const {
213 return Exports->findSymbol(SymCtx.Kind, SymCtx.SymbolName,
214 SymCtx.ObjCIFKind) !=
nullptr;
217bool DylibVerifier::shouldIgnoreZipperedAvailability(
const Record *R,
218 SymbolContext &SymCtx) {
219 if (!(Zippered && SymCtx.FA->Avail.isUnavailable()))
224 DeferredZipperedSymbols[SymCtx.SymbolName].emplace_back(
225 ZipperedDeclSource{SymCtx.FA, SourceManagers.back().get(), Ctx.
Target});
230bool DylibVerifier::compareObjCInterfaceSymbols(
const Record *R,
231 SymbolContext &SymCtx,
233 const bool IsDeclVersionComplete =
234 ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::Class) ==
235 ObjCIFSymbolKind::Class) &&
236 ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::MetaClass) ==
237 ObjCIFSymbolKind::MetaClass);
239 const bool IsDylibVersionComplete = DR->isCompleteInterface();
242 if (IsDeclVersionComplete && IsDylibVersionComplete)
245 auto PrintDiagnostic = [&](
auto SymLinkage,
const Record *
Record,
246 StringRef SymName,
bool PrintAsWarning =
false) {
247 if (SymLinkage == RecordLinkage::Unknown)
249 Ctx.
Diag->
Report(SymCtx.FA->Loc, PrintAsWarning
250 ? diag::warn_library_missing_symbol
251 : diag::err_library_missing_symbol)
256 Ctx.
Diag->
Report(SymCtx.FA->Loc, PrintAsWarning
257 ? diag::warn_library_hidden_symbol
258 : diag::err_library_hidden_symbol)
263 if (IsDeclVersionComplete) {
267 if (!DR->isExportedSymbol(ObjCIFSymbolKind::Class)) {
268 SymCtx.ObjCIFKind = ObjCIFSymbolKind::Class;
269 PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::Class), R,
270 getAnnotatedName(R, SymCtx),
273 if (!DR->isExportedSymbol(ObjCIFSymbolKind::MetaClass)) {
274 SymCtx.ObjCIFKind = ObjCIFSymbolKind::MetaClass;
275 PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass), R,
276 getAnnotatedName(R, SymCtx),
282 if (DR->isExportedSymbol(SymCtx.ObjCIFKind)) {
283 if (!IsDylibVersionComplete) {
285 SymCtx.Kind = EncodeKind::GlobalSymbol;
286 SymCtx.SymbolName = R->getName();
293 PrintDiagnostic(DR->getLinkageForSymbol(SymCtx.ObjCIFKind), R,
299 SymbolContext &SymCtx,
302 if (R->isExported()) {
305 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_library_missing_symbol)
306 << getAnnotatedName(R, SymCtx);
310 if (DR->isInternal()) {
312 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_library_hidden_symbol)
313 << getAnnotatedName(R, SymCtx);
321 if ((R->isInternal() && !SymCtx.Inlined) && DR && DR->isExported()) {
329 if (shouldIgnoreInternalZipperedSymbol(R, SymCtx))
335 ID = diag::warn_header_hidden_symbol;
338 ID = diag::err_header_hidden_symbol;
342 Ctx.
Diag->
Report(SymCtx.FA->Loc, ID) << getAnnotatedName(R, SymCtx);
354 SymbolContext &SymCtx,
356 if (!SymCtx.FA->Avail.isUnavailable())
359 if (shouldIgnoreZipperedAvailability(R, SymCtx))
362 const bool IsDeclAvailable = SymCtx.FA->Avail.isUnavailable();
367 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::warn_header_availability_mismatch)
368 << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable;
373 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_availability_mismatch)
374 << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable;
380 llvm_unreachable(
"Unexpected verification mode symbol verification");
382 llvm_unreachable(
"Unexpected verification mode symbol verification");
385bool DylibVerifier::compareSymbolFlags(
const Record *R, SymbolContext &SymCtx,
387 if (DR->isThreadLocalValue() && !R->isThreadLocalValue()) {
389 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_dylib_symbol_flags_mismatch)
390 << getAnnotatedName(DR, SymCtx) << DR->isThreadLocalValue();
394 if (!DR->isThreadLocalValue() && R->isThreadLocalValue()) {
396 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_symbol_flags_mismatch)
397 << getAnnotatedName(R, SymCtx) << R->isThreadLocalValue();
402 if (DR->isWeakDefined() && !R->isWeakDefined()) {
404 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_dylib_symbol_flags_mismatch)
405 << getAnnotatedName(DR, SymCtx) << R->isWeakDefined();
409 if (!DR->isWeakDefined() && R->isWeakDefined()) {
411 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_symbol_flags_mismatch)
412 << getAnnotatedName(R, SymCtx) << R->isWeakDefined();
421 SymbolContext &SymCtx) {
425 if (R->isExported() && !SymCtx.FA->Avail.isUnavailable() &&
426 !SymCtx.FA->Avail.isObsoleted()) {
427 addSymbol(R, SymCtx);
432 if (shouldIgnoreReexport(R, SymCtx)) {
442 if (shouldIgnoreObsolete(R, SymCtx, DR)) {
448 if (SymCtx.FA->Avail.isUnavailable() && (!DR || DR->isInternal())) {
453 Result VisibilityCheck = compareVisibility(R, SymCtx, DR);
455 updateState(VisibilityCheck);
466 if (SymCtx.ObjCIFKind != ObjCIFSymbolKind::None) {
467 if (!compareObjCInterfaceSymbols(
468 R, SymCtx, Ctx.
DylibSlice->findObjCInterface(DR->getName()))) {
474 Result AvailabilityCheck = compareAvailability(R, SymCtx, DR);
476 updateState(AvailabilityCheck);
480 if (!compareSymbolFlags(R, SymCtx, DR)) {
485 addSymbol(R, SymCtx);
490bool DylibVerifier::canVerify() {
494void DylibVerifier::assignSlice(
const Target &
T) {
495 assert(
T == Ctx.
Target &&
"Active targets should match.");
502 Dylib, [&
T](
const auto &Slice) {
return T == Slice->getTarget(); });
504 assert(It != Dylib.end() &&
"Target slice should always exist.");
523 SourceManagers.push_back(std::move(SourceMgr));
529 const StringRef SuperClass) {
534 ObjCIVarRecord::createScopedName(SuperClass, R->getName());
536 return verifyImpl(R, SymCtx);
541 if (R->getLinkageForSymbol(ObjCIFSymbolKind::Class) != RecordLinkage::Unknown)
542 Result |= ObjCIFSymbolKind::Class;
543 if (R->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass) !=
544 RecordLinkage::Unknown)
545 Result |= ObjCIFSymbolKind::MetaClass;
546 if (R->getLinkageForSymbol(ObjCIFSymbolKind::EHType) !=
547 RecordLinkage::Unknown)
548 Result |= ObjCIFSymbolKind::EHType;
560 SymCtx.
Kind = R->hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType
561 : EncodeKind::ObjectiveCClass;
564 return verifyImpl(R, SymCtx);
576 SymCtx.
Kind = Sym.Kind;
578 SymCtx.
Inlined = R->isInlined();
579 return verifyImpl(R, SymCtx);
587 : getTargetTripleName(
Target));
590 if (
Loc &&
Loc->isValid())
591 llvm::errs() <<
Loc->File <<
":" <<
Loc->Line <<
":" << 0 <<
": ";
603 (Name.starts_with(
"__ZTI") || Name.starts_with(
"__ZTS")));
605void DylibVerifier::visitSymbolInDylib(
const Record &R, SymbolContext &SymCtx) {
607 if (R.isUndefined()) {
613 if (R.isInternal()) {
620 const StringRef SymbolName(SymCtx.SymbolName);
621 if (
const Symbol *Sym = Exports->findSymbol(SymCtx.Kind, SymCtx.SymbolName,
622 SymCtx.ObjCIFKind)) {
623 if (Sym->hasArchitecture(Ctx.
Target.Arch)) {
629 const bool IsLinkerSymbol = SymbolName.starts_with(
"$ld$");
631 if (R.isVerified()) {
635 auto It = DeferredZipperedSymbols.find(SymCtx.SymbolName);
636 if (It == DeferredZipperedSymbols.end()) {
642 for (
const ZipperedDeclSource &ZSource : It->second) {
643 if (ZSource.FA->Avail.isObsoleted()) {
647 if (ZSource.T.Arch != Ctx.
Target.Arch)
649 Locs.emplace_back(ZSource);
651 assert(Locs.size() == 2 &&
"Expected two decls for zippered symbol");
654 for (
const ZipperedDeclSource &ZSource : Locs) {
658 DiagID = diag::err_header_availability_mismatch;
661 DiagID = diag::warn_header_availability_mismatch;
668 Ctx.
Diag->
Report(diag::warn_target) << getTargetTripleName(ZSource.T);
670 << getAnnotatedName(&R, SymCtx) << ZSource.FA->Avail.isUnavailable()
671 << ZSource.FA->Avail.isUnavailable();
681 if (Aliases.count({SymbolName.str(), SymCtx.Kind})) {
690 accumulateSrcLocForDylibSymbols();
695 if (IsLinkerSymbol) {
698 Ctx.
Diag->
Report(diag::err_header_symbol_missing)
699 << getAnnotatedName(&R, SymCtx,
Loc.isValid());
710 Ctx.
Diag->
Report(diag::err_header_symbol_missing)
711 << getAnnotatedName(&R, SymCtx,
Loc.isValid());
723 Ctx.
Diag->
Report(diag::warn_header_symbol_missing)
724 << getAnnotatedName(&R, SymCtx,
Loc.isValid());
738 SymbolContext SymCtx;
740 SymCtx.SymbolName = Sym.Name;
741 SymCtx.Kind = Sym.Kind;
742 visitSymbolInDylib(R, SymCtx);
746 const StringRef Super) {
747 SymbolContext SymCtx;
748 SymCtx.SymbolName = ObjCIVarRecord::createScopedName(Super, R.getName());
749 SymCtx.Kind = EncodeKind::ObjectiveCInstanceVariable;
750 visitSymbolInDylib(R, SymCtx);
753void DylibVerifier::accumulateSrcLocForDylibSymbols() {
754 if (DSYMPath.empty())
757 assert(DWARFCtx !=
nullptr &&
"Expected an initialized DWARFContext");
762 DylibReader::accumulateSourceLocFromDSYM(DSYMPath, Ctx.
Target);
766 SymbolContext SymCtx;
767 SymCtx.SymbolName = R.getName();
769 if (SymCtx.ObjCIFKind > ObjCIFSymbolKind::EHType) {
770 if (R.hasExceptionAttribute()) {
771 SymCtx.Kind = EncodeKind::ObjectiveCClassEHType;
772 visitSymbolInDylib(R, SymCtx);
774 SymCtx.Kind = EncodeKind::ObjectiveCClass;
775 visitSymbolInDylib(R, SymCtx);
777 SymCtx.Kind = R.hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType
778 : EncodeKind::ObjectiveCClass;
779 visitSymbolInDylib(R, SymCtx);
783 visitObjCIVar(*IV, R.getName());
788 visitObjCIVar(*IV, R.getSuperClassName());
794 assert(!Dylib.empty() &&
"No binary to verify against");
797 DWARFCtx = &DWARFInfo;
798 Ctx.
Target =
Target(Architecture::AK_unknown, PlatformType::PLATFORM_UNKNOWN);
799 for (std::shared_ptr<RecordsSlice> Slice : Dylib) {
800 if (Ctx.
Target.Arch == Slice->getTarget().Arch)
804 Ctx.
Target = Slice->getTarget();
817 assert(!Dylib.empty() &&
"Need dylib to verify.");
824 for (
const std::shared_ptr<RecordsSlice> &RS : Dylib) {
825 DylibTargets.push_back(RS->getTarget());
827 for (
const StringRef LibName : BinInfo.RexportedLibraries)
828 DylibReexports[LibName].set(DylibTargets.back().Arch);
829 for (
const StringRef LibName : BinInfo.AllowableClients)
830 DylibClients[LibName].set(DylibTargets.back().Arch);
832 if (FT >= FileType::TBD_V5)
833 for (
const StringRef Name : BinInfo.RPaths)
834 DylibRPaths[Name].set(DylibTargets.back().Arch);
840 if (ProvidedArchs != DylibArchs) {
841 Ctx.
Diag->
Report(diag::err_architecture_mismatch)
842 << ProvidedArchs << DylibArchs;
845 auto ProvidedPlatforms = mapToPlatformVersionSet(ProvidedTargets);
846 auto DylibPlatforms = mapToPlatformVersionSet(DylibTargets);
847 if (ProvidedPlatforms != DylibPlatforms) {
848 const bool DiffMinOS =
849 mapToPlatformSet(ProvidedTargets) == mapToPlatformSet(DylibTargets);
851 Ctx.
Diag->
Report(diag::warn_platform_mismatch)
852 << ProvidedPlatforms << DylibPlatforms;
855 << ProvidedPlatforms << DylibPlatforms;
862 const BinaryAttrs &DylibBA = (*Dylib.begin())->getBinaryAttrs();
864 if (ProvidedBA.InstallName != DylibBA.InstallName) {
865 Ctx.
Diag->
Report(diag::err_install_name_mismatch)
866 << ProvidedBA.InstallName << DylibBA.InstallName;
870 if (ProvidedBA.CurrentVersion != DylibBA.CurrentVersion) {
871 Ctx.
Diag->
Report(diag::err_current_version_mismatch)
872 << ProvidedBA.CurrentVersion << DylibBA.CurrentVersion;
876 if (ProvidedBA.CompatVersion != DylibBA.CompatVersion) {
877 Ctx.
Diag->
Report(diag::err_compatibility_version_mismatch)
878 << ProvidedBA.CompatVersion << DylibBA.CompatVersion;
882 if (ProvidedBA.AppExtensionSafe != DylibBA.AppExtensionSafe) {
883 Ctx.
Diag->
Report(diag::err_appextension_safe_mismatch)
884 << (ProvidedBA.AppExtensionSafe ?
"true" :
"false")
885 << (DylibBA.AppExtensionSafe ?
"true" :
"false");
889 if (!DylibBA.TwoLevelNamespace) {
890 Ctx.
Diag->
Report(diag::err_no_twolevel_namespace);
894 if (ProvidedBA.OSLibNotForSharedCache != DylibBA.OSLibNotForSharedCache) {
895 Ctx.
Diag->
Report(diag::err_shared_cache_eligiblity_mismatch)
896 << (ProvidedBA.OSLibNotForSharedCache ?
"true" :
"false")
897 << (DylibBA.OSLibNotForSharedCache ?
"true" :
"false");
901 if (ProvidedBA.ParentUmbrella.empty() && !DylibBA.ParentUmbrella.empty()) {
902 Ctx.
Diag->
Report(diag::err_parent_umbrella_missing)
903 <<
"installAPI option" << DylibBA.ParentUmbrella;
907 if (!ProvidedBA.ParentUmbrella.empty() && DylibBA.ParentUmbrella.empty()) {
908 Ctx.
Diag->
Report(diag::err_parent_umbrella_missing)
909 <<
"binary file" << ProvidedBA.ParentUmbrella;
913 if ((!ProvidedBA.ParentUmbrella.empty()) &&
914 (ProvidedBA.ParentUmbrella != DylibBA.ParentUmbrella)) {
915 Ctx.
Diag->
Report(diag::err_parent_umbrella_mismatch)
916 << ProvidedBA.ParentUmbrella << DylibBA.ParentUmbrella;
920 auto CompareLibraries = [&](
const LibAttrs &Provided,
const LibAttrs &Dylib,
921 unsigned DiagID_missing,
unsigned DiagID_mismatch,
923 if (Provided == Dylib)
926 for (
const llvm::StringMapEntry<ArchitectureSet> &PAttr : Provided) {
927 const auto DAttrIt = Dylib.find(PAttr.getKey());
928 if (DAttrIt == Dylib.end()) {
929 Ctx.
Diag->
Report(DiagID_missing) <<
"binary file" << PAttr;
934 if (PAttr.getValue() != DAttrIt->getValue()) {
935 Ctx.
Diag->
Report(DiagID_mismatch) << PAttr << *DAttrIt;
941 for (
const llvm::StringMapEntry<ArchitectureSet> &DAttr : Dylib) {
942 const auto PAttrIt = Provided.find(DAttr.getKey());
943 if (PAttrIt == Provided.end()) {
944 Ctx.
Diag->
Report(DiagID_missing) <<
"installAPI option" << DAttr;
950 if (PAttrIt->getValue() != DAttr.getValue()) {
952 llvm_unreachable(
"this case was already covered above.");
958 if (!CompareLibraries(ProvidedReexports, DylibReexports,
959 diag::err_reexported_libraries_missing,
960 diag::err_reexported_libraries_mismatch))
963 if (!CompareLibraries(ProvidedClients, DylibClients,
964 diag::err_allowable_clients_missing,
965 diag::err_allowable_clients_mismatch))
968 if (FT >= FileType::TBD_V5) {
973 if (!ProvidedBA.InstallName.ends_with(
"_asan")) {
974 if (!CompareLibraries(ProvidedRPaths, DylibRPaths,
975 diag::warn_rpaths_missing,
976 diag::warn_rpaths_mismatch,
986 for (
const auto &[Alias,
Base] : Aliases) {
989 if (
const Symbol *Sym = Exports->findSymbol(
Base.second,
Base.first)) {
990 Flags = Sym->getFlags();
991 Targets = {Sym->targets().begin(), Sym->targets().end()};
994 Record R(Alias.first, RecordLinkage::Exported, Flags);
997 SymCtx.
Kind = Alias.second;
998 addSymbol(&R, SymCtx, std::move(Targets));
1001 return std::move(Exports);
llvm::MachO::ObjCIVarRecord ObjCIVarRecord
llvm::MachO::SymbolFlags SymbolFlags
llvm::MachO::RecordLoc RecordLoc
llvm::MachO::InterfaceFile InterfaceFile
llvm::MachO::ObjCCategoryRecord ObjCCategoryRecord
llvm::MachO::GlobalRecord GlobalRecord
llvm::MachO::ArchitectureSet ArchitectureSet
llvm::MachO::EncodeKind EncodeKind
llvm::MachO::ObjCInterfaceRecord ObjCInterfaceRecord
llvm::MachO::ObjCIFSymbolKind ObjCIFSymbolKind
llvm::MachO::FileType FileType
llvm::MachO::Target Target
llvm::MachO::RecordsSlice::BinaryAttrs BinaryAttrs
llvm::MachO::Record Record
llvm::MachO::TargetList TargetList
llvm::MachO::SimpleSymbol SimpleSymbol
Decl - This represents one declaration (or definition), e.g.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setSourceManager(SourceManager *SrcMgr)
SourceManager & getSourceManager() const
Represents a function declaration or definition.
Represents a variable declaration or definition.
Result verify(GlobalRecord *R, const FrontendAttrs *FA)
Result getState() const
Get result of verification.
void setSourceManager(IntrusiveRefCntPtr< SourceManager > SourceMgr)
Set different source managers to the same diagnostics engine.
std::unique_ptr< SymbolSet > takeExports()
Release ownership over exports.
bool verifyBinaryAttrs(const ArrayRef< Target > ProvidedTargets, const BinaryAttrs &ProvidedBA, const LibAttrs &ProvidedReexports, const LibAttrs &ProvidedClients, const LibAttrs &ProvidedRPaths, const FileType &FT)
Compare and report the attributes represented as load commands in the dylib to the attributes provide...
void setTarget(const Target &T)
Initialize target for verification.
Result verifyRemainingSymbols()
Record * findRecordFromSlice(const RecordsSlice *Slice, StringRef Name, EncodeKind Kind)
llvm::StringMap< ArchitectureSet > LibAttrs
static bool isCppMangled(StringRef Name)
static std::string demangle(StringRef Name)
static DylibVerifier::Result updateResult(const DylibVerifier::Result Prev, const DylibVerifier::Result Curr)
static ObjCIFSymbolKind assignObjCIFSymbolKind(const ObjCInterfaceRecord *R)
static bool shouldIgnorePrivateExternAttr(const Decl *D)
std::vector< ZipperedDeclSource > ZipperedDeclSources
static bool shouldIgnoreCpp(StringRef Name, bool IsWeakDef)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
DylibReader::SymbolToSourceLocMap SourceLocs
Metadata stored about a mapping of a declaration to a symbol.
ObjCIFSymbolKind ObjCIFKind
bool DiscoveredFirstError
void emitDiag(llvm::function_ref< void()> Report, RecordLoc *Loc=nullptr)
RecordsSlice * DylibSlice
llvm::MachO::Target Target
Frontend information captured about records.