#include "llvm/AsmParser/Parser.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/LineIterator.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/MemoryBuffer.h"
///
/// Return true if an error occurred.
bool parseMachineFunction(yaml::Input &In);
+
+private:
+ /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
+ SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
+ SMRange SourceRange);
};
} // end anonymous namespace
dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
Context);
- if (!M)
+ if (!M) {
+ Error = diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange());
return M;
+ }
In.nextDocument();
if (!In.setCurrentDocument())
return M;
return false;
}
+SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
+ SMRange SourceRange) {
+ assert(SourceRange.isValid());
+
+ // Translate the location of the error from the location in the llvm IR string
+ // to the corresponding location in the MIR file.
+ auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
+ unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
+ unsigned Column = Error.getColumnNo();
+ StringRef LineStr = Error.getLineContents();
+ SMLoc Loc = Error.getLoc();
+
+ // Get the full line and adjust the column number by taking the indentation of
+ // LLVM IR into account.
+ for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
+ L != E; ++L) {
+ if (L.line_number() == Line) {
+ LineStr = *L;
+ Loc = SMLoc::getFromPointer(LineStr.data());
+ auto Indent = LineStr.find(Error.getLineContents());
+ if (Indent != StringRef::npos)
+ Column += Indent;
+ break;
+ }
+ }
+
+ return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
+ Error.getMessage(), LineStr, Error.getRanges(),
+ Error.getFixIts());
+}
+
std::unique_ptr<Module> llvm::parseMIRFile(StringRef Filename,
SMDiagnostic &Error,
LLVMContext &Context) {
--- /dev/null
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# This test ensures an error is reported if the embedded LLVM IR contains an
+# error.
+
+--- |
+
+ ; CHECK: [[@LINE+3]]:15: error: use of undefined value '%a'
+ define i32 @foo(i32 %x, i32 %y) {
+ %z = alloca i32, align 4
+ store i32 %a, i32* %z, align 4
+ br label %Test
+ Test:
+ %m = load i32, i32* %z, align 4
+ %cond = icmp eq i32 %y, %m
+ br i1 %cond, label %IfEqual, label %IfUnequal
+ IfEqual:
+ ret i32 1
+ IfUnequal:
+ ret i32 0
+ }
+
+...