From 926d65d4f7b9f525658f1ed5b519ec3abd814807 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 23 Jun 2015 22:39:23 +0000 Subject: [PATCH] MIR Parser: Use correct source locations for machine instruction diagnostics. This commit translates the source locations for MIParser diagnostics from the locations in the machine instruction string to the locations in the MIR file. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D10574 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240474 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MIRYamlMapping.h | 40 ++++++++++++++++++- lib/CodeGen/MIRParser/MIRParser.cpp | 25 +++++++++++- .../MIR/X86/expected-machine-operand.mir | 2 +- test/CodeGen/MIR/X86/missing-comma.mir | 2 +- test/CodeGen/MIR/X86/missing-instruction.mir | 2 +- test/CodeGen/MIR/X86/unknown-instruction.mir | 2 +- test/CodeGen/MIR/X86/unknown-register.mir | 2 +- .../MIR/X86/unrecognized-character.mir | 2 +- 8 files changed, 67 insertions(+), 10 deletions(-) diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index 8b205113d64..4325fb98078 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -22,7 +22,43 @@ #include "llvm/Support/YAMLTraits.h" #include -LLVM_YAML_IS_SEQUENCE_VECTOR(std::string) +namespace llvm { +namespace yaml { + +/// A wrapper around std::string which contains a source range that's being +/// set during parsing. +struct StringValue { + std::string Value; + SMRange SourceRange; + + StringValue() {} + StringValue(std::string Value) : Value(std::move(Value)) {} + + bool operator==(const StringValue &Other) const { + return Value == Other.Value; + } +}; + +template <> struct ScalarTraits { + static void output(const StringValue &S, void *, llvm::raw_ostream &OS) { + OS << S.Value; + } + + static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) { + S.Value = Scalar.str(); + if (const auto *Node = + reinterpret_cast(Ctx)->getCurrentNode()) + S.SourceRange = Node->getSourceRange(); + return ""; + } + + static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } +}; + +} // end namespace yaml +} // end namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue) namespace llvm { namespace yaml { @@ -34,7 +70,7 @@ struct MachineBasicBlock { bool AddressTaken = false; // TODO: Serialize the successors and liveins. - std::vector Instructions; + std::vector Instructions; }; template <> struct MappingTraits { diff --git a/lib/CodeGen/MIRParser/MIRParser.cpp b/lib/CodeGen/MIRParser/MIRParser.cpp index 1ba7f1f1df2..57ecacf7dce 100644 --- a/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/lib/CodeGen/MIRParser/MIRParser.cpp @@ -84,6 +84,10 @@ public: const yaml::MachineBasicBlock &YamlMBB); private: + /// Return a MIR diagnostic converted from an MI string diagnostic. + SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error, + SMRange SourceRange); + /// Return a MIR diagnostic converted from an LLVM assembly diagnostic. SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, SMRange SourceRange); @@ -129,6 +133,7 @@ static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { std::unique_ptr MIRParserImpl::parse() { yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(), /*Ctxt=*/nullptr, handleYAMLDiag, this); + In.setContext(&In); if (!In.setCurrentDocument()) { if (In.error()) @@ -235,16 +240,32 @@ bool MIRParserImpl::initializeMachineBasicBlock( // Parse the instructions. for (const auto &MISource : YamlMBB.Instructions) { SMDiagnostic Error; - if (auto *MI = parseMachineInstr(SM, MF, MISource, Error)) { + if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, Error)) { MBB.insert(MBB.end(), MI); continue; } - reportDiagnostic(Error); + reportDiagnostic(diagFromMIStringDiag(Error, MISource.SourceRange)); return true; } return false; } +SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error, + SMRange SourceRange) { + assert(SourceRange.isValid() && "Invalid source range"); + SMLoc Loc = SourceRange.Start; + bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() && + *Loc.getPointer() == '\''; + // Translate the location of the error from the location in the MI string to + // the corresponding location in the MIR file. + Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() + + (HasQuote ? 1 : 0)); + + // TODO: Translate any source ranges as well. + return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None, + Error.getFixIts()); +} + SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, SMRange SourceRange) { assert(SourceRange.isValid()); diff --git a/test/CodeGen/MIR/X86/expected-machine-operand.mir b/test/CodeGen/MIR/X86/expected-machine-operand.mir index 262cd8bc39a..685f3bfe31a 100644 --- a/test/CodeGen/MIR/X86/expected-machine-operand.mir +++ b/test/CodeGen/MIR/X86/expected-machine-operand.mir @@ -13,7 +13,7 @@ name: foo body: - name: entry instructions: - # CHECK: 1:16: expected a machine operand + # CHECK: [[@LINE+1]]:24: expected a machine operand - '%eax = XOR32rr =' - 'RETQ %eax' ... diff --git a/test/CodeGen/MIR/X86/missing-comma.mir b/test/CodeGen/MIR/X86/missing-comma.mir index 76fea10e8b0..dc06a87dc4b 100644 --- a/test/CodeGen/MIR/X86/missing-comma.mir +++ b/test/CodeGen/MIR/X86/missing-comma.mir @@ -13,7 +13,7 @@ name: foo body: - name: entry instructions: - # CHECK: 1:21: expected ',' before the next machine operand + # CHECK: [[@LINE+1]]:29: expected ',' before the next machine operand - '%eax = XOR32rr %eax %eflags' - 'RETQ %eax' ... diff --git a/test/CodeGen/MIR/X86/missing-instruction.mir b/test/CodeGen/MIR/X86/missing-instruction.mir index 0cf4371d349..e18b667bae4 100644 --- a/test/CodeGen/MIR/X86/missing-instruction.mir +++ b/test/CodeGen/MIR/X86/missing-instruction.mir @@ -13,6 +13,6 @@ name: foo body: - name: entry instructions: - # CHECK: 1:1: expected a machine instruction + # CHECK: [[@LINE+1]]:9: expected a machine instruction - '' ... diff --git a/test/CodeGen/MIR/X86/unknown-instruction.mir b/test/CodeGen/MIR/X86/unknown-instruction.mir index 05decaac929..0d1db9f9a3f 100644 --- a/test/CodeGen/MIR/X86/unknown-instruction.mir +++ b/test/CodeGen/MIR/X86/unknown-instruction.mir @@ -15,6 +15,6 @@ name: foo body: - name: entry instructions: - # CHECK: 1:1: unknown machine instruction name 'retJust0' + # CHECK: [[@LINE+1]]:8: unknown machine instruction name 'retJust0' - retJust0 ... diff --git a/test/CodeGen/MIR/X86/unknown-register.mir b/test/CodeGen/MIR/X86/unknown-register.mir index c5d349345dc..59284f99a6d 100644 --- a/test/CodeGen/MIR/X86/unknown-register.mir +++ b/test/CodeGen/MIR/X86/unknown-register.mir @@ -15,7 +15,7 @@ name: foo body: - name: entry instructions: - # CHECK: 1:1: unknown register name 'xax' + # CHECK: [[@LINE+1]]:9: unknown register name 'xax' - '%xax = MOV32r0' - 'RETQ %xax' ... diff --git a/test/CodeGen/MIR/X86/unrecognized-character.mir b/test/CodeGen/MIR/X86/unrecognized-character.mir index b645018c428..0fd504fb5bb 100644 --- a/test/CodeGen/MIR/X86/unrecognized-character.mir +++ b/test/CodeGen/MIR/X86/unrecognized-character.mir @@ -13,6 +13,6 @@ name: foo body: - name: entry instructions: - # CHECK: 1:1: unexpected character '`' + # CHECK: [[@LINE+1]]:9: unexpected character '`' - '` RETQ' ... -- 2.34.1