[cfe-dev] compiling to/from std::string

Eli Friedman eli.friedman at gmail.com
Wed May 5 12:04:09 PDT 2010


On Wed, May 5, 2010 at 11:34 AM, Joshua Housh <joshua.housh at gmail.com> wrote:
> 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<unnamed>::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=<value optimized out>) 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=<value optimized out>, line=241,
>     function=0x1a5ca80 "virtual
> void<unnamed>::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




More information about the cfe-dev mailing list