mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-29 13:29:28 +00:00
This makes the 'verifyFunction' and 'verifyModule' functions totally independent operations on the LLVM IR. It also cleans up their API a bit by lifting the abort behavior into their clients and just using an optional raw_ostream parameter to control printing. The implementation of the verifier is now just an InstVisitor with no multiple inheritance. It also is significantly more const-correct, and hides the const violations internally. The two layers that force us to break const correctness are building a DomTree and dispatching through the InstVisitor. A new VerifierPass is used to implement the legacy pass manager interface in terms of the other pieces. The error messages produced may be slightly different now, and we may have slightly different short circuiting behavior with different usage models of the verifier, but generally everything works equivalently and this unblocks wiring the verifier up to the new pass manager. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199569 91177308-0d34-0410-b5e6-96231b3b80d8
120 lines
3.6 KiB
C++
120 lines
3.6 KiB
C++
//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This utility may be invoked in the following manner:
|
|
// llvm-as --help - Output information about command line switches
|
|
// llvm-as [options] - Read LLVM asm from stdin, write bitcode to stdout
|
|
// llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode
|
|
// to the x.bc file.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/AsmParser/Parser.h"
|
|
#include "llvm/Bitcode/ReaderWriter.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/Verifier.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/ManagedStatic.h"
|
|
#include "llvm/Support/PrettyStackTrace.h"
|
|
#include "llvm/Support/Signals.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "llvm/Support/SystemUtils.h"
|
|
#include "llvm/Support/ToolOutputFile.h"
|
|
#include <memory>
|
|
using namespace llvm;
|
|
|
|
static cl::opt<std::string>
|
|
InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
|
|
|
|
static cl::opt<std::string>
|
|
OutputFilename("o", cl::desc("Override output filename"),
|
|
cl::value_desc("filename"));
|
|
|
|
static cl::opt<bool>
|
|
Force("f", cl::desc("Enable binary output on terminals"));
|
|
|
|
static cl::opt<bool>
|
|
DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false));
|
|
|
|
static cl::opt<bool>
|
|
DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
|
|
|
|
static cl::opt<bool>
|
|
DisableVerify("disable-verify", cl::Hidden,
|
|
cl::desc("Do not run verifier on input LLVM (dangerous!)"));
|
|
|
|
static void WriteOutputFile(const Module *M) {
|
|
// Infer the output filename if needed.
|
|
if (OutputFilename.empty()) {
|
|
if (InputFilename == "-") {
|
|
OutputFilename = "-";
|
|
} else {
|
|
std::string IFN = InputFilename;
|
|
int Len = IFN.length();
|
|
if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
|
|
// Source ends in .ll
|
|
OutputFilename = std::string(IFN.begin(), IFN.end()-3);
|
|
} else {
|
|
OutputFilename = IFN; // Append a .bc to it
|
|
}
|
|
OutputFilename += ".bc";
|
|
}
|
|
}
|
|
|
|
std::string ErrorInfo;
|
|
OwningPtr<tool_output_file> Out(new tool_output_file(
|
|
OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary));
|
|
if (!ErrorInfo.empty()) {
|
|
errs() << ErrorInfo << '\n';
|
|
exit(1);
|
|
}
|
|
|
|
if (Force || !CheckBitcodeOutputToConsole(Out->os(), true))
|
|
WriteBitcodeToFile(M, Out->os());
|
|
|
|
// Declare success.
|
|
Out->keep();
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
// Print a stack trace if we signal out.
|
|
sys::PrintStackTraceOnErrorSignal();
|
|
PrettyStackTraceProgram X(argc, argv);
|
|
LLVMContext &Context = getGlobalContext();
|
|
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
|
|
cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
|
|
|
|
// Parse the file now...
|
|
SMDiagnostic Err;
|
|
OwningPtr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
|
|
if (M.get() == 0) {
|
|
Err.print(argv[0], errs());
|
|
return 1;
|
|
}
|
|
|
|
if (!DisableVerify) {
|
|
std::string ErrorStr;
|
|
raw_string_ostream OS(ErrorStr);
|
|
if (verifyModule(*M.get(), &OS)) {
|
|
errs() << argv[0]
|
|
<< ": assembly parsed, but does not verify as correct!\n";
|
|
errs() << OS.str();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get();
|
|
|
|
if (!DisableOutput)
|
|
WriteOutputFile(M.get());
|
|
|
|
return 0;
|
|
}
|