<div class="gmail_quote">On Sat, Nov 12, 2011 at 1:23 AM, Sven Verdoolaege <span dir="ltr"><<a href="mailto:skimo-cfe@kotnet.org">skimo-cfe@kotnet.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":c4k">Let's assume I want to avoid a subprocess.<br>
Maybe there is no need, but that's how I'm doing it now.<br></div></blockquote><div><br></div><div>Entirely reasonable...</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":c4k"><div class="im">> I can sketch out the code to do this if it helps<br>
<br>
</div>If it's not too much trouble for you, then I would appreciate<br>
such a sketch. It may also help others.</div></blockquote></div><br><div>It looks something like the following. I've editted this down heavily from some real code we've used, but I've not even compiled it (as you can tell) so its very pseudo-code-ish... lemme know if you need something more concrete, but hopefully this is enough to get you started:</div>
<div><br></div><div><div>/// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.</div><div>/// Returns NULL on error.</div><div>static const clang::driver::ArgStringList *GetCC1Arguments(</div>
<div> clang::DiagnosticsEngine *Diagnostics,</div><div> clang::driver::Compilation *Compilation) {</div><div> // We expect to get back exactly one Command job, if we didn't something</div><div> // failed. Extract that job from the Compilation.</div>
<div> const clang::driver::JobList &Jobs = Compilation->getJobs();</div><div> if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {</div><div> // diagnose this...</div><div> return NULL;</div>
<div> }</div><div><br></div><div> // The one job we find should be to invoke clang again.</div><div> const clang::driver::Command *Cmd = cast<clang::driver::Command>(*Jobs.begin());</div><div> if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {</div>
<div> // diagnose this...</div><div> return NULL;</div><div> }</div><div><br></div><div> return &Cmd->getArguments();</div><div>}</div><div><br></div><div>const std::vector<char*> Argv = ...; // get this from somewhere...</div>
<div>const char *const BinaryName = Argv[0];</div><div>DiagnosticOptions DefaultDiagnosticOptions;</div><div>TextDiagnosticPrinter DiagnosticPrinter(</div><div> llvm::errs(), DefaultDiagnosticOptions);</div><div>DiagnosticsEngine Diagnostics(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>(</div>
<div> new DiagnosticIDs()), &DiagnosticPrinter, false);</div><div><br></div><div>clang::driver::Driver Driver(..., Diagnostics);</div><div>const llvm::OwningPtr<clang::driver::Compilation> Compilation(</div><div>
Driver.BuildCompilation(llvm::ArrayRef<const char*>(</div><div> &Argv[0], Argv.size() - 1)));</div><div>const clang::driver::ArgStringList *const CC1Args = GetCC1Arguments(</div><div> &Diagnostics, Compilation.get());</div>
<div>if (CC1Args == NULL) {</div><div> return false;</div><div>}</div><div>llvm::OwningPtr<clang::CompilerInvocation> Invocation(</div><div> new clang::CompilerInvocation);</div><div> clang::CompilerInvocation::CreateFromArgs(</div>
<div> *Invocation, CC1Args->data() + 1, CC1Args->data() + CC1Args->size(),</div><div> Diagnostics);</div><div> Invocation->getFrontendOpts().DisableFree = false;</div></div>