llvm-diff.cpp revision 221337
1254721Semaste//===-- llvm-diff.cpp - Module comparator command-line driver ---*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste// 10254721Semaste// This file defines the command-line driver for the difference engine. 11254721Semaste// 12254721Semaste//===----------------------------------------------------------------------===// 13254721Semaste 14254721Semaste#include "DiffLog.h" 15254721Semaste#include "DifferenceEngine.h" 16254721Semaste 17254721Semaste#include "llvm/LLVMContext.h" 18254721Semaste#include "llvm/Module.h" 19254721Semaste#include "llvm/Type.h" 20254721Semaste#include "llvm/ADT/DenseMap.h" 21254721Semaste#include "llvm/ADT/SmallVector.h" 22254721Semaste#include "llvm/ADT/StringRef.h" 23254721Semaste#include "llvm/Support/CommandLine.h" 24254721Semaste#include "llvm/Support/IRReader.h" 25254721Semaste#include "llvm/Support/MemoryBuffer.h" 26254721Semaste#include "llvm/Support/raw_ostream.h" 27254721Semaste#include "llvm/Support/SourceMgr.h" 28254721Semaste 29254721Semaste#include <string> 30254721Semaste#include <utility> 31254721Semaste 32254721Semaste 33254721Semasteusing namespace llvm; 34254721Semaste 35254721Semaste/// Reads a module from a file. On error, messages are written to stderr 36254721Semaste/// and null is returned. 37254721Semastestatic Module *ReadModule(LLVMContext &Context, StringRef Name) { 38254721Semaste SMDiagnostic Diag; 39254721Semaste Module *M = ParseIRFile(Name, Diag, Context); 40254721Semaste if (!M) 41254721Semaste Diag.Print("llvmdiff", errs()); 42254721Semaste return M; 43254721Semaste} 44254721Semaste 45254721Semastestatic void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R, 46254721Semaste StringRef Name) { 47254721Semaste // Drop leading sigils from the global name. 48254721Semaste if (Name.startswith("@")) Name = Name.substr(1); 49269024Semaste 50269024Semaste Function *LFn = L->getFunction(Name); 51269024Semaste Function *RFn = R->getFunction(Name); 52254721Semaste if (LFn && RFn) 53254721Semaste Engine.diff(LFn, RFn); 54254721Semaste else if (!LFn && !RFn) 55254721Semaste errs() << "No function named @" << Name << " in either module\n"; 56254721Semaste else if (!LFn) 57254721Semaste errs() << "No function named @" << Name << " in left module\n"; 58254721Semaste else 59254721Semaste errs() << "No function named @" << Name << " in right module\n"; 60254721Semaste} 61254721Semaste 62254721Semastestatic cl::opt<std::string> LeftFilename(cl::Positional, 63254721Semaste cl::desc("<first file>"), 64254721Semaste cl::Required); 65254721Semastestatic cl::opt<std::string> RightFilename(cl::Positional, 66254721Semaste cl::desc("<second file>"), 67254721Semaste cl::Required); 68254721Semastestatic cl::list<std::string> GlobalsToCompare(cl::Positional, 69254721Semaste cl::desc("<globals to compare>")); 70254721Semaste 71254721Semasteint main(int argc, char **argv) { 72254721Semaste cl::ParseCommandLineOptions(argc, argv); 73254721Semaste 74254721Semaste LLVMContext Context; 75254721Semaste 76254721Semaste // Load both modules. Die if that fails. 77254721Semaste Module *LModule = ReadModule(Context, LeftFilename); 78254721Semaste Module *RModule = ReadModule(Context, RightFilename); 79254721Semaste if (!LModule || !RModule) return 1; 80254721Semaste 81254721Semaste DiffConsumer Consumer(LModule, RModule); 82254721Semaste DifferenceEngine Engine(Context, Consumer); 83254721Semaste 84254721Semaste // If any global names were given, just diff those. 85254721Semaste if (!GlobalsToCompare.empty()) { 86254721Semaste for (unsigned I = 0, E = GlobalsToCompare.size(); I != E; ++I) 87254721Semaste diffGlobal(Engine, LModule, RModule, GlobalsToCompare[I]); 88254721Semaste 89254721Semaste // Otherwise, diff everything in the module. 90254721Semaste } else { 91254721Semaste Engine.diff(LModule, RModule); 92254721Semaste } 93254721Semaste 94254721Semaste delete LModule; 95254721Semaste delete RModule; 96254721Semaste 97254721Semaste return Consumer.hadDifferences(); 98254721Semaste} 99254721Semaste