[cfe-dev] Help on Generating LLVM Module from C++ file using libClang
WENZHI CUI via cfe-dev
cfe-dev at lists.llvm.org
Mon Nov 20 08:49:31 PST 2017
Hi everyone,
I want to generate LLVM Module from a C++ file using the LibClang C++
API. I am using clang 5.0.0 compiled from source. Currently, I am
using EmitLLVMOnlyAction (as in clang-interpreter) to generate the LLVM
Module.
Unfortunately, I got an error "clang: Not enough positional command line
arguments specified! Must specify at least 1 positional argument: See:
clang -help" when I run ExecuteAction() on a CompilerInvocation object. I
though this might be a missing argument problem so I printed out the
driver::Command object which I used to create the CompilerInvocation object
(I am using CompilerInvocation::CreateFromArgs() to create the object):
"/home/cwz/llvm-root/build-5.0.0/bin/clang++" -cc1 -triple
nvptx64-nvidia-cuda -emit-llvm-bc -emit-llvm-uselists -disable-free
-main-file-name dummy.cpp -mrelocation-model static -mthread-model posix
-mdisable-fp-elim -fmath-errno -no-integrated-as -dwarf-column-info
-debugger-tuning=gdb -coverage-notes-file /home/cwz/piko-public/pikoc/
samples/rasterPipelineFixPt/dummy.gcno -resource-dir
/home/cwz/llvm-root/build-5.0.0/lib/clang/5.0.0 -I /usr/local/cuda/include
-I ../../api/include -I ../../include -I basicTypes -I EasyBMP -I
sceneParser -I util -I assimp/include -I bezmesh -D __PIKOC__ -D
__PIKOC_DEVICE__ -I /home/cwz/piko-public/pikoc/samples/rasterPipelineFixPt
-I /home/cwz/llvm-root/build-5.0.0/lib/clang/5.0.0/include -I
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0 -I
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/x86_64-linux-gnu/c++/5.4.0
-I /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/backward
-I /usr/local/include -I /include -I /usr/include -I
/usr/include/x86_64-linux-gnu -fdeprecated-macro -fno-dwarf-directory-asm
-fdebug-compilation-dir /home/cwz/piko-public/pikoc/samples/rasterPipelineFixPt
-ferror-limit 19 -fmessage-length 204 -fobjc-runtime=gcc -fcxx-exceptions
-fexceptions -fdiagnostics-show-option -o dummy.bc -x c++ dummy.cpp
The dummy.cpp is the C++ file I want to compile to LLVM Module. The
argument seems legit to me and I can compile dummy.cpp using clang from
command line so I think the C++ file is good.
Can anyone help me figure out why I am getting the not enogh positional
argument error or point me to a better way to do this? Thanks in advance
for your help.
Best wishes,
Wenzhi Cui
The complete code snippet is here:
bool PikoBackend::createLLVMModule() {
std::string Path = "/home/cwz/llvm-root/build-5.0.0/bin/clang++";
llvm::errs() << "Path=" << Path << "\n";
llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new
DiagnosticOptions();
TextDiagnosticPrinter *DiagClient =
new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
std::string TripleStr = this->getTargetTriple() + "-" + "cuda";
llvm::Triple T(TripleStr);
Driver TheDriver(Path, T.str(), Diags);
TheDriver.setTitle("PikoPipe");
TheDriver.setCheckInputsExist(false);
llvm::SmallVector<const char *, 32> Args(pikocOptions.Argv,
pikocOptions.Argv + pikocOptions.Argc);
Args.push_back("-D__PIKOC__");
Args.push_back("-D__PIKOC_DEVICE__");
Args.push_back("-c");
Args.push_back("-emit-llvm");
Args.push_back("-xc++");
std::string include("-I");
auto include_cwd = include + pikocOptions.workingDir;
Args.push_back(include_cwd.c_str());
auto include_piko = include + pikocOptions.pikoIncludeDir;
Args.push_back(include_piko.c_str());
auto include_res = include + pikocOptions.clangResourceDir;
Args.push_back(include_res.c_str());
for(int i = 0; i < pikocOptions.includeDirs.size(); ++i) {
Args.push_back("-I");
Args.push_back(pikocOptions.includeDirs[i].c_str());
}
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args));
if (!C) {
llvm::errs() << "Compilation has problem building it\n";
return false;
}
const driver::JobList &Jobs = C->getJobs();
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
Jobs.Print(OS, "; ", true);
Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
return false;
}
const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
if (llvm::StringRef(Cmd.getCreator().getName()) != "clang") {
Diags.Report(diag::err_fe_expected_clang_command);
return false;
}
// Initialize a compiler invocation object from the clang (-cc1)
arguments.
const driver::ArgStringList &CCArgs = Cmd.getArguments();
Cmd.Print(llvm::errs(), "\n", false);
std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation);
CompilerInvocation::CreateFromArgs(*CI,
const_cast<const char **>(CCArgs.data
()),
const_cast<const char **>(CCArgs.data
()) +
CCArgs.size() - 1,
Diags);
// Show the invocation, with -v.
if (CI->getHeaderSearchOpts().Verbose) {
llvm::errs() << "clang invocation:\n";
Jobs.Print(llvm::errs(), "\n", true);
llvm::errs() << "\n";
}
// FIXME: This is copied from cc1_main.cpp; simplify and eliminate.
// Create a compiler instance to handle the actual work.
CompilerInstance Clang;
Clang.setInvocation(std::move(CI));
Clang.getHeaderSearchOpts().ResourceDir = pikocOptions.clangResourceDir;
// Create the compilers actual diagnostics engine.
Clang.createDiagnostics();
if (!Clang.hasDiagnostics())
return false;
llvm::LLVMContext& ctx = GlobalContext;
// Create and execute the frontend to generate an LLVM bitcode module.
llvm::errs() << "Codegen...\n";
std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&ctx));
if (!Clang.ExecuteAction(*Act)) {
llvm::errs() << "Parsing erros...\n";
return false;
}
if(Clang.getDiagnostics().hasErrorOccurred()) {
llvm::errs() << "Parsing erros in diagnostics...\n";
return false;
}
this->module = Act->takeModule().get();
return true;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171120/7d94e7aa/attachment.html>
More information about the cfe-dev
mailing list