Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-diff/llvm-diff.cpp
35260 views
1
//===-- llvm-diff.cpp - Module comparator command-line driver ---*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines the command-line driver for the difference engine.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "lib/DiffLog.h"
14
#include "lib/DifferenceEngine.h"
15
#include "llvm/ADT/StringRef.h"
16
#include "llvm/IR/LLVMContext.h"
17
#include "llvm/IR/Module.h"
18
#include "llvm/IR/Type.h"
19
#include "llvm/IRReader/IRReader.h"
20
#include "llvm/Support/CommandLine.h"
21
#include "llvm/Support/MemoryBuffer.h"
22
#include "llvm/Support/SourceMgr.h"
23
#include "llvm/Support/raw_ostream.h"
24
#include "llvm/Support/WithColor.h"
25
#include <string>
26
#include <utility>
27
28
29
using namespace llvm;
30
31
/// Reads a module from a file. On error, messages are written to stderr
32
/// and null is returned.
33
static std::unique_ptr<Module> readModule(LLVMContext &Context,
34
StringRef Name) {
35
SMDiagnostic Diag;
36
std::unique_ptr<Module> M = parseIRFile(Name, Diag, Context);
37
if (!M)
38
Diag.print("llvm-diff", errs());
39
return M;
40
}
41
42
static void diffGlobal(DifferenceEngine &Engine, Module &L, Module &R,
43
StringRef Name) {
44
// Drop leading sigils from the global name.
45
Name.consume_front("@");
46
47
Function *LFn = L.getFunction(Name);
48
Function *RFn = R.getFunction(Name);
49
if (LFn && RFn)
50
Engine.diff(LFn, RFn);
51
else if (!LFn && !RFn)
52
errs() << "No function named @" << Name << " in either module\n";
53
else if (!LFn)
54
errs() << "No function named @" << Name << " in left module\n";
55
else
56
errs() << "No function named @" << Name << " in right module\n";
57
}
58
59
cl::OptionCategory DiffCategory("Diff Options");
60
61
static cl::opt<std::string> LeftFilename(cl::Positional,
62
cl::desc("<first file>"), cl::Required,
63
cl::cat(DiffCategory));
64
static cl::opt<std::string> RightFilename(cl::Positional,
65
cl::desc("<second file>"),
66
cl::Required, cl::cat(DiffCategory));
67
static cl::list<std::string> GlobalsToCompare(cl::Positional,
68
cl::desc("<globals to compare>"),
69
cl::cat(DiffCategory));
70
71
int main(int argc, char **argv) {
72
cl::HideUnrelatedOptions({&DiffCategory, &getColorCategory()});
73
cl::ParseCommandLineOptions(argc, argv);
74
75
LLVMContext Context;
76
77
// Load both modules. Die if that fails.
78
std::unique_ptr<Module> LModule = readModule(Context, LeftFilename);
79
std::unique_ptr<Module> RModule = readModule(Context, RightFilename);
80
if (!LModule || !RModule) return 1;
81
82
DiffConsumer Consumer;
83
DifferenceEngine Engine(Consumer);
84
85
// If any global names were given, just diff those.
86
if (!GlobalsToCompare.empty()) {
87
for (unsigned I = 0, E = GlobalsToCompare.size(); I != E; ++I)
88
diffGlobal(Engine, *LModule, *RModule, GlobalsToCompare[I]);
89
90
// Otherwise, diff everything in the module.
91
} else {
92
Engine.diff(LModule.get(), RModule.get());
93
}
94
95
return Consumer.hadDifferences();
96
}
97
98