<html><head></head><body>Thanks very much, Yaron, that does the job nicely.<br><br>Graham.<br><br><div><span title="yaron.keren@gmail.com">Yaron Keren</span><span class="detail"> <yaron.keren@gmail.com></span> , 1/22/2014 7:56 PM:<br><blockquote class="mori" style="margin:0 0 0 .8ex;border-left:2px blue solid;padding-left:1ex;"><div class="mcnt"><div><div>cling uses this approach so it can add more source lines to the input file as they come in from the user.</div><div><br></div><div>You may have an easier solution: </div><div>

<br></div><div>1 Use SourceManager.getFileManager().getVirtualFile() to create a virtual source file.</div><div>2 Allocate a MemoryBuffer with your sources.</div><div>3 Use overrideFileContents to replace the file contents with the MemoryBuffer.</div>

<div>4 Pass the virtual file file name to <span style="font-size:12.800000190734863px;font-family:arial,sans-serif;">clang::CompilerInstance.</span></div><div><br></div><div><span style="font-family:arial,sans-serif;font-size:12.800000190734863px;">Yaron</span><br>

</div><div><span style="font-family:arial,sans-serif;font-size:12.800000190734863px;"><br></span></div></div><div class="mcntgmail_extra"><br><br><div class="mcntgmail_quote"><div>2014/1/22 Graham Lee <span><<a href="mailto:graham@iamleeg.com" target="_blank" class="mailto">graham@iamleeg.com</a>></span></div>

<blockquote class="mcntgmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div>







<p>Hi all,</p>
<p><br></p>
<p>I’ve got an application that uses the clang frontend to generate a bit code module that’s run by LLVM’s JIT. The current way it works is to take the user-supplied source, write it to a temporary file and construct a clang invocation to compile that source file, based on the code in clang’s examples/clang-interpreter/. That works, but I want to use a memory buffer instead of the main file to avoid making all these temporary files.</p>


<p><br></p>
<p>What I have tried:</p>
<p>- initialising the source manager with my buffer:</p>
<p>  // the args used by the driver have “-“ as the input file</p>
<p>  // and ‘Clang’ is a clang::CompilerInstance</p>
<p>  Clang.setInvocation(CI.take());</p>
<p>  Clang.createDiagnostics();</p>
<p>  if (!Clang.hasDiagnostics())</p>
<p>  {</p>
<p>      if (error)</p>
<p>      {</p>
<p>          *error = [self compilerErrorWithCode:IKBCompilerErrorCouldNotReportUnderlyingErrors compilerOutput:diagnostic_output];</p>
<p>      }</p>
<p>      return nil;</p>
<p>  }</p>
<p><br></p>
<p>  Clang.createFileManager();</p>
<p>  Clang.createSourceManager(Clang.getFileManager());</p>
<p>  llvm::StringRef sourceString([source UTF8String]);</p>
<p>  llvm::MemoryBuffer* mainFile = llvm::MemoryBuffer::getMemBuffer(sourceString);</p>
<p>  FrontendInputFile inputFile(mainFile, IK_ObjC);</p>
<p>  Clang.InitializeSourceManager(inputFile);</p>
<p><br></p>
<p><span>- creating a main file ID with the buffer. I used the approach taken by cling here: <a href="https://github.com/cxx-hep/root-cern/blob/be3c582075364538f14b65ba5f528f730ef8f2ba/interpreter/cling/lib/Interpreter/CIFactory.cpp#L239-L263" target="_blank"><span>https://github.com/cxx-hep/root-cern/blob/be3c582075364538f14b65ba5f528f730ef8f2ba/interpreter/cling/lib/Interpreter/CIFactory.cpp#L239-L263</span></a></span></p>


<p>- following the other branch in cling’s example above, I tried setting the main file’s content buffer to be my buffer.</p>
<p><br></p>
<p>In each case, I try to execute an EmitLLVMOnlyAction(). This waits without completing, and I find that the application has paused in ::read(), waiting for data from stdin. Indeed if I launch my application from the terminal and press Ctrl-D when I get to that point, this happens:</p>


<p><br></p>
<p>Assertion failed: ((!RequiresNullTerminator || BufEnd[0] == 0) && "Buffer is not null terminated!"), function init, file /Users/leeg/Documents/OtherProjects/llvm/lib/Support/MemoryBuffer.cpp, line 57.</p>


<p><br></p>
<p>So it seems that none of the three things I have tried above has actually convinced the compiler instance that it should read the main file from my buffer, instead of stdin. Clearly I’ve missed some step in the problem, but can someone please tell me what that step is?</p>


<p><br></p>
<p><span>For more context, the full application is at <a href="https://bitbucket.org/iamleeg/ikbclassbrowser" target="_blank"><span>https://bitbucket.org/iamleeg/ikbclassbrowser</span></a> and the (current, working) way to invoke clang is at <a href="https://bitbucket.org/iamleeg/ikbclassbrowser/src/2ea5643705fdeccd3c2bea08c516e3289f9a9fd8/ClassBrowser/Code%20Execution/IKBClangCompiler.mm?at=master#cl-80" target="_blank"><span>https://bitbucket.org/iamleeg/ikbclassbrowser/src/2ea5643705fdeccd3c2bea08c516e3289f9a9fd8/ClassBrowser/Code%20Execution/IKBClangCompiler.mm?at=master#cl-80</span></a>.</span></p>


<p><br></p>
<p>Thanks,</p>
<p>Graham.</p></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" class="mailto">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>
</div></blockquote></div></body></html>