Index: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h +++ llvm/trunk/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 @@ bool AddressTaken = false; // TODO: Serialize the successors and liveins. - std::vector Instructions; + std::vector Instructions; }; template <> struct MappingTraits { Index: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp @@ -84,6 +84,10 @@ 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 @@ 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 @@ // 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()); Index: llvm/trunk/test/CodeGen/MIR/X86/expected-machine-operand.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/expected-machine-operand.mir +++ llvm/trunk/test/CodeGen/MIR/X86/expected-machine-operand.mir @@ -13,7 +13,7 @@ body: - name: entry instructions: - # CHECK: 1:16: expected a machine operand + # CHECK: [[@LINE+1]]:24: expected a machine operand - '%eax = XOR32rr =' - 'RETQ %eax' ... Index: llvm/trunk/test/CodeGen/MIR/X86/missing-comma.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/missing-comma.mir +++ llvm/trunk/test/CodeGen/MIR/X86/missing-comma.mir @@ -13,7 +13,7 @@ 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' ... Index: llvm/trunk/test/CodeGen/MIR/X86/missing-instruction.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/missing-instruction.mir +++ llvm/trunk/test/CodeGen/MIR/X86/missing-instruction.mir @@ -13,6 +13,6 @@ body: - name: entry instructions: - # CHECK: 1:1: expected a machine instruction + # CHECK: [[@LINE+1]]:9: expected a machine instruction - '' ... Index: llvm/trunk/test/CodeGen/MIR/X86/unknown-instruction.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/unknown-instruction.mir +++ llvm/trunk/test/CodeGen/MIR/X86/unknown-instruction.mir @@ -15,6 +15,6 @@ body: - name: entry instructions: - # CHECK: 1:1: unknown machine instruction name 'retJust0' + # CHECK: [[@LINE+1]]:8: unknown machine instruction name 'retJust0' - retJust0 ... Index: llvm/trunk/test/CodeGen/MIR/X86/unknown-register.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/unknown-register.mir +++ llvm/trunk/test/CodeGen/MIR/X86/unknown-register.mir @@ -15,7 +15,7 @@ body: - name: entry instructions: - # CHECK: 1:1: unknown register name 'xax' + # CHECK: [[@LINE+1]]:9: unknown register name 'xax' - '%xax = MOV32r0' - 'RETQ %xax' ... Index: llvm/trunk/test/CodeGen/MIR/X86/unrecognized-character.mir =================================================================== --- llvm/trunk/test/CodeGen/MIR/X86/unrecognized-character.mir +++ llvm/trunk/test/CodeGen/MIR/X86/unrecognized-character.mir @@ -13,6 +13,6 @@ body: - name: entry instructions: - # CHECK: 1:1: unexpected character '`' + # CHECK: [[@LINE+1]]:9: unexpected character '`' - '` RETQ' ...