#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/APIAnalysis.h"
using namespace llvm;
static cl::OptionCategory APIAnalyzerCategory("api-analyzer options");
static cl::list<std::string> InputFilenames(cl::Positional,
cl::desc("<input bitcode file>"),
cl::value_desc("filename"),
cl::cat(APIAnalyzerCategory));
cl::opt<bool> ScanSelFromString("scan-strings",
cl::desc("Scan NSSelectorFromString calls"),
cl::init(false), cl::cat(APIAnalyzerCategory));
cl::opt<bool> ScanDLSym("scan-dlsym", cl::desc("Scan dlsym calls"),
cl::init(false), cl::cat(APIAnalyzerCategory));
cl::opt<bool> Demangle("demangle", cl::desc("Demangle symbols"),
cl::init(false), cl::cat(APIAnalyzerCategory));
cl::opt<bool> BitcodeOnly("bitcode-only", cl::desc("Only analyze bitcode"),
cl::init(false), cl::cat(APIAnalyzerCategory));
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
EnableDebugBuffering = true;
llvm_shutdown_obj Y;
InitializeAnalyzer();
cl::HideUnrelatedOptions(APIAnalyzerCategory);
cl::ParseCommandLineOptions(argc, argv, "llvm API analysis tool\n");
cl::PrintOptionValues();
APIAnalysisResult result;
APIAnalysisOptions options = {ScanSelFromString, ScanDLSym, Demangle,
BitcodeOnly};
int exit_code = 0;
for (auto file : InputFilenames) {
StringRef filename(file);
exit_code += AnalyzeFile(filename, result, options);
}
outs() << "--------------------------------------------------\n"
<< "Objective-C Selectors:\n"
<< "--------------------------------------------------\n";
for (auto &s : result.messageNames)
outs() << s.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Objective-C Class Names:\n"
<< "--------------------------------------------------\n";
for (auto &s : result.internalClassNames)
outs() << s.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Objective-C External Class Names:\n"
<< "--------------------------------------------------\n";
for (auto &s : result.externalClassNames)
outs() << s.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "External Function entries:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.externalFunctions)
outs() << d.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Internal Function entries:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.internalFunctions)
outs() << d.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "External Globals:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.externalGlobals)
outs() << d.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Internal Globals:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.internalGlobals)
outs() << d.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Asm Symbols:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.asmSymbols)
outs() << d << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Linked libraries:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.linkedLibraries)
outs() << d.first() << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Ordered libraries:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.orderedLibraries)
outs() << d << "\n";
outs() << "\n--------------------------------------------------\n"
<< "Obj-C Class Metadata:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.objCClasses) {
outs() << "*** " << d.first() << " : " << d.second.parentClass << " ***\n";
outs() << "Defined Class Methods:\n";
for (auto &m : d.second.internalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Class Methods:\n";
for (auto &m : d.second.externalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Defined Instance Methods:\n";
for (auto &m : d.second.internalInstanceMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Instance Methods:\n";
for (auto &m : d.second.externalInstanceMethods)
outs() << "\t" << m << "\n";
}
outs() << "\n--------------------------------------------------\n"
<< "Obj-C Protocol Metadata:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.objCProtocols) {
outs() << "*** " << d.first() << " ***\n";
outs() << "Defined Class Methods:\n";
for (auto &m : d.second.internalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Class Methods:\n";
for (auto &m : d.second.externalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Defined Instance Methods:\n";
for (auto &m : d.second.internalInstanceMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Instance Methods:\n";
for (auto &m : d.second.externalInstanceMethods)
outs() << "\t" << m << "\n";
}
outs() << "\n--------------------------------------------------\n"
<< "Obj-C Category Metadata:\n"
<< "--------------------------------------------------\n";
for (auto &d : result.objCCategories) {
outs() << "*** " << d.first.second << " (" << d.first.first << ") ***\n";
outs() << "Defined Class Methods:\n";
for (auto &m : d.second.internalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Class Methods:\n";
for (auto &m : d.second.externalClassMethods)
outs() << "\t" << m << "\n";
outs() << "Defined Instance Methods:\n";
for (auto &m : d.second.internalInstanceMethods)
outs() << "\t" << m << "\n";
outs() << "Declared Instance Methods:\n";
for (auto &m : d.second.externalInstanceMethods)
outs() << "\t" << m << "\n";
}
outs() << "\n--------------------------------------------------\n"
<< "Obj-C Potentially Defined Selectors:\n"
<< "--------------------------------------------------\n";
for (auto &s : result.potentiallyDefinedSelectors)
outs() << "\t" << s.first() << "\n";
return exit_code;
}