12
12
// ===----------------------------------------------------------------------===//
13
13
14
14
#include " MIParser.h"
15
+ #include " MILexer.h"
15
16
#include " llvm/ADT/StringMap.h"
16
17
#include " llvm/CodeGen/MachineBasicBlock.h"
17
18
#include " llvm/CodeGen/MachineFunction.h"
@@ -29,19 +30,27 @@ class MIParser {
29
30
SourceMgr &SM;
30
31
MachineFunction &MF;
31
32
SMDiagnostic &Error;
32
- StringRef Source;
33
+ StringRef Source, CurrentSource;
34
+ MIToken Token;
33
35
// / Maps from instruction names to op codes.
34
36
StringMap<unsigned > Names2InstrOpCodes;
35
37
36
38
public:
37
39
MIParser (SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
38
40
StringRef Source);
39
41
42
+ void lex ();
43
+
40
44
// / Report an error at the current location with the given message.
41
45
// /
42
46
// / This function always return true.
43
47
bool error (const Twine &Msg);
44
48
49
+ // / Report an error at the given location with the given message.
50
+ // /
51
+ // / This function always return true.
52
+ bool error (StringRef::iterator Loc, const Twine &Msg);
53
+
45
54
MachineInstr *parse ();
46
55
47
56
private:
@@ -50,38 +59,58 @@ class MIParser {
50
59
// / Try to convert an instruction name to an opcode. Return true if the
51
60
// / instruction name is invalid.
52
61
bool parseInstrName (StringRef InstrName, unsigned &OpCode);
62
+
63
+ bool parseInstruction (unsigned &OpCode);
53
64
};
54
65
55
66
} // end anonymous namespace
56
67
57
68
MIParser::MIParser (SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
58
69
StringRef Source)
59
- : SM(SM), MF(MF), Error(Error), Source(Source) {}
70
+ : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
71
+ Token(MIToken::Error, StringRef()) {}
72
+
73
+ void MIParser::lex () {
74
+ CurrentSource = lexMIToken (
75
+ CurrentSource, Token,
76
+ [this ](StringRef::iterator Loc, const Twine &Msg) { error (Loc, Msg); });
77
+ }
78
+
79
+ bool MIParser::error (const Twine &Msg) { return error (Token.location (), Msg); }
60
80
61
- bool MIParser::error (const Twine &Msg) {
81
+ bool MIParser::error (StringRef::iterator Loc, const Twine &Msg) {
62
82
// TODO: Get the proper location in the MIR file, not just a location inside
63
83
// the string.
64
- Error =
65
- SMDiagnostic (SM, SMLoc (), SM.getMemoryBuffer (SM.getMainFileID ())
66
- ->getBufferIdentifier (),
67
- 1 , 0 , SourceMgr::DK_Error, Msg.str (), Source, None, None);
84
+ assert (Loc >= Source.data () && Loc <= (Source.data () + Source.size ()));
85
+ Error = SMDiagnostic (
86
+ SM, SMLoc (),
87
+ SM.getMemoryBuffer (SM.getMainFileID ())->getBufferIdentifier (), 1 ,
88
+ Loc - Source.data (), SourceMgr::DK_Error, Msg.str (), Source, None, None);
68
89
return true ;
69
90
}
70
91
71
92
MachineInstr *MIParser::parse () {
72
- StringRef InstrName = Source;
93
+ lex ();
94
+
73
95
unsigned OpCode;
74
- if (parseInstrName (InstrName, OpCode)) {
75
- error (Twine (" unknown machine instruction name '" ) + InstrName + " '" );
96
+ if (Token.isError () || parseInstruction (OpCode))
76
97
return nullptr ;
77
- }
78
98
79
99
// TODO: Parse the rest of instruction - machine operands, etc.
80
100
const auto &MCID = MF.getSubtarget ().getInstrInfo ()->get (OpCode);
81
101
auto *MI = MF.CreateMachineInstr (MCID, DebugLoc ());
82
102
return MI;
83
103
}
84
104
105
+ bool MIParser::parseInstruction (unsigned &OpCode) {
106
+ if (Token.isNot (MIToken::Identifier))
107
+ return error (" expected a machine instruction" );
108
+ StringRef InstrName = Token.stringValue ();
109
+ if (parseInstrName (InstrName, OpCode))
110
+ return error (Twine (" unknown machine instruction name '" ) + InstrName + " '" );
111
+ return false ;
112
+ }
113
+
85
114
void MIParser::initNames2InstrOpCodes () {
86
115
if (!Names2InstrOpCodes.empty ())
87
116
return ;
0 commit comments