llvm.org GIT mirror llvm / 926d65d
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 Alex Lorenz 5 years ago
8 changed file(s) with 67 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
2121 #include "llvm/Support/YAMLTraits.h"
2222 #include
2323
24 LLVM_YAML_IS_SEQUENCE_VECTOR(std::string)
24 namespace llvm {
25 namespace yaml {
26
27 /// A wrapper around std::string which contains a source range that's being
28 /// set during parsing.
29 struct StringValue {
30 std::string Value;
31 SMRange SourceRange;
32
33 StringValue() {}
34 StringValue(std::string Value) : Value(std::move(Value)) {}
35
36 bool operator==(const StringValue &Other) const {
37 return Value == Other.Value;
38 }
39 };
40
41 template <> struct ScalarTraits {
42 static void output(const StringValue &S, void *, llvm::raw_ostream &OS) {
43 OS << S.Value;
44 }
45
46 static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) {
47 S.Value = Scalar.str();
48 if (const auto *Node =
49 reinterpret_cast(Ctx)->getCurrentNode())
50 S.SourceRange = Node->getSourceRange();
51 return "";
52 }
53
54 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
55 };
56
57 } // end namespace yaml
58 } // end namespace llvm
59
60 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue)
2561
2662 namespace llvm {
2763 namespace yaml {
3369 bool AddressTaken = false;
3470 // TODO: Serialize the successors and liveins.
3571
36 std::vector<std::string> Instructions;
72 std::vector<StringValue> Instructions;
3773 };
3874
3975 template <> struct MappingTraits {
8383 const yaml::MachineBasicBlock &YamlMBB);
8484
8585 private:
86 /// Return a MIR diagnostic converted from an MI string diagnostic.
87 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
88 SMRange SourceRange);
89
8690 /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
8791 SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
8892 SMRange SourceRange);
128132 std::unique_ptr MIRParserImpl::parse() {
129133 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
130134 /*Ctxt=*/nullptr, handleYAMLDiag, this);
135 In.setContext(&In);
131136
132137 if (!In.setCurrentDocument()) {
133138 if (In.error())
234239 // Parse the instructions.
235240 for (const auto &MISource : YamlMBB.Instructions) {
236241 SMDiagnostic Error;
237 if (auto *MI = parseMachineInstr(SM, MF, MISource, Error)) {
242 if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, Error)) {
238243 MBB.insert(MBB.end(), MI);
239244 continue;
240245 }
241 reportDiagnostic(Error);
246 reportDiagnostic(diagFromMIStringDiag(Error, MISource.SourceRange));
242247 return true;
243248 }
244249 return false;
250 }
251
252 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
253 SMRange SourceRange) {
254 assert(SourceRange.isValid() && "Invalid source range");
255 SMLoc Loc = SourceRange.Start;
256 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
257 *Loc.getPointer() == '\'';
258 // Translate the location of the error from the location in the MI string to
259 // the corresponding location in the MIR file.
260 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
261 (HasQuote ? 1 : 0));
262
263 // TODO: Translate any source ranges as well.
264 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
265 Error.getFixIts());
245266 }
246267
247268 SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
1212 body:
1313 - name: entry
1414 instructions:
15 # CHECK: 1:16: expected a machine operand
15 # CHECK: [[@LINE+1]]:24: expected a machine operand
1616 - '%eax = XOR32rr ='
1717 - 'RETQ %eax'
1818 ...
1212 body:
1313 - name: entry
1414 instructions:
15 # CHECK: 1:21: expected ',' before the next machine operand
15 # CHECK: [[@LINE+1]]:29: expected ',' before the next machine operand
1616 - '%eax = XOR32rr %eax %eflags'
1717 - 'RETQ %eax'
1818 ...
1212 body:
1313 - name: entry
1414 instructions:
15 # CHECK: 1:1: expected a machine instruction
15 # CHECK: [[@LINE+1]]:9: expected a machine instruction
1616 - ''
1717 ...
1414 body:
1515 - name: entry
1616 instructions:
17 # CHECK: 1:1: unknown machine instruction name 'retJust0'
17 # CHECK: [[@LINE+1]]:8: unknown machine instruction name 'retJust0'
1818 - retJust0
1919 ...
1414 body:
1515 - name: entry
1616 instructions:
17 # CHECK: 1:1: unknown register name 'xax'
17 # CHECK: [[@LINE+1]]:9: unknown register name 'xax'
1818 - '%xax = MOV32r0'
1919 - 'RETQ %xax'
2020 ...
1212 body:
1313 - name: entry
1414 instructions:
15 # CHECK: 1:1: unexpected character '`'
15 # CHECK: [[@LINE+1]]:9: unexpected character '`'
1616 - '` RETQ'
1717 ...