compiling to/from std::string

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

compiling to/from std::string

Joshua Housh
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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: compiling to/from std::string

Eli Friedman
On Wed, May 5, 2010 at 11:34 AM, Joshua Housh <[hidden email]> 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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: compiling to/from std::string

Eli Friedman
On Wed, May 5, 2010 at 1:51 PM, Joshua Housh <[hidden email]> wrote:

> Hi,
>
> The following arguments were the result of me printing out the args in a
> call to clang ("./clang test.c"):
>
> std::vector<std::string> args = std::vector<std::string>();
> args.push_back("test2.c");
> args.push_back("-resource-dir");
> args.push_back("/home/joshua/llvm/Debug/lib/clang/1.5");
> args.push_back("-fdollars-in-identifiers");
> args.push_back("-fno-operator-names");
> args.push_back("-ftemplate-depth");
> args.push_back("99");
> args.push_back("-triple");
> args.push_back("x86_64-unknown-linux-gnu");

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
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev