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 if (Reexports.empty())
193 for (
const InterfaceFile &Lib : Reexports) {
194 if (!Lib.hasTarget(Ctx.
Target))
197 Lib.getSymbol(SymCtx.Kind, SymCtx.SymbolName, SymCtx.ObjCIFKind))
198 if ((*Sym)->hasTarget(Ctx.
Target))
204bool DylibVerifier::shouldIgnoreInternalZipperedSymbol(
205 const Record *R,
const SymbolContext &SymCtx)
const {
209 return Exports->findSymbol(SymCtx.Kind, SymCtx.SymbolName,
210 SymCtx.ObjCIFKind) !=
nullptr;
213bool DylibVerifier::shouldIgnoreZipperedAvailability(
const Record *R,
214 SymbolContext &SymCtx) {
215 if (!(Zippered && SymCtx.FA->Avail.isUnavailable()))
220 DeferredZipperedSymbols[SymCtx.SymbolName].emplace_back(
221 ZipperedDeclSource{SymCtx.FA, SourceManagers.back().get(), Ctx.
Target});
226bool DylibVerifier::compareObjCInterfaceSymbols(
const Record *R,
227 SymbolContext &SymCtx,
229 const bool IsDeclVersionComplete =
230 ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::Class) ==
231 ObjCIFSymbolKind::Class) &&
232 ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::MetaClass) ==
233 ObjCIFSymbolKind::MetaClass);
235 const bool IsDylibVersionComplete = DR->isCompleteInterface();
238 if (IsDeclVersionComplete && IsDylibVersionComplete)
241 auto PrintDiagnostic = [&](
auto SymLinkage,
const Record *
Record,
242 StringRef SymName,
bool PrintAsWarning =
false) {
243 if (SymLinkage == RecordLinkage::Unknown)
245 Ctx.
Diag->
Report(SymCtx.FA->Loc, PrintAsWarning
246 ? diag::warn_library_missing_symbol
247 : diag::err_library_missing_symbol)
252 Ctx.
Diag->
Report(SymCtx.FA->Loc, PrintAsWarning
253 ? diag::warn_library_hidden_symbol
254 : diag::err_library_hidden_symbol)
259 if (IsDeclVersionComplete) {
263 if (!DR->isExportedSymbol(ObjCIFSymbolKind::Class)) {
264 SymCtx.ObjCIFKind = ObjCIFSymbolKind::Class;
265 PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::Class), R,
266 getAnnotatedName(R, SymCtx),
269 if (!DR->isExportedSymbol(ObjCIFSymbolKind::MetaClass)) {
270 SymCtx.ObjCIFKind = ObjCIFSymbolKind::MetaClass;
271 PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass), R,
272 getAnnotatedName(R, SymCtx),
278 if (DR->isExportedSymbol(SymCtx.ObjCIFKind)) {
279 if (!IsDylibVersionComplete) {
281 SymCtx.Kind = EncodeKind::GlobalSymbol;
282 SymCtx.SymbolName = R->getName();
289 PrintDiagnostic(DR->getLinkageForSymbol(SymCtx.ObjCIFKind), R,
295 SymbolContext &SymCtx,
298 if (R->isExported()) {
301 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_library_missing_symbol)
302 << getAnnotatedName(R, SymCtx);
306 if (DR->isInternal()) {
308 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_library_hidden_symbol)
309 << getAnnotatedName(R, SymCtx);
317 if ((R->isInternal() && !SymCtx.Inlined) && DR && DR->isExported()) {
325 if (shouldIgnoreInternalZipperedSymbol(R, SymCtx))
331 ID = diag::warn_header_hidden_symbol;
334 ID = diag::err_header_hidden_symbol;
338 Ctx.
Diag->
Report(SymCtx.FA->Loc, ID) << getAnnotatedName(R, SymCtx);
350 SymbolContext &SymCtx,
352 if (!SymCtx.FA->Avail.isUnavailable())
355 if (shouldIgnoreZipperedAvailability(R, SymCtx))
358 const bool IsDeclAvailable = SymCtx.FA->Avail.isUnavailable();
363 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::warn_header_availability_mismatch)
364 << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable;
369 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_availability_mismatch)
370 << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable;
376 llvm_unreachable(
"Unexpected verification mode symbol verification");
378 llvm_unreachable(
"Unexpected verification mode symbol verification");
381bool DylibVerifier::compareSymbolFlags(
const Record *R, SymbolContext &SymCtx,
383 if (DR->isThreadLocalValue() && !R->isThreadLocalValue()) {
385 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_dylib_symbol_flags_mismatch)
386 << getAnnotatedName(DR, SymCtx) << DR->isThreadLocalValue();
390 if (!DR->isThreadLocalValue() && R->isThreadLocalValue()) {
392 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_symbol_flags_mismatch)
393 << getAnnotatedName(R, SymCtx) << R->isThreadLocalValue();
398 if (DR->isWeakDefined() && !R->isWeakDefined()) {
400 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_dylib_symbol_flags_mismatch)
401 << getAnnotatedName(DR, SymCtx) << R->isWeakDefined();
405 if (!DR->isWeakDefined() && R->isWeakDefined()) {
407 Ctx.
Diag->
Report(SymCtx.FA->Loc, diag::err_header_symbol_flags_mismatch)
408 << getAnnotatedName(R, SymCtx) << R->isWeakDefined();
417 SymbolContext &SymCtx) {
421 if (R->isExported() && !SymCtx.FA->Avail.isUnavailable() &&
422 !SymCtx.FA->Avail.isObsoleted()) {
423 addSymbol(R, SymCtx);
428 if (shouldIgnoreReexport(R, SymCtx)) {
438 if (shouldIgnoreObsolete(R, SymCtx, DR)) {
444 if (SymCtx.FA->Avail.isUnavailable() && (!DR || DR->isInternal())) {
449 Result VisibilityCheck = compareVisibility(R, SymCtx, DR);
451 updateState(VisibilityCheck);
462 if (SymCtx.ObjCIFKind != ObjCIFSymbolKind::None) {
463 if (!compareObjCInterfaceSymbols(
464 R, SymCtx, Ctx.
DylibSlice->findObjCInterface(DR->getName()))) {
470 Result AvailabilityCheck = compareAvailability(R, SymCtx, DR);
472 updateState(AvailabilityCheck);
476 if (!compareSymbolFlags(R, SymCtx, DR)) {
481 addSymbol(R, SymCtx);
486bool DylibVerifier::canVerify() {
490void DylibVerifier::assignSlice(
const Target &
T) {
491 assert(
T == Ctx.
Target &&
"Active targets should match.");
498 Dylib, [&
T](
const auto &Slice) {
return T == Slice->getTarget(); });
500 assert(It != Dylib.end() &&
"Target slice should always exist.");
519 SourceManagers.push_back(std::move(SourceMgr));
525 const StringRef SuperClass) {
529 std::string FullName =
530 ObjCIVarRecord::createScopedName(SuperClass, R->getName());
531 SymbolContext SymCtx{FullName, EncodeKind::ObjectiveCInstanceVariable, FA};
532 return verifyImpl(R, SymCtx);
537 if (R->getLinkageForSymbol(ObjCIFSymbolKind::Class) != RecordLinkage::Unknown)
538 Result |= ObjCIFSymbolKind::Class;
539 if (R->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass) !=
540 RecordLinkage::Unknown)
541 Result |= ObjCIFSymbolKind::MetaClass;
542 if (R->getLinkageForSymbol(ObjCIFSymbolKind::EHType) !=
543 RecordLinkage::Unknown)
544 Result |= ObjCIFSymbolKind::EHType;
556 SymCtx.
Kind = R->hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType
557 : EncodeKind::ObjectiveCClass;
560 return verifyImpl(R, SymCtx);
572 SymCtx.
Kind = Sym.Kind;
574 SymCtx.
Inlined = R->isInlined();
575 return verifyImpl(R, SymCtx);
583 : getTargetTripleName(
Target));
586 if (Loc && Loc->isValid())
587 llvm::errs() << Loc->File <<
":" << Loc->Line <<
":" << 0 <<
": ";
599 (Name.starts_with(
"__ZTI") || Name.starts_with(
"__ZTS")));
601void DylibVerifier::visitSymbolInDylib(
const Record &R, SymbolContext &SymCtx) {
603 if (R.isUndefined()) {
609 if (R.isInternal()) {
616 const StringRef SymbolName(SymCtx.SymbolName);
617 if (
const Symbol *Sym = Exports->findSymbol(SymCtx.Kind, SymCtx.SymbolName,
618 SymCtx.ObjCIFKind)) {
619 if (Sym->hasArchitecture(Ctx.
Target.Arch)) {
625 const bool IsLinkerSymbol = SymbolName.starts_with(
"$ld$");
627 if (R.isVerified()) {
631 auto It = DeferredZipperedSymbols.find(SymCtx.SymbolName);
632 if (It == DeferredZipperedSymbols.end()) {
638 for (
const ZipperedDeclSource &ZSource : It->second) {
639 if (ZSource.FA->Avail.isObsoleted()) {
643 if (ZSource.T.Arch != Ctx.
Target.Arch)
645 Locs.emplace_back(ZSource);
647 assert(Locs.size() == 2 &&
"Expected two decls for zippered symbol");
650 for (
const ZipperedDeclSource &ZSource : Locs) {
654 DiagID = diag::err_header_availability_mismatch;
657 DiagID = diag::warn_header_availability_mismatch;
664 Ctx.
Diag->
Report(diag::warn_target) << getTargetTripleName(ZSource.T);
666 << getAnnotatedName(&R, SymCtx) << ZSource.FA->Avail.isUnavailable()
667 << ZSource.FA->Avail.isUnavailable();
677 if (Aliases.count({SymbolName.str(), SymCtx.Kind})) {
686 accumulateSrcLocForDylibSymbols();
691 if (IsLinkerSymbol) {
694 Ctx.
Diag->
Report(diag::err_header_symbol_missing)
695 << getAnnotatedName(&R, SymCtx, Loc.isValid());
706 Ctx.
Diag->
Report(diag::err_header_symbol_missing)
707 << getAnnotatedName(&R, SymCtx, Loc.isValid());
719 Ctx.
Diag->
Report(diag::warn_header_symbol_missing)
720 << getAnnotatedName(&R, SymCtx, Loc.isValid());
734 SymbolContext SymCtx;
736 SymCtx.SymbolName = Sym.Name;
737 SymCtx.Kind = Sym.Kind;
738 visitSymbolInDylib(R, SymCtx);
742 const StringRef Super) {
743 SymbolContext SymCtx;
744 SymCtx.SymbolName = ObjCIVarRecord::createScopedName(Super, R.getName());
745 SymCtx.Kind = EncodeKind::ObjectiveCInstanceVariable;
746 visitSymbolInDylib(R, SymCtx);
749void DylibVerifier::accumulateSrcLocForDylibSymbols() {
750 if (DSYMPath.empty())
753 assert(DWARFCtx !=
nullptr &&
"Expected an initialized DWARFContext");
758 DylibReader::accumulateSourceLocFromDSYM(DSYMPath, Ctx.
Target);
762 SymbolContext SymCtx;
763 SymCtx.SymbolName = R.getName();
765 if (SymCtx.ObjCIFKind > ObjCIFSymbolKind::EHType) {
766 if (R.hasExceptionAttribute()) {
767 SymCtx.Kind = EncodeKind::ObjectiveCClassEHType;
768 visitSymbolInDylib(R, SymCtx);
770 SymCtx.Kind = EncodeKind::ObjectiveCClass;
771 visitSymbolInDylib(R, SymCtx);
773 SymCtx.Kind = R.hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType
774 : EncodeKind::ObjectiveCClass;
775 visitSymbolInDylib(R, SymCtx);
779 visitObjCIVar(*IV, R.getName());
784 visitObjCIVar(*IV, R.getSuperClassName());
790 assert(!Dylib.empty() &&
"No binary to verify against");
793 DWARFCtx = &DWARFInfo;
794 Ctx.
Target =
Target(Architecture::AK_unknown, PlatformType::PLATFORM_UNKNOWN);
795 for (std::shared_ptr<RecordsSlice> Slice : Dylib) {
796 if (Ctx.
Target.Arch == Slice->getTarget().Arch)
800 Ctx.
Target = Slice->getTarget();
813 assert(!Dylib.empty() &&
"Need dylib to verify.");
820 for (
const std::shared_ptr<RecordsSlice> &RS : Dylib) {
821 DylibTargets.push_back(RS->getTarget());
823 for (
const StringRef LibName : BinInfo.RexportedLibraries)
824 DylibReexports[LibName].set(DylibTargets.back().Arch);
825 for (
const StringRef LibName : BinInfo.AllowableClients)
826 DylibClients[LibName].set(DylibTargets.back().Arch);
828 if (FT >= FileType::TBD_V5)
829 for (
const StringRef Name : BinInfo.RPaths)
830 DylibRPaths[Name].set(DylibTargets.back().Arch);
836 if (ProvidedArchs != DylibArchs) {
837 Ctx.
Diag->
Report(diag::err_architecture_mismatch)
838 << ProvidedArchs << DylibArchs;
841 auto ProvidedPlatforms = mapToPlatformVersionSet(ProvidedTargets);
842 auto DylibPlatforms = mapToPlatformVersionSet(DylibTargets);
843 if (ProvidedPlatforms != DylibPlatforms) {
844 const bool DiffMinOS =
845 mapToPlatformSet(ProvidedTargets) == mapToPlatformSet(DylibTargets);
847 Ctx.
Diag->
Report(diag::warn_platform_mismatch)
848 << ProvidedPlatforms << DylibPlatforms;
851 << ProvidedPlatforms << DylibPlatforms;
858 const BinaryAttrs &DylibBA = (*Dylib.begin())->getBinaryAttrs();
860 if (ProvidedBA.InstallName != DylibBA.InstallName) {
861 Ctx.
Diag->
Report(diag::err_install_name_mismatch)
862 << ProvidedBA.InstallName << DylibBA.InstallName;
866 if (ProvidedBA.CurrentVersion != DylibBA.CurrentVersion) {
867 Ctx.
Diag->
Report(diag::err_current_version_mismatch)
868 << ProvidedBA.CurrentVersion << DylibBA.CurrentVersion;
872 if (ProvidedBA.CompatVersion != DylibBA.CompatVersion) {
873 Ctx.
Diag->
Report(diag::err_compatibility_version_mismatch)
874 << ProvidedBA.CompatVersion << DylibBA.CompatVersion;
878 if (ProvidedBA.AppExtensionSafe != DylibBA.AppExtensionSafe) {
879 Ctx.
Diag->
Report(diag::err_appextension_safe_mismatch)
880 << (ProvidedBA.AppExtensionSafe ?
"true" :
"false")
881 << (DylibBA.AppExtensionSafe ?
"true" :
"false");
885 if (!DylibBA.TwoLevelNamespace) {
886 Ctx.
Diag->
Report(diag::err_no_twolevel_namespace);
890 if (ProvidedBA.OSLibNotForSharedCache != DylibBA.OSLibNotForSharedCache) {
891 Ctx.
Diag->
Report(diag::err_shared_cache_eligiblity_mismatch)
892 << (ProvidedBA.OSLibNotForSharedCache ?
"true" :
"false")
893 << (DylibBA.OSLibNotForSharedCache ?
"true" :
"false");
897 if (ProvidedBA.ParentUmbrella.empty() && !DylibBA.ParentUmbrella.empty()) {
898 Ctx.
Diag->
Report(diag::err_parent_umbrella_missing)
899 <<
"installAPI option" << DylibBA.ParentUmbrella;
903 if (!ProvidedBA.ParentUmbrella.empty() && DylibBA.ParentUmbrella.empty()) {
904 Ctx.
Diag->
Report(diag::err_parent_umbrella_missing)
905 <<
"binary file" << ProvidedBA.ParentUmbrella;
909 if ((!ProvidedBA.ParentUmbrella.empty()) &&
910 (ProvidedBA.ParentUmbrella != DylibBA.ParentUmbrella)) {
911 Ctx.
Diag->
Report(diag::err_parent_umbrella_mismatch)
912 << ProvidedBA.ParentUmbrella << DylibBA.ParentUmbrella;
916 auto CompareLibraries = [&](
const LibAttrs &Provided,
const LibAttrs &Dylib,
917 unsigned DiagID_missing,
unsigned DiagID_mismatch,
919 if (Provided == Dylib)
922 for (
const llvm::StringMapEntry<ArchitectureSet> &PAttr : Provided) {
923 const auto DAttrIt = Dylib.find(PAttr.getKey());
924 if (DAttrIt == Dylib.end()) {
925 Ctx.
Diag->
Report(DiagID_missing) <<
"binary file" << PAttr;
930 if (PAttr.getValue() != DAttrIt->getValue()) {
931 Ctx.
Diag->
Report(DiagID_mismatch) << PAttr << *DAttrIt;
937 for (
const llvm::StringMapEntry<ArchitectureSet> &DAttr : Dylib) {
938 const auto PAttrIt = Provided.find(DAttr.getKey());
939 if (PAttrIt == Provided.end()) {
940 Ctx.
Diag->
Report(DiagID_missing) <<
"installAPI option" << DAttr;
946 if (PAttrIt->getValue() != DAttr.getValue()) {
948 llvm_unreachable(
"this case was already covered above.");
954 if (!CompareLibraries(ProvidedReexports, DylibReexports,
955 diag::err_reexported_libraries_missing,
956 diag::err_reexported_libraries_mismatch))
959 if (!CompareLibraries(ProvidedClients, DylibClients,
960 diag::err_allowable_clients_missing,
961 diag::err_allowable_clients_mismatch))
964 if (FT >= FileType::TBD_V5) {
969 if (!ProvidedBA.InstallName.ends_with(
"_asan")) {
970 if (!CompareLibraries(ProvidedRPaths, DylibRPaths,
971 diag::warn_rpaths_missing,
972 diag::warn_rpaths_mismatch,
982 for (
const auto &[Alias,
Base] : Aliases) {
985 if (
const Symbol *Sym = Exports->findSymbol(
Base.second,
Base.first)) {
986 Flags = Sym->getFlags();
987 Targets = {Sym->targets().begin(), Sym->targets().end()};
990 Record R(Alias.first, RecordLinkage::Exported, Flags);
993 SymCtx.
Kind = Alias.second;
994 addSymbol(&R, SymCtx, std::move(Targets));
997 return std::move(Exports);
llvm::MachO::ObjCIVarRecord ObjCIVarRecord
llvm::MachO::SymbolFlags SymbolFlags
llvm::MachO::RecordLoc RecordLoc
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.