compiling to/from std::string

Hi,

So I’m trying to take preprocessed source code (in the form of an std::string) and compile it and have the resulting object code also be outputted into string (bypassing the file system).

My current code:

CompilerInstance Clang;
TextDiagnosticBuffer DiagsBuffer;
CompilerInvocation Invocation;
Diagnostic Diags(&DiagsBuffer);

Clang.setDiagnostics(&Diags);
Clang.setDiagnosticClient(&
DiagsBuffer);
CompilerInvocation::CreateFromArgs(Invocation, (const char **)argAddresses.begin(),
(const char **)argAddresses.end(), Diags);
Clang.setInvocation(&Invocation);

FrontendOptions FeOpts = Clang.getFrontendOpts();
FeOpts.ProgramAction = frontend::EmitObj;
std::vector<std::pair<FrontendOptions::InputKind, std::string> > opts;
std::pair<FrontendOptions::InputKind, std::string> p(FeOpts.IK_PreprocessedCXX, “source”);
opts.push_back(p);
FeOpts.Inputs = opts;

Clang.createFileManager();
Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
Clang.getTargetOpts()));
Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());

// override the source file
llvm::MemoryBuffer* Buffer = llvm::MemoryBuffer::getMemBuffer(Source, “source”);

SourceManager SM(Diags);
Clang.setSourceManager(&SM);
FileManager& FM = Clang.getFileManager();
std::string sourceName(“source”);
const FileEntry* fe = FM.getVirtualFile(sourceName, strlen(Buffer->getBufferStart()), time(NULL));
SM.overrideFileContents(fe, Buffer);

Clang.createPreprocessor();
llvm::LLVMContext llvmc;
Clang.setLLVMContext(&llvmc);

// set the output file
Clang.clearOutputFiles(false);
std::string objectCode;
llvm::raw_string_ostream* OS = new llvm::raw_string_ostream(objectCode);
llvm::sys::Path Path = llvm::sys::Path::GetCurrentDirectory();
llvm::StringRef PathName(Path.getBasename());
Clang.addOutputFile(PathName, OS);

// compile
EmitObjAction E;
E.BeginSourceFile(Clang, sourceName);
E.Execute();
E.EndSourceFile();

I get the following error in E.Execute():

FIXME: MCMachoStreamer:EmitFileDirective not implemented
clang: MCMachOStreamer.cpp:241: virtual void::MCMachOStreamer::EmitSymbolAttribute(llvm::MCSymbol*, llvm::MCSymbolAttr): Assertion `0 && “Invalid symbol attribute for Mach-O!”’ failed.

The backtrace looks like:
#0 0x00007ffff6c81a75 in *__GI_raise (sig=) at …/nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff6c855c0 in *__GI_abort () at abort.c:92
#2 0x00007ffff6c7a941 in __GI___assert_fail (assertion=0x1a5bb30 “0 && “Invalid symbol attribute for Mach-O!””,
file=, line=241,
function=0x1a5ca80 "virtual void::MCMachOStreamer::EmitSymbolAttribute(llvm::MCSymbol
, llvm::MCSymbolAttr)") at assert.c:81
#3 0x0000000001338a41 in EmitSymbolAttribute (this=0x2322230, Symbol=0x23240e0, Attribute=llvm::MCSA_ELF_TypeFunction)
at MCMachOStreamer.cpp:241
#4 0x0000000000fb8802 in llvm::AsmPrinter::EmitFunctionHeader (this=0x2322b00) at AsmPrinter.cpp:322
#5 0x0000000000d86fbe in llvm::X86AsmPrinter::runOnMachineFunction (this=0x2322b00, MF=…) at X86AsmPrinter.cpp:70
#6 0x000000000103865d in llvm::MachineFunctionPass::runOnFunction (this=0x2322b00, F=…) at MachineFunctionPass.cpp:33
#7 0x00000000013f9a2b in llvm::FPPassManager::runOnFunction (this=0x23033c0, F=…) at PassManager.cpp:1418
#8 0x00000000013f96f5 in llvm::FunctionPassManagerImpl::run (this=0x23025c0, F=…) at PassManager.cpp:1369
#9 0x00000000013f93a5 in llvm::FunctionPassManager::run (this=0x22edc70, F=…) at PassManager.cpp:1299
#10 0x0000000000420a25 in EmitAssembly (this=0x22a4e20) at CodeGenAction.cpp:467
#11 0x000000000041f512 in HandleTranslationUnit (this=0x22a4e20, C=…) at CodeGenAction.cpp:165
#12 0x00000000006a0db3 in clang::ParseAST (PP=…, Consumer=0x22a4e20, Ctx=…, PrintStats=false,
CompleteTranslationUnit=true, CompletionConsumer=0x0) at ParseAST.cpp:119
#13 0x0000000000441692 in clang::ASTFrontendAction::ExecuteAction (this=0x7ffff6246ac0) at FrontendAction.cpp:229
#14 0x00000000004412cd in clang::FrontendAction::Execute (this=0x7ffff6246ac0) at FrontendAction.cpp:155

That backtrace looks like a bug in the -integrated-as codepath rather
than an issue with your code. Can you attach the source code and the
command-line arguments you're using?

-Eli

Ah; generating an object file directly only works on OS X at the
moment; there's still some work left to get it working on Linux.

-Eli