blob: e505ab4baeb3aa1736795382d9918fe2dd48c815 [file] [log] [blame]
Alex Lorenz2bdb4e12015-05-27 18:02:19 +00001//===- MIRParser.cpp - MIR serialization format parser implementation -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the class that parses the optional LLVM IR and machine
11// functions that are stored in MIR files.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/MIRParser/MIRParser.h"
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000016#include "MIParser.h"
Alex Lorenz33f0aef2015-06-26 16:46:11 +000017#include "llvm/ADT/DenseMap.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000018#include "llvm/ADT/StringRef.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000019#include "llvm/ADT/StringMap.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000020#include "llvm/ADT/STLExtras.h"
21#include "llvm/AsmParser/Parser.h"
Alex Lorenz5d6108e2015-06-26 22:56:48 +000022#include "llvm/AsmParser/SlotMapping.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000023#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000024#include "llvm/CodeGen/MachineFrameInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz78d78312015-05-28 22:41:12 +000026#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000027#include "llvm/IR/BasicBlock.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000028#include "llvm/IR/DiagnosticInfo.h"
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000029#include "llvm/IR/Instructions.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000030#include "llvm/IR/LLVMContext.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000031#include "llvm/IR/Module.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000032#include "llvm/IR/ValueSymbolTable.h"
Alex Lorenz09b832c2015-05-29 17:05:41 +000033#include "llvm/Support/LineIterator.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000034#include "llvm/Support/SMLoc.h"
35#include "llvm/Support/SourceMgr.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/YAMLTraits.h"
38#include <memory>
39
40using namespace llvm;
41
Alex Lorenz735c47e2015-06-15 20:30:22 +000042namespace llvm {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000043
44/// This class implements the parsing of LLVM IR that's embedded inside a MIR
45/// file.
46class MIRParserImpl {
47 SourceMgr SM;
48 StringRef Filename;
49 LLVMContext &Context;
Alex Lorenz735c47e2015-06-15 20:30:22 +000050 StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
Alex Lorenz5d6108e2015-06-26 22:56:48 +000051 SlotMapping IRSlots;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000052
53public:
54 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
55 LLVMContext &Context);
56
Alex Lorenz735c47e2015-06-15 20:30:22 +000057 void reportDiagnostic(const SMDiagnostic &Diag);
58
59 /// Report an error with the given message at unknown location.
60 ///
61 /// Always returns true.
62 bool error(const Twine &Message);
63
Alex Lorenzb1f9ce82015-07-08 20:22:20 +000064 /// Report an error with the given message at the given location.
65 ///
66 /// Always returns true.
67 bool error(SMLoc Loc, const Twine &Message);
68
Alex Lorenz0fd7c622015-06-30 17:55:00 +000069 /// Report a given error with the location translated from the location in an
70 /// embedded string literal to a location in the MIR file.
71 ///
72 /// Always returns true.
73 bool error(const SMDiagnostic &Error, SMRange SourceRange);
74
Alex Lorenz78d78312015-05-28 22:41:12 +000075 /// Try to parse the optional LLVM module and the machine functions in the MIR
76 /// file.
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000077 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000078 /// Return null if an error occurred.
Alex Lorenz735c47e2015-06-15 20:30:22 +000079 std::unique_ptr<Module> parse();
Alex Lorenz78d78312015-05-28 22:41:12 +000080
81 /// Parse the machine function in the current YAML document.
82 ///
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000083 /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
84 /// A dummy IR function is created and inserted into the given module when
85 /// this parameter is true.
86 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000087 /// Return true if an error occurred.
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000088 bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
Alex Lorenz09b832c2015-05-29 17:05:41 +000089
Alex Lorenz735c47e2015-06-15 20:30:22 +000090 /// Initialize the machine function to the state that's described in the MIR
91 /// file.
92 ///
93 /// Return true if error occurred.
94 bool initializeMachineFunction(MachineFunction &MF);
95
Alex Lorenz4f093bf2015-06-19 17:43:07 +000096 /// Initialize the machine basic block using it's YAML representation.
97 ///
98 /// Return true if an error occurred.
Alex Lorenz7a503fa2015-07-07 17:46:43 +000099 bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
100 const yaml::MachineBasicBlock &YamlMBB,
101 const PerFunctionMIParsingState &PFS);
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000102
Alex Lorenz54565cf2015-06-24 19:56:10 +0000103 bool initializeRegisterInfo(MachineRegisterInfo &RegInfo,
104 const yaml::MachineFunction &YamlMF);
105
Alex Lorenz60541c12015-07-09 19:55:27 +0000106 bool initializeFrameInfo(MachineFrameInfo &MFI,
107 const yaml::MachineFrameInfo &YamlMFI);
108
Alex Lorenz09b832c2015-05-29 17:05:41 +0000109private:
Alex Lorenz51af1602015-06-23 22:39:23 +0000110 /// Return a MIR diagnostic converted from an MI string diagnostic.
111 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
112 SMRange SourceRange);
113
Alex Lorenz09b832c2015-05-29 17:05:41 +0000114 /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
115 SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
116 SMRange SourceRange);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000117
118 /// Create an empty function with the given name.
119 void createDummyFunction(StringRef Name, Module &M);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000120};
121
Alex Lorenz735c47e2015-06-15 20:30:22 +0000122} // end namespace llvm
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000123
124MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
125 StringRef Filename, LLVMContext &Context)
126 : SM(), Filename(Filename), Context(Context) {
127 SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
128}
129
Alex Lorenz735c47e2015-06-15 20:30:22 +0000130bool MIRParserImpl::error(const Twine &Message) {
131 Context.diagnose(DiagnosticInfoMIRParser(
132 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
133 return true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000134}
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000135
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000136bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
137 Context.diagnose(DiagnosticInfoMIRParser(
138 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
139 return true;
140}
141
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000142bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
143 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
144 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
145 return true;
146}
147
Alex Lorenz735c47e2015-06-15 20:30:22 +0000148void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
149 DiagnosticSeverity Kind;
150 switch (Diag.getKind()) {
151 case SourceMgr::DK_Error:
152 Kind = DS_Error;
153 break;
154 case SourceMgr::DK_Warning:
155 Kind = DS_Warning;
156 break;
157 case SourceMgr::DK_Note:
158 Kind = DS_Note;
159 break;
160 }
161 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
162}
163
164static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
165 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
166}
167
168std::unique_ptr<Module> MIRParserImpl::parse() {
Alex Lorenz78d78312015-05-28 22:41:12 +0000169 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
Alex Lorenz735c47e2015-06-15 20:30:22 +0000170 /*Ctxt=*/nullptr, handleYAMLDiag, this);
Alex Lorenz51af1602015-06-23 22:39:23 +0000171 In.setContext(&In);
Alex Lorenz78d78312015-05-28 22:41:12 +0000172
173 if (!In.setCurrentDocument()) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000174 if (In.error())
Alex Lorenz78d78312015-05-28 22:41:12 +0000175 return nullptr;
176 // Create an empty module when the MIR file is empty.
177 return llvm::make_unique<Module>(Filename, Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000178 }
179
Alex Lorenz78d78312015-05-28 22:41:12 +0000180 std::unique_ptr<Module> M;
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000181 bool NoLLVMIR = false;
Alex Lorenz78d78312015-05-28 22:41:12 +0000182 // Parse the block scalar manually so that we can return unique pointer
183 // without having to go trough YAML traits.
184 if (const auto *BSN =
185 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000186 SMDiagnostic Error;
Alex Lorenz78d78312015-05-28 22:41:12 +0000187 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000188 Context, &IRSlots);
Alex Lorenz09b832c2015-05-29 17:05:41 +0000189 if (!M) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000190 reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
Alex Lorenz78d78312015-05-28 22:41:12 +0000191 return M;
Alex Lorenz09b832c2015-05-29 17:05:41 +0000192 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000193 In.nextDocument();
194 if (!In.setCurrentDocument())
195 return M;
196 } else {
197 // Create an new, empty module.
198 M = llvm::make_unique<Module>(Filename, Context);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000199 NoLLVMIR = true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000200 }
201
202 // Parse the machine functions.
203 do {
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000204 if (parseMachineFunction(In, *M, NoLLVMIR))
Alex Lorenz78d78312015-05-28 22:41:12 +0000205 return nullptr;
206 In.nextDocument();
207 } while (In.setCurrentDocument());
208
209 return M;
210}
211
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000212bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
213 bool NoLLVMIR) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000214 auto MF = llvm::make_unique<yaml::MachineFunction>();
215 yaml::yamlize(In, *MF, false);
Alex Lorenz78d78312015-05-28 22:41:12 +0000216 if (In.error())
217 return true;
Alex Lorenz735c47e2015-06-15 20:30:22 +0000218 auto FunctionName = MF->Name;
Alex Lorenzfe2aa972015-06-15 22:23:23 +0000219 if (Functions.find(FunctionName) != Functions.end())
220 return error(Twine("redefinition of machine function '") + FunctionName +
221 "'");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000222 Functions.insert(std::make_pair(FunctionName, std::move(MF)));
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000223 if (NoLLVMIR)
224 createDummyFunction(FunctionName, M);
Alex Lorenz5ef16b82015-06-16 17:06:29 +0000225 else if (!M.getFunction(FunctionName))
226 return error(Twine("function '") + FunctionName +
227 "' isn't defined in the provided LLVM IR");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000228 return false;
229}
230
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000231void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
232 auto &Context = M.getContext();
233 Function *F = cast<Function>(M.getOrInsertFunction(
234 Name, FunctionType::get(Type::getVoidTy(Context), false)));
235 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
236 new UnreachableInst(Context, BB);
237}
238
Alex Lorenz735c47e2015-06-15 20:30:22 +0000239bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
240 auto It = Functions.find(MF.getName());
241 if (It == Functions.end())
242 return error(Twine("no machine function information for function '") +
243 MF.getName() + "' in the MIR file");
244 // TODO: Recreate the machine function.
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000245 const yaml::MachineFunction &YamlMF = *It->getValue();
246 if (YamlMF.Alignment)
247 MF.setAlignment(YamlMF.Alignment);
248 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
249 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
Alex Lorenz54565cf2015-06-24 19:56:10 +0000250 if (initializeRegisterInfo(MF.getRegInfo(), YamlMF))
251 return true;
Alex Lorenz60541c12015-07-09 19:55:27 +0000252 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF.FrameInfo))
253 return true;
Alex Lorenz54565cf2015-06-24 19:56:10 +0000254
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000255 PerFunctionMIParsingState PFS;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000256 const auto &F = *MF.getFunction();
257 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
258 const BasicBlock *BB = nullptr;
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000259 const yaml::StringValue &Name = YamlMBB.Name;
260 if (!Name.Value.empty()) {
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000261 BB = dyn_cast_or_null<BasicBlock>(
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000262 F.getValueSymbolTable().lookup(Name.Value));
Alex Lorenz00302df2015-06-19 20:12:03 +0000263 if (!BB)
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000264 return error(Name.SourceRange.Start,
265 Twine("basic block '") + Name.Value +
266 "' is not defined in the function '" + MF.getName() +
267 "'");
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000268 }
269 auto *MBB = MF.CreateMachineBasicBlock(BB);
270 MF.insert(MF.end(), MBB);
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000271 bool WasInserted =
272 PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000273 if (!WasInserted)
274 return error(Twine("redefinition of machine basic block with id #") +
275 Twine(YamlMBB.ID));
276 }
277
278 // Initialize the machine basic blocks after creating them all so that the
279 // machine instructions parser can resolve the MBB references.
280 unsigned I = 0;
281 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
282 if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000283 PFS))
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000284 return true;
285 }
286 return false;
287}
288
289bool MIRParserImpl::initializeMachineBasicBlock(
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000290 MachineFunction &MF, MachineBasicBlock &MBB,
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000291 const yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000292 const PerFunctionMIParsingState &PFS) {
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000293 MBB.setAlignment(YamlMBB.Alignment);
294 if (YamlMBB.AddressTaken)
295 MBB.setHasAddressTaken();
296 MBB.setIsLandingPad(YamlMBB.IsLandingPad);
Alex Lorenzf09df002015-06-30 18:16:42 +0000297 SMDiagnostic Error;
298 // Parse the successors.
299 for (const auto &MBBSource : YamlMBB.Successors) {
300 MachineBasicBlock *SuccMBB = nullptr;
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000301 if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, PFS, IRSlots,
Alex Lorenzf09df002015-06-30 18:16:42 +0000302 Error))
303 return error(Error, MBBSource.SourceRange);
304 // TODO: Report an error when adding the same successor more than once.
305 MBB.addSuccessor(SuccMBB);
306 }
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000307 // Parse the instructions.
308 for (const auto &MISource : YamlMBB.Instructions) {
Alex Lorenz3708a642015-06-30 17:47:50 +0000309 MachineInstr *MI = nullptr;
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000310 if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error))
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000311 return error(Error, MISource.SourceRange);
Alex Lorenz3708a642015-06-30 17:47:50 +0000312 MBB.insert(MBB.end(), MI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000313 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000314 return false;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000315}
316
Alex Lorenz54565cf2015-06-24 19:56:10 +0000317bool MIRParserImpl::initializeRegisterInfo(
318 MachineRegisterInfo &RegInfo, const yaml::MachineFunction &YamlMF) {
319 assert(RegInfo.isSSA());
320 if (!YamlMF.IsSSA)
321 RegInfo.leaveSSA();
322 assert(RegInfo.tracksLiveness());
323 if (!YamlMF.TracksRegLiveness)
324 RegInfo.invalidateLiveness();
325 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
326 return false;
327}
328
Alex Lorenz60541c12015-07-09 19:55:27 +0000329bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI,
330 const yaml::MachineFrameInfo &YamlMFI) {
331 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
332 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
333 MFI.setHasStackMap(YamlMFI.HasStackMap);
334 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
335 MFI.setStackSize(YamlMFI.StackSize);
336 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
337 if (YamlMFI.MaxAlignment)
338 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
339 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
340 MFI.setHasCalls(YamlMFI.HasCalls);
341 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
342 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
343 MFI.setHasVAStart(YamlMFI.HasVAStart);
344 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
345 return false;
346}
347
Alex Lorenz51af1602015-06-23 22:39:23 +0000348SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
349 SMRange SourceRange) {
350 assert(SourceRange.isValid() && "Invalid source range");
351 SMLoc Loc = SourceRange.Start;
352 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
353 *Loc.getPointer() == '\'';
354 // Translate the location of the error from the location in the MI string to
355 // the corresponding location in the MIR file.
356 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
357 (HasQuote ? 1 : 0));
358
359 // TODO: Translate any source ranges as well.
360 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
361 Error.getFixIts());
362}
363
Alex Lorenz09b832c2015-05-29 17:05:41 +0000364SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
365 SMRange SourceRange) {
366 assert(SourceRange.isValid());
367
368 // Translate the location of the error from the location in the llvm IR string
369 // to the corresponding location in the MIR file.
370 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
371 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
372 unsigned Column = Error.getColumnNo();
373 StringRef LineStr = Error.getLineContents();
374 SMLoc Loc = Error.getLoc();
375
376 // Get the full line and adjust the column number by taking the indentation of
377 // LLVM IR into account.
378 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
379 L != E; ++L) {
380 if (L.line_number() == Line) {
381 LineStr = *L;
382 Loc = SMLoc::getFromPointer(LineStr.data());
383 auto Indent = LineStr.find(Error.getLineContents());
384 if (Indent != StringRef::npos)
385 Column += Indent;
386 break;
387 }
388 }
389
390 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
391 Error.getMessage(), LineStr, Error.getRanges(),
392 Error.getFixIts());
393}
394
Alex Lorenz735c47e2015-06-15 20:30:22 +0000395MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
396 : Impl(std::move(Impl)) {}
397
398MIRParser::~MIRParser() {}
399
400std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
401
402bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
403 return Impl->initializeMachineFunction(MF);
404}
405
406std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
407 SMDiagnostic &Error,
408 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000409 auto FileOrErr = MemoryBuffer::getFile(Filename);
410 if (std::error_code EC = FileOrErr.getError()) {
411 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
412 "Could not open input file: " + EC.message());
Alex Lorenz735c47e2015-06-15 20:30:22 +0000413 return nullptr;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000414 }
Alex Lorenz735c47e2015-06-15 20:30:22 +0000415 return createMIRParser(std::move(FileOrErr.get()), Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000416}
417
Alex Lorenz735c47e2015-06-15 20:30:22 +0000418std::unique_ptr<MIRParser>
419llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
420 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000421 auto Filename = Contents->getBufferIdentifier();
Alex Lorenz735c47e2015-06-15 20:30:22 +0000422 return llvm::make_unique<MIRParser>(
423 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000424}