static std::unique_ptr<llvm::Module> getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path, IntrusiveRefCntPtr<vfs::FileSystem> VFS) { CompilerInstance Clang; Clang.createDiagnostics(); Clang.setVirtualFileSystem(&*VFS); #if CLANG_VERSION_MAJOR < 4 IntrusiveRefCntPtr<CompilerInvocation> CI = createCompilerInvocation(std::move(CFlags), Path, Clang.getDiagnostics()); Clang.setInvocation(&*CI); #else std::shared_ptr<CompilerInvocation> CI( createCompilerInvocation(std::move(CFlags), Path, Clang.getDiagnostics())); Clang.setInvocation(CI); #endif std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx)); if (!Clang.ExecuteAction(*Act)) return std::unique_ptr<llvm::Module>(nullptr); return Act->takeModule(); }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; MyASTConsumer *astConsumer = new MyASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
/****************************************************************************** * This tutorial just shows off the steps needed to build up to a Preprocessor * object. Note that the order below is important. *****************************************************************************/ int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; TextDiagnosticPrinter *pTextDiagnosticPrinter = new TextDiagnosticPrinter( llvm::outs(), &diagnosticOptions, true); ci.createDiagnostics(pTextDiagnosticPrinter); llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); return 0; }
int main() { CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.getHeaderSearchOpts().AddPath( StringRef("../usr/lib/clang/3.0/include"), frontend::Angled, false, false, false ); ci.getHeaderSearchOpts().AddPath( StringRef("support"), frontend::Quoted, true, false, false ); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); PrintFunctionsConsumer *astConsumer = new PrintFunctionsConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile("julia.h"); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
//===----------------------------------------------------------------------===// // MAIN FUNCTION //===----------------------------------------------------------------------===// int main(int argc, char *argv[]) { struct stat filestat; // Single argument check if (argc != 2) { errs() << "Usage: "PROGRAM_NAME" <filename>\n"; return 1; } // File existence check std::string fname(argv[argc - 1]); if (stat(fname.c_str(), &filestat) == -1) { perror(fname.c_str()); exit(EXIT_FAILURE); } CompilerInstance compiler; DiagnosticOptions diagnosticOptions; TextDiagnosticPrinter *pTextDiagnosticPrinter = new TextDiagnosticPrinter(outs(),&diagnosticOptions,true); compiler.createDiagnostics(pTextDiagnosticPrinter); compiler.getDiagnosticClient().EndSourceFile(); return 0; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: rewritersample <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(); LangOptions &lo = TheCompInst.getLangOpts(); lo.CPlusPlus = 1; // Initialize target info with the default triple for our platform. auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(TU_Module); TheCompInst.createASTContext(); // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(argv[1]); SourceMgr.setMainFileID( SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User)); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MyASTConsumer TheConsumer(TheRewriter); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext()); // At this point the rewriter's buffer should be full with the rewritten // file contents. const RewriteBuffer *RewriteBuf = TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end()); return 0; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: rewritersample <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance ci; ci.createDiagnostics(0, 0); // Initialize target info with the default triple for our platform. TargetOptions TO; TO.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo( ci.getDiagnostics(), TO); ci.setTarget(TI); ci.createFileManager(); FileManager &fm = ci.getFileManager(); ci.createSourceManager(fm); SourceManager &SourceMgr = ci.getSourceManager(); ci.createPreprocessor(); ci.createASTContext(); // A Rewriter helps us manage the code rewriting task. Rewriter rw; rw.setSourceMgr(SourceMgr, ci.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *fi = fm.getFile(argv[1]); SourceMgr.createMainFileID(fi); ci.getDiagnosticClient().BeginSourceFile( ci.getLangOpts(), &ci.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MyASTConsumer astc(rw); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(ci.getPreprocessor(), &astc, ci.getASTContext()); // At this point the rewriter's buffer should be full with the rewritten // file contents. const RewriteBuffer *rwb = rw.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << string(rwb->begin(), rwb->end()); return 0; }
vector<uint8_t> ClangCompilerBackend<T>::compileEBPFObject(const string _code) { // Send code trough pipe to stdin int codeInPipe[2]; pipe2(codeInPipe, O_NONBLOCK); write(codeInPipe[1], (void *) _code.c_str(), _code.length()); close(codeInPipe[1]); // We need to close the pipe to send an EOF int stdinCopy = dup(STDIN_FILENO); dup2(codeInPipe[0], STDIN_FILENO); // Prepare reception of code trought stdou int codeOutPipe[2]; pipe(codeOutPipe); int stdoutCopy = dup(STDOUT_FILENO); dup2(codeOutPipe[1], STDOUT_FILENO); // Initialize various LLVM/Clang components InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllTargets(); // Prepare compilation arguments vector<const char *> args; args.push_back("--target=bpf"); // Target is bpf assembly args.push_back("-xc"); // Code is in c language args.push_back("-"); // Read code from stdiargs.push_back("-strip-debug"); // Strip symbols // Initialize CompilerInvocation CompilerInvocation *CI = createInvocationFromCommandLine(makeArrayRef(args) , NULL); // Create CompilerInstance CompilerInstance Clang; Clang.setInvocation(CI); // Initialize CompilerInstace Clang.createDiagnostics(); // Create and execute action CodeGenAction *compilerAction; compilerAction = new EmitObjAction(); Clang.ExecuteAction(*compilerAction); // Get compiled object close(codeInPipe[0]); vector<uint8_t> objBuffer(2048); int bytesRead = read(codeOutPipe[0], objBuffer.data(), objBuffer.size()); objBuffer.resize(bytesRead); // Cleanup dup2(stdinCopy, STDIN_FILENO); dup2(stdoutCopy, STDOUT_FILENO); return objBuffer; }
int main (int argc, char* argv[]) { // Process our own command line options and remove them from the arguments // before letting the compiler invocation process the arguments. Arguments arguments; handleCommandLineOptions(argc, argv, arguments); CompilerInstance compiler; // Create diagnostics so errors while processing command line arguments can // be reported. compiler.createDiagnostics(argc, argv); CompilerInvocation::CreateFromArgs( compiler.getInvocation(), &arguments[0], &arguments[0] + arguments.size(), compiler.getDiagnostics()); if (!handleFrontEndOptions(compiler.getFrontendOpts())) { return EXIT_FAILURE; } compiler.getInvocation().setLangDefaults(IK_CXX); if (compiler.getHeaderSearchOpts().UseBuiltinIncludes && compiler.getHeaderSearchOpts().ResourceDir.empty()) { compiler.getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath( argv[0], reinterpret_cast<void*>(showHelp)); } if (compiler.getLangOpts().MicrosoftMode) { // TODO: Kludge to allow clang to parse Microsoft headers. // Visual C++ does name resolution at template instantiation, but clang does // name resolution at template definition. A Microsoft header defines a // template referencing _invalid_parameter_noinfo but is not declared at // that point. It is declared later in the <xutility> header file. } UnnecessaryIncludeFinderAction action; compiler.ExecuteAction(action); bool foundUnnecessary = action.reportUnnecessaryIncludes( compiler.getSourceManager()); llvm_shutdown(); return foundUnnecessary ? EXIT_FAILURE : exitStatus; }
CompilerInstance *createCompilerInstance(int argc, const char **argv) { std::string path = getExecutablePath(argv[0]); IntrusiveRefCntPtr<DiagnosticOptions> diag_options = new DiagnosticOptions; TextDiagnosticPrinter *diag_client = new TextDiagnosticPrinter(llvm::errs(), &*diag_options); IntrusiveRefCntPtr<DiagnosticIDs> diag_id = new DiagnosticIDs; DiagnosticsEngine diagnostics(diag_id, &*diag_options, diag_client); Driver driver{path, llvm::sys::getDefaultTargetTriple(), diagnostics}; driver.setTitle("Meditation"); llvm::SmallVector<const char*, 256> args; llvm::SpecificBumpPtrAllocator<char> argAllocator; std::error_code EC = llvm::sys::Process::GetArgumentVector(args, llvm::makeArrayRef(argv, argc), argAllocator); args.push_back("-fsyntax-only"); if(EC){ llvm::errs()<<"Cannot get arguments: " << EC.message() << '\n'; } unique_ptr<Compilation> compilation(driver.BuildCompilation(args)); if(compilation->getJobs().size()!=1 || !llvm::isa<Command>(*(compilation->getJobs().begin()))) { llvm::SmallString<256> msg; llvm::raw_svector_ostream out(msg); compilation->getJobs().Print(out, "; ", true); diagnostics.Report(clang::diag::err_fe_expected_compiler_job) << out.str(); return nullptr; } const Command& command = llvm::cast<Command>(*(compilation->getJobs().begin())); if (StringRef(command.getCreator().getName()) != "clang") { diagnostics.Report(clang::diag::err_fe_expected_clang_command); return nullptr; } const clang::driver::ArgStringList &cc_arguments = command.getArguments(); unique_ptr<CompilerInvocation> invocation(new CompilerInvocation); CompilerInvocation::CreateFromArgs(*invocation, cc_arguments.data(), cc_arguments.data()+cc_arguments.size(), diagnostics); invocation->getFrontendOpts().DisableFree = false; CompilerInstance *compiler = new CompilerInstance; compiler->setInvocation(invocation.release()); compiler->createDiagnostics(); if(!compiler->hasDiagnostics()) return nullptr; if(compiler->getHeaderSearchOpts().UseBuiltinIncludes && compiler->getHeaderSearchOpts().ResourceDir.empty()){ compiler->getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(argv[0], (void*)(intptr_t)getExecutablePath); } return compiler; }
int csabase::run(int argc_, const char **argv_) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc_, argv_); SmallVector<const char *, 1024> argv; SpecificBumpPtrAllocator<char> ArgAllocator; StringSetSaver Saver; sys::Process::GetArgumentVector(argv, ArrayRef<const char *>(argv_, argc_), ArgAllocator); cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, argv); argv.insert(argv.begin() == argv.end() ? argv.begin() : argv.begin() + 1, "-xc++"); llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmParser(); CompilerInstance Clang; TextDiagnosticBuffer DiagsBuffer; IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, &DiagsBuffer, false); bool Success = CompilerInvocation::CreateFromArgs( Clang.getInvocation(), argv.data() + 1, argv.data() + argv.size(), Diags); Clang.createDiagnostics(); install_fatal_error_handler(LLVMErrorHandler, &Clang.getDiagnostics()); DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); if (Success) { Success = ExecuteCompilerInvocation(&Clang); } remove_fatal_error_handler(); llvm::llvm_shutdown(); return !Success; }
void checkVariables(string filename, vector<Issue>& lineIssues){ // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(); CompilerInvocation TheCompInv; LangOptions &lo = TheCompInst.getLangOpts(); lo.CPlusPlus = 1; lo.Bool = 1; lo.WChar = 1; lo.NoBuiltin = 0; // Initialize target info with the default triple for our platform. auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(TU_Module); Preprocessor& pp = TheCompInst.getPreprocessor(); pp.getBuiltinInfo().InitializeBuiltins(pp.getIdentifierTable(), lo); //pp.getLangOpts().NoBuiltin); TheCompInst.createASTContext(); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(filename); SourceMgr.setMainFileID( SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User)); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); MyASTConsumer consm{lineIssues, SourceMgr}; ParseAST(TheCompInst.getPreprocessor(), &consm, TheCompInst.getASTContext()); }
int main(int argc, char *argv[]) { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::ASTConsumer; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance CI; DiagnosticOptions diagnosticOptions; TextDiagnosticPrinter *pTextDiagnosticPrinter = new TextDiagnosticPrinter( llvm::outs(), diagnosticOptions, true); CI.createDiagnostics(0, NULL, pTextDiagnosticPrinter); TargetOptions targetOptions; targetOptions.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pTargetInfo = TargetInfo::CreateTargetInfo( CI.getDiagnostics(), targetOptions); CI.setTarget(pTargetInfo); CI.createFileManager(); CI.createSourceManager(CI.getFileManager()); CI.createPreprocessor(); CI.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); CI.setASTConsumer(astConsumer); CI.createASTContext(); CI.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = CI.getFileManager().getFile(argv[1]); CI.getSourceManager().createMainFileID(pFile); CI.getASTContext().BuiltinInfo.InitializeBuiltins( CI.getPreprocessor().getIdentifierTable(), CI.getLangOpts()); CI.getDiagnosticClient().BeginSourceFile( CI.getLangOpts(), &(CI.getPreprocessor())); clang::ParseAST(CI.getSema()); CI.getDiagnosticClient().EndSourceFile(); return 0; }
int main(int argc, const char *argv[]) { struct stat sb; if (argc != 2) { std::cout << "Usage: ./PrintFunctionInfo <filename>" << std::endl; exit(1); } if (stat(argv[1], &sb) == -1) { perror(argv[1]); exit(EXIT_FAILURE); } CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; FunctionLocConsumer *astConsumer = new FunctionLocConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); const FileEntry *pFile = ci.getFileManager().getFile(argv[1]); ci.getSourceManager().createMainFileID(pFile); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext()); ci.getDiagnosticClient().EndSourceFile(); return 0; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; ci.createDiagnostics(); llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); #ifdef CLANG_3_5 ci.createPreprocessor(clang::TU_Complete); #else ci.createPreprocessor(); #endif ci.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); clang::ParseAST(ci.getSema()); ci.getASTContext().Idents.PrintStats(); return 0; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; CompilerInstance ci; ci.createDiagnostics(0,NULL); TargetOptions to; to.Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = false; ASTConsumer *astConsumer = new ASTConsumer(); ci.setASTConsumer(astConsumer); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().createMainFileID(pFile); ci.getPreprocessor().EnterMainSourceFile(); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); Parser parser(ci.getPreprocessor(), ci.getSema(), false /*skipFunctionBodies*/); parser.ParseTranslationUnit(); ci.getDiagnosticClient().EndSourceFile(); ci.getASTContext().Idents.PrintStats(); return 0; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::ASTContext; using clang::ASTConsumer; using clang::Parser; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; ci.createDiagnostics(); std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>(); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(clang::TU_Complete); ci.getPreprocessorOpts().UsePredefines = false; ci.setASTConsumer(llvm::make_unique<ASTConsumer>()); ci.createASTContext(); ci.createSema(clang::TU_Complete, NULL); const FileEntry *pFile = ci.getFileManager().getFile("test.c"); ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); clang::ParseAST(ci.getSema()); ci.getASTContext().Idents.PrintStats(); return 0; }
/// \brief Compile a module file for the given module, using the options /// provided by the importing compiler instance. static void compileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName) { llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: return; case llvm::LockFileManager::LFS_Owned: // We're responsible for building the module ourselves. Do so below. break; case llvm::LockFileManager::LFS_Shared: // Someone else is responsible for building the module. Wait for them to // finish. Locked.waitForUnlock(); return; } ModuleMap &ModMap = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); // Construct a compiler invocation for creating this module. IntrusiveRefCntPtr<CompilerInvocation> Invocation (new CompilerInvocation(ImportingInstance.getInvocation())); PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); // For any options that aren't intended to affect how a module is built, // reset them to their default values. Invocation->getLangOpts()->resetNonModularOptions(); PPOpts.resetNonModularOptions(); // Note the name of the module we're building. Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); // Make sure that the failed-module structure has been allocated in // the importing instance, and propagate the pointer to the newly-created // instance. PreprocessorOptions &ImportingPPOpts = ImportingInstance.getInvocation().getPreprocessorOpts(); if (!ImportingPPOpts.FailedModules) ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; PPOpts.FailedModules = ImportingPPOpts.FailedModules; // If there is a module map file, build the module using the module map. // Set up the inputs/outputs so that we build the module from its umbrella // header. FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); FrontendOpts.OutputFile = ModuleFileName.str(); FrontendOpts.DisableFree = false; FrontendOpts.Inputs.clear(); InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); // Get or create the module map that we'll use to build this module. SmallString<128> TempModuleMapFileName; if (const FileEntry *ModuleMapFile = ModMap.getContainingModuleMapFile(Module)) { // Use the module map where this module resides. FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(), IK)); } else { // Create a temporary module map file. TempModuleMapFileName = Module->Name; TempModuleMapFileName += "-%%%%%%%%.map"; int FD; if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD, TempModuleMapFileName, /*makeAbsolute=*/true) != llvm::errc::success) { ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file) << TempModuleMapFileName; return; } // Print the module map to this file. llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true); Module->print(OS); FrontendOpts.Inputs.push_back( FrontendInputFile(TempModuleMapFileName.str().str(), IK)); } // Don't free the remapped file buffers; they are owned by our caller. PPOpts.RetainRemappedFileBuffers = true; Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; assert(ImportingInstance.getInvocation().getModuleHash() == Invocation->getModuleHash() && "Module hash mismatch!"); // Construct a compiler instance that will be used to actually create the // module. CompilerInstance Instance; Instance.setInvocation(&*Invocation); Instance.createDiagnostics(/*argc=*/0, /*argv=*/0, &ImportingInstance.getDiagnosticClient(), /*ShouldOwnClient=*/true, /*ShouldCloneClient=*/true); // Note that this module is part of the module build stack, so that we // can detect cycles in the module graph. Instance.createFileManager(); // FIXME: Adopt file manager from importer? Instance.createSourceManager(Instance.getFileManager()); SourceManager &SourceMgr = Instance.getSourceManager(); SourceMgr.setModuleBuildStack( ImportingInstance.getSourceManager().getModuleBuildStack()); SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); // Construct a module-generating action. GenerateModuleAction CreateModuleAction; // Execute the action to actually build the module in-place. Use a separate // thread so that we get a stack large enough. const unsigned ThreadStackSize = 8 << 20; llvm::CrashRecoveryContext CRC; CompileModuleMapData Data = { Instance, CreateModuleAction }; CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize); // Delete the temporary module map file. // FIXME: Even though we're executing under crash protection, it would still // be nice to do this with RemoveFileOnSignal when we can. However, that // doesn't make sense for all clients, so clean this up manually. Instance.clearOutputFiles(/*EraseFiles=*/true); if (!TempModuleMapFileName.empty()) llvm::sys::Path(TempModuleMapFileName).eraseFromDisk(); }
CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer, int argc, const char* const *argv, const char* llvmdir) { // Create an instance builder, passing the llvmdir and arguments. // // Initialize the llvm library. llvm::InitializeNativeTarget(); llvm::InitializeAllAsmPrinters(); llvm::sys::Path resource_path; if (llvmdir) { resource_path = llvmdir; resource_path.appendComponent("lib"); resource_path.appendComponent("clang"); resource_path.appendComponent(CLANG_VERSION_STRING); } else { // FIXME: The first arg really does need to be argv[0] on FreeBSD. // // Note: The second arg is not used for Apple, FreeBSD, Linux, // or cygwin, and can only be used on systems which support // the use of dladdr(). // // Note: On linux and cygwin this uses /proc/self/exe to find the path. // // Note: On Apple it uses _NSGetExecutablePath(). // // Note: On FreeBSD it uses getprogpath(). // // Note: Otherwise it uses dladdr(). // resource_path = CompilerInvocation::GetResourcesPath("cling", (void*)(intptr_t) locate_cling_executable ); } if (!resource_path.canRead()) { llvm::errs() << "ERROR in cling::CIFactory::createCI():\n resource directory " << resource_path.str() << " not found!\n"; resource_path = ""; } //______________________________________ DiagnosticOptions* DefaultDiagnosticOptions = new DiagnosticOptions(); DefaultDiagnosticOptions->ShowColors = llvm::sys::Process::StandardErrHasColors() ? 1 : 0; TextDiagnosticPrinter* DiagnosticPrinter = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs()); DiagnosticsEngine* Diagnostics = new DiagnosticsEngine(DiagIDs, DefaultDiagnosticOptions, DiagnosticPrinter, /*Owns it*/ true); // LEAKS! std::vector<const char*> argvCompile(argv, argv + argc); // We do C++ by default; append right after argv[0] name // Only insert it if there is no other "-x": bool haveMinusX = false; for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc; ++iarg) { haveMinusX = !strcmp(*iarg, "-x"); } if (!haveMinusX) { argvCompile.insert(argvCompile.begin() + 1,"-x"); argvCompile.insert(argvCompile.begin() + 2, "c++"); } argvCompile.push_back("-c"); argvCompile.push_back("-"); clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(), "cling.out", *Diagnostics); //Driver.setWarnMissingInput(false); Driver.setCheckInputsExist(false); // think foo.C(12) llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size()); llvm::OwningPtr<clang::driver::Compilation> Compilation(Driver.BuildCompilation(RF)); const clang::driver::ArgStringList* CC1Args = GetCC1Arguments(Diagnostics, Compilation.get()); if (CC1Args == NULL) { return 0; } clang::CompilerInvocation* Invocation = new clang::CompilerInvocation; clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1, CC1Args->data() + CC1Args->size(), *Diagnostics); Invocation->getFrontendOpts().DisableFree = true; if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes && !resource_path.empty()) { // Update ResourceDir // header search opts' entry for resource_path/include isn't // updated by providing a new resource path; update it manually. clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts(); llvm::sys::Path oldResInc(Opts.ResourceDir); oldResInc.appendComponent("include"); llvm::sys::Path newResInc(resource_path); newResInc.appendComponent("include"); bool foundOldResInc = false; for (unsigned i = 0, e = Opts.UserEntries.size(); !foundOldResInc && i != e; ++i) { HeaderSearchOptions::Entry &E = Opts.UserEntries[i]; if (!E.IsFramework && E.Group == clang::frontend::System && E.IgnoreSysRoot && oldResInc.str() == E.Path) { E.Path = newResInc.str(); foundOldResInc = true; } } Opts.ResourceDir = resource_path.str(); } // Create and setup a compiler instance. CompilerInstance* CI = new CompilerInstance(); CI->setInvocation(Invocation); CI->createDiagnostics(DiagnosticPrinter, /*ShouldOwnClient=*/ false, /*ShouldCloneClient=*/ false); { // // Buffer the error messages while we process // the compiler options. // // Set the language options, which cling needs SetClingCustomLangOpts(CI->getLangOpts()); CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__"); if (CI->getLangOpts().CPlusPlus11 == 1) { // http://llvm.org/bugs/show_bug.cgi?id=13530 CI->getInvocation().getPreprocessorOpts() .addMacroDef("__CLING__CXX11"); } if (CI->getDiagnostics().hasErrorOccurred()) { delete CI; CI = 0; return 0; } } CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(), &Invocation->getTargetOpts())); if (!CI->hasTarget()) { delete CI; CI = 0; return 0; } CI->getTarget().setForcedLangOptions(CI->getLangOpts()); SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget()); if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) { // clang "forgets" the basic arch part needed by winnt.h: if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86) { CI->getInvocation().getPreprocessorOpts().addMacroDef("_X86_=1"); } else if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86_64) { CI->getInvocation().getPreprocessorOpts().addMacroDef("__x86_64=1"); } else { llvm::errs() << "Warning: unhandled target architecture " << CI->getTarget().getTriple().getArchName() << '\n'; } } // Set up source and file managers CI->createFileManager(); SourceManager* SM = new SourceManager(CI->getDiagnostics(), CI->getFileManager(), /*UserFilesAreVolatile*/ true); CI->setSourceManager(SM); // FIXME: SM leaks. // Set up the memory buffer if (buffer) CI->getSourceManager().createMainFileIDForMemBuffer(buffer); else { // As main file we want // * a virtual file that is claiming to be huge // * with an empty memory buffer attached (to bring the content) SourceManager& SM = CI->getSourceManager(); FileManager& FM = SM.getFileManager(); // Build the virtual file const char* Filename = "InteractiveInputLineIncluder.h"; const std::string& CGOptsMainFileName = CI->getInvocation().getCodeGenOpts().MainFileName; if (!CGOptsMainFileName.empty()) Filename = CGOptsMainFileName.c_str(); const FileEntry* FE = FM.getVirtualFile(Filename, 1U << 15U, time(0)); FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User); const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID); const SrcMgr::ContentCache* MainFileCC = MainFileSLocE.getFile().getContentCache(); llvm::MemoryBuffer* MainFileMB = llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n"); const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB); } // Set up the preprocessor CI->createPreprocessor(); Preprocessor& PP = CI->getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); // Set up the ASTContext ASTContext *Ctx = new ASTContext(CI->getLangOpts(), PP.getSourceManager(), &CI->getTarget(), PP.getIdentifierTable(), PP.getSelectorTable(), PP.getBuiltinInfo(), /*size_reserve*/0, /*DelayInit*/false); CI->setASTContext(Ctx); // Set up the ASTConsumers CI->setASTConsumer(new DeclCollector()); // Set up Sema CodeCompleteConsumer* CCC = 0; CI->createSema(TU_Complete, CCC); // Set CodeGen options // CI->getCodeGenOpts().DebugInfo = 1; // want debug info // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete // ctor to the base ctor causes // the JIT to crash // When asserts are on, TURN ON not compare the VerifyModule assert(CI->getCodeGenOpts().VerifyModule = 1); return CI; }
int main() { using clang::CompilerInstance; using clang::TargetOptions; using clang::TargetInfo; using clang::FileEntry; using clang::Token; using clang::HeaderSearch; using clang::HeaderSearchOptions; using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; CompilerInstance ci; DiagnosticOptions diagnosticOptions; ci.createDiagnostics(); llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(); ci.getPreprocessorOpts().UsePredefines = true; llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso( new clang::HeaderSearchOptions()); HeaderSearch headerSearch(hso, ci.getFileManager(), ci.getDiagnostics(), ci.getLangOpts(), pti); // <Warning!!> -- Platform Specific Code lives here // This depends on A) that you're running linux and // B) that you have the same GCC LIBs installed that // I do. // Search through Clang itself for something like this, // go on, you won't find it. The reason why is Clang // has its own versions of std* which are installed under // /usr/local/lib/clang/<version>/include/ // See somewhere around Driver.cpp:77 to see Clang adding // its version of the headers to its include path. hso->AddPath("/usr/include", clang::frontend::Angled, false, false); hso->AddPath("/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include", clang::frontend::Angled, false, false); // </Warning!!> -- End of Platform Specific Code clang::InitializePreprocessor(ci.getPreprocessor(), ci.getPreprocessorOpts(), *hso, ci.getFrontendOpts()); const FileEntry *pFile = ci.getFileManager().getFile("testInclude.c"); ci.getSourceManager().createMainFileID(pFile); ci.getPreprocessor().EnterMainSourceFile(); ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); Token tok; do { ci.getPreprocessor().Lex(tok); if( ci.getDiagnostics().hasErrorOccurred()) break; ci.getPreprocessor().DumpToken(tok); std::cerr << std::endl; } while ( tok.isNot(clang::tok::eof)); ci.getDiagnosticClient().EndSourceFile(); return 0; }
int main(int argc, char *argv[]) { #if 0 vector<string> args; args.push_back("tool-executable"); for (int i = 1; i < argc; ++i) { args.push_back(argv[i]); } parse_with_tool(args); return 0; #endif string user_defines; for (int i = 1; i < argc; ++i) { if (argv[i][0] == '-' && argv[i][1] == 'D') { user_defines += "#define "; char *def = argv[i]+2; char* eq_pos = strchr(def, '='); if (eq_pos) { user_defines += string(def, eq_pos - def); user_defines += " "; user_defines += string(def+1); } else { user_defines += string(def); } user_defines += "\n"; } } if (argc < 2) { llvm::errs() << "Usage: mkapi filename [-Ddefine1 -Ddefine2...]\n"; return 1; } string file(argv[1]); // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; TheCompInst.createDiagnostics(0, true); //() for clang3.3, (0,0) for clang3.2 // Initialize target info with the default triple for our platform. TargetOptions *TO = new TargetOptions(); //TODO: why on stack crash when dtor called TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo( TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); TheCompInst.createPreprocessor(); TheCompInst.createASTContext(); if (!user_defines.empty()) { clang::Preprocessor &PP = TheCompInst.getPreprocessor(); PP.setPredefines(PP.getPredefines() + user_defines); } //cout << "predefines: " << TheCompInst.getPreprocessor().getPredefines() << endl; // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(file); SourceMgr.createMainFileID(FileIn); TheCompInst.getDiagnosticClient().BeginSourceFile( TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by // ParseAST. MkApiASTConsumer TheConsumer(TheRewriter); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext() , clang::TU_Complete); // At this point the rewriter's buffer should be full with the rewritten // file contents. #if 0 const RewriteBuffer *RewriteBuf = TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID()); llvm::outs() << string(RewriteBuf->begin(), RewriteBuf->end()); #endif std::vector<func_info> fi = TheConsumer.GetFuncInfo(); stringstream stream; for (std::vector<func_info>::const_iterator it = fi.begin(); it != fi.end(); ++it) { std::vector<std::string> params = (*it).argv; stream << "DEFINE_DLLAPI_ARG(" << params.size() << ", " << (*it).return_type << ", " << (*it).name; for (int i = 0; i < params.size(); ++i) { stream << ", " << params[i]; } stream << ")" << endl; } cout << stream.str() << endl; return 0; }
int cc1_main(const char **ArgBegin, const char **ArgEnd, const char *Argv0, void *MainAddr) { CompilerInstance Clang; Clang.setLLVMContext(new llvm::LLVMContext); // Run clang -cc1 test. if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") { TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); Diagnostic Diags(&DiagClient); return cc1_test(Diags, ArgBegin + 1, ArgEnd); } // Initialize targets first, so that --version shows registered targets. llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); // Buffer diagnostics from argument parsing so that we can output them using a // well formed diagnostic object. TextDiagnosticBuffer DiagsBuffer; Diagnostic Diags(&DiagsBuffer); CompilerInvocation::CreateFromArgs(Clang.getInvocation(), ArgBegin, ArgEnd, Diags); // Infer the builtin include path if unspecified. if (Clang.getHeaderSearchOpts().UseBuiltinIncludes && Clang.getHeaderSearchOpts().ResourceDir.empty()) Clang.getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(Argv0, MainAddr); // Honor -help. if (Clang.getFrontendOpts().ShowHelp) { llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable()); Opts->PrintHelp(llvm::outs(), "clang -cc1", "LLVM 'Clang' Compiler: http://clang.llvm.org"); return 0; } // Honor -version. // // FIXME: Use a better -version message? if (Clang.getFrontendOpts().ShowVersion) { llvm::cl::PrintVersionMessage(); return 0; } // Create the actual diagnostics engine. Clang.createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin)); if (!Clang.hasDiagnostics()) return 1; // Set an error handler, so that any LLVM backend diagnostics go through our // error handler. llvm::llvm_install_error_handler(LLVMErrorHandler, static_cast<void*>(&Clang.getDiagnostics())); DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); // Load any requested plugins. for (unsigned i = 0, e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) { const std::string &Path = Clang.getFrontendOpts().Plugins[i]; std::string Error; if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; } // If there were errors in processing arguments, don't do anything else. bool Success = false; if (!Clang.getDiagnostics().getNumErrors()) { // Create and execute the frontend action. llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang)); if (Act) Success = Clang.ExecuteAction(*Act); } // Managed static deconstruction. Useful for making things like // -time-passes usable. llvm::llvm_shutdown(); return !Success; }
int main(int argc, const char **argv, char * const *envp) { void *MainAddr = (void*) (intptr_t) GetExecutablePath; llvm::sys::Path Path = GetExecutablePath(argv[0]); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); Diagnostic Diags(DiagID, DiagClient); Driver TheDriver(Path.str(), llvm::sys::getHostTriple(), "a.out", /*IsProduction=*/false, /*CXXIsProduction=*/false, Diags); TheDriver.setTitle("clang interpreter"); // FIXME: This is a hack to try to force the driver to do something we can // recognize. We need to extend the driver library to support this use model // (basically, exactly one input, and the operation mode is hard wired). llvm::SmallVector<const char *, 16> Args(argv, argv + argc); Args.push_back("-fsyntax-only"); llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args)); if (!C) return 0; // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate. // We expect to get back exactly one command job, if we didn't something // failed. Extract that job from the compilation. const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { llvm::SmallString<256> Msg; llvm::raw_svector_ostream OS(Msg); C->PrintJob(OS, C->getJobs(), "; ", true); Diags.Report(diag::err_fe_expected_compiler_job) << OS.str(); return 1; } 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 1; } // Initialize a compiler invocation object from the clang (-cc1) arguments. const driver::ArgStringList &CCArgs = Cmd->getArguments(); llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation); CompilerInvocation::CreateFromArgs(*CI, const_cast<const char **>(CCArgs.data()), const_cast<const char **>(CCArgs.data()) + CCArgs.size(), Diags); // Show the invocation, with -v. if (CI->getHeaderSearchOpts().Verbose) { llvm::errs() << "clang invocation:\n"; C->PrintJob(llvm::errs(), C->getJobs(), "\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(CI.take()); // Create the compilers actual diagnostics engine. Clang.createDiagnostics(int(CCArgs.size()),const_cast<char**>(CCArgs.data())); if (!Clang.hasDiagnostics()) return 1; // Infer the builtin include path if unspecified. if (Clang.getHeaderSearchOpts().UseBuiltinIncludes && Clang.getHeaderSearchOpts().ResourceDir.empty()) Clang.getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(argv[0], MainAddr); // Create and execute the frontend to generate an LLVM bitcode module. llvm::OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction()); if (!Clang.ExecuteAction(*Act)) return 1; int Res = 255; if (llvm::Module *Module = Act->takeModule()) Res = Execute(Module, envp); // Shutdown. llvm::llvm_shutdown(); return Res; }
static int CompileSubprocess(const char **argv, int argc, sys::Path &ResourceDir, bool bugreport, bool versionOnly, sys::Path &apiMapPath) { std::vector<char*> llvmArgs; char apim[] = "-clam-apimap"; llvmArgs.push_back((char*)argv[0]); llvmArgs.push_back(apim); llvmArgs.push_back((char*)apiMapPath.c_str()); // Split args into cc1 and LLVM args, separator is -- int cc1_argc; for (cc1_argc=1;cc1_argc<argc;cc1_argc++) { if (StringRef(argv[cc1_argc]) == "--") { for (int i=cc1_argc+1;i<argc;i++) { llvmArgs.push_back((char*)argv[i]); } break; } } // Initialize CompilerInstance from commandline args CompilerInstance Clang; Clang.setLLVMContext(new llvm::LLVMContext); LLVMInitializeClamBCTargetInfo(); LLVMInitializeClamBCTarget(); TextDiagnosticBuffer DiagsBuffer; Diagnostic Diags(&DiagsBuffer); CompilerInvocation::CreateFromArgs(Clang.getInvocation(), argv+1, argv+cc1_argc, Diags); FrontendOptions &FrontendOpts = Clang.getInvocation().getFrontendOpts(); // Handle --version if (FrontendOpts.ShowVersion || versionOnly) { printVersion(outs(), true); exit(0); } DiagnosticOptions &DiagOpts = Clang.getInvocation().getDiagnosticOpts(); DiagOpts.ShowOptionNames = DiagOpts.ShowColors = 1; DiagOpts.MessageLength = 80;// we are writing to a file DiagOpts.Warnings.push_back("all"); DiagOpts.Warnings.push_back("no-pointer-sign"); Clang.createDiagnostics(argc-1, const_cast<char**>(argv+1)); if (!Clang.hasDiagnostics()) return 2; Clang.getInvocation().getHeaderSearchOpts().ResourceDir = ResourceDir.str(); // Set default options LangOptions &LangOpts = Clang.getInvocation().getLangOpts(); // This is a freestanding environment, without libc, etc. LangOpts.Freestanding = 1; HeaderSearchOptions &HeaderSearchOpts = Clang.getInvocation().getHeaderSearchOpts(); HeaderSearchOpts.UseStandardIncludes = 0; if (bugreport) HeaderSearchOpts.Verbose = 1; if (FrontendOpts.ProgramAction != frontend::PrintPreprocessedInput) FrontendOpts.ProgramAction = frontend::EmitBC; if (bugreport) FrontendOpts.ProgramAction = frontend::PrintPreprocessedInput; // Don't bother freeing of memory on exit FrontendOpts.DisableFree = 1; CodeGenOptions &Opts = Clang.getInvocation().getCodeGenOpts(); Opts.Inlining = CodeGenOptions::OnlyAlwaysInlining; // always generate debug info, so that ClamBC backend can output sourcelevel // diagnostics. Opts.DebugInfo = true; // FIXME: once the verifier can work w/o targetdata, and targetdate opts set // DisableLLVMOpts to true! // This is needed to avoid target-specific optimizations Opts.DisableLLVMOpts = false; AnalyzerOptions &AOpts = Clang.getInvocation().getAnalyzerOpts(); AOpts.AnalysisList.push_back(WarnDeadStores); AOpts.AnalysisList.push_back(WarnUninitVals); AOpts.AnalysisList.push_back(SecuritySyntacticChecks); AOpts.AnalysisList.push_back(WarnSizeofPointer); // Set triple Clang.getInvocation().getTargetOpts().Triple = "clambc-generic-generic"; // Set default include Clang.getInvocation().getPreprocessorOpts().Includes.push_back("bytecode.h"); // Set an LLVM error handler. llvm::llvm_install_error_handler(LLVMErrorHandler, static_cast<void*>(&Clang.getDiagnostics())); DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); // If there were any errors in processing arguments, exit now. if (Clang.getDiagnostics().getNumErrors()) return 1; // Create the target instance. //TODO: directly create a clambc target Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), Clang.getTargetOpts())); if (!Clang.hasTarget()) return 1; // Inform the target of the language options Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); if (Clang.getHeaderSearchOpts().Verbose) { llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING << " based upon " << PACKAGE_STRING << " hosted on " << llvm::sys::getHostTriple() << "\n"; // Convert the invocation back to argument strings. std::vector<std::string> InvocationArgs; Clang.getInvocation().toArgs(InvocationArgs); // Dump the converted arguments. llvm::SmallVector<const char*, 32> Invocation2Args; llvm::errs() << "invocation argv :"; for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) { Invocation2Args.push_back(InvocationArgs[i].c_str()); llvm::errs() << " \"" << InvocationArgs[i] << '"'; } llvm::errs() << "\n"; } std::string Input = FrontendOpts.Inputs[0].second; if (Input == "-" && bugreport) return 2; raw_fd_ostream *fd = 0; if (FrontendOpts.ProgramAction == frontend::EmitBC) { // replace output file of compiler with a tempfile, // and save the final output filename. std::string FinalOutput = FrontendOpts.OutputFile; if (FinalOutput.empty()) { if (Input == "-") FinalOutput = "-"; else { sys::Path P(sys::Path(Input).getBasename()); P.appendSuffix("cbc"); FinalOutput = P.str(); } } llvm::raw_fd_ostream *tmpfd; std::string Err2; fd = Clang.createOutputFile(FinalOutput, Err2, false); if (!fd) { Clang.getDiagnostics().Report(clang::diag::err_drv_unable_to_make_temp) << Err2; return 1; } sys::Path P = sys::Path(FinalOutput); P.eraseSuffix(); P.appendSuffix("tmp.bc"); FrontendOpts.OutputFile = P.str(); tmpfd = Clang.createOutputFile(P.str(), Err2, true); if (!tmpfd) { Clang.getDiagnostics().Report(clang::diag::err_drv_unable_to_make_temp) << Err2; return 1; } delete tmpfd; sys::RemoveFileOnSignal(sys::Path(FrontendOpts.OutputFile)); } if (!FrontendOpts.Inputs.empty()) { char srcp[] = "-clambc-src"; llvmArgs.push_back(srcp); llvmArgs.push_back(strdup(Input.c_str())); } // Parse LLVM commandline args cl::ParseCommandLineOptions(llvmArgs.size(), &llvmArgs[0]); std::string re2cpath = getTmpDir(); if (re2cpath.empty()) { llvm::errs()<< "Failed to create temporary file for re2c-out!\n"; return 2; } re2cpath += "/clambc-compiler-re2c-out"; sys::Path TmpRe2C(re2cpath); if (!FrontendOpts.Inputs.empty()) { char re2c_args[] = "--no-generation-date"; char re2c_o[] = "-o"; char name[] = ""; char *args[6] = { name, re2c_args, re2c_o, NULL, NULL, NULL }; args[4] = strdup(Input.c_str()); std::string ErrMsg(""); if (TmpRe2C.createTemporaryFileOnDisk(true, &ErrMsg)) { Clang.getDiagnostics().Report(clang::diag::err_drv_unable_to_make_temp) << ErrMsg; return 1; } sys::RemoveFileOnSignal(TmpRe2C); args[3] = strdup(TmpRe2C.str().c_str()); int ret = re2c_main(5, args); if (ret) { Clang.getDiagnostics().Report(clang::diag::err_drv_command_failed) << "re2c" << ret; return 1; } Input = TmpRe2C.str(); } // Create a file manager object to provide access to and cache the // filesystem. Clang.createFileManager(); // Create the source manager. Clang.createSourceManager(); // Create the preprocessor. Clang.createPreprocessor(); llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang)); if (Act && Act->BeginSourceFile(Clang, Input, false)) { Act->Execute(); Act->EndSourceFile(); } TmpRe2C.eraseFromDisk();// erase tempfile int ret = Clang.getDiagnostics().getNumErrors() != 0; if (ret) return ret; if (FrontendOpts.ProgramAction != frontend::EmitBC) { // stop processing if not compiling a final .cbc file return 0; } ret = compileInternal(FrontendOpts.OutputFile.c_str(), Opts.OptimizationLevel, Opts.OptimizeSize, argv[0], fd, Clang); // Erase temp file, we need to do this here since OutputFile is a tempfile // only if action was EmitBC sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); return ret; }
//使用的格式: ./checkMemory 被测试文件名 -- int main(int argc,const char **argv) { //----此块基本一样 start---- struct stat sb; //set compilerinstance for rewriter std::string fileName(argv[1]); if (stat(fileName.c_str(), &sb) == -1){ perror(fileName.c_str()); exit(EXIT_FAILURE); } CompilerInstance compiler; DiagnosticOptions diagnosticOptions; compiler.createDiagnostics(); //invocation可以传递任何flag给preprocessor CompilerInvocation *Invocation = new CompilerInvocation; CompilerInvocation::CreateFromArgs(*Invocation, argv + 1, argv + argc-1,compiler.getDiagnostics()); compiler.setInvocation(Invocation); //建立TargetOptions和TargetInfo,并设置好Target // Set default target triple llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions()); pto->Triple = llvm::sys::getDefaultTargetTriple(); llvm::IntrusiveRefCntPtr<TargetInfo> pti(TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), pto.getPtr())); compiler.setTarget(pti.getPtr()); //FileManager,SourceManager 以及heaDREearch的Options的设置 compiler.createFileManager(); compiler.createSourceManager(compiler.getFileManager()); HeaderSearchOptions &headerSearchOptions = compiler.getHeaderSearchOpts(); headerSearchOptions.AddPath("/usr/include/c++", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/local/lib/clang/3.5.0/include", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/include/i386-linux-gnu", clang::frontend::Angled, false, false); headerSearchOptions.AddPath("/usr/include", clang::frontend::Angled, false, false); /* headerSearchOptions.AddPath("/usr/include", clang::frontend::Angled, false, false); */ //langOptions设置,要传给rewriter LangOptions langOpts; langOpts.GNUMode = 1; langOpts.CXXExceptions = 1; langOpts.RTTI = 1; langOpts.Bool = 1; langOpts.CPlusPlus = 1; Invocation->setLangDefaults(langOpts, clang::IK_CXX,clang::LangStandard::lang_cxx0x); //create PP compiler.createPreprocessor();//(TU_Complete);// compiler.getPreprocessorOpts().UsePredefines = false; //createASTContext compiler.createASTContext(); //set the sourceManager for rewriter rewrite.setSourceMgr(compiler.getSourceManager(), compiler.getLangOpts()); //插装文件入口 const FileEntry *pFile = compiler.getFileManager().getFile(fileName); compiler.getSourceManager().createMainFileID(pFile); compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(),&compiler.getPreprocessor()); MyASTConsumer astConsumer(rewrite); //将.c转成_out.c // Convert <file>.c to <file_out>.c std::string outName (fileName); /*size_t ext = outName.rfind("."); //根据有没有找到‘。’来决定在哪里加入_out if (ext == std::string::npos) ext = outName.length(); outName.insert(ext, "_out"); */ outName.insert(outName.length(),"_out"); llvm::errs() << "Output to: " << outName << "\n"; std::string OutErrorInfo; //新建输入到新文件的流 llvm::raw_fd_ostream outFile(outName.c_str(), OutErrorInfo);//,llvm::sys::fs::F_None);//版本问题////// //----此块基本一样 end---- if (OutErrorInfo.empty()){ // Parse the AST //用PP,astConsumer,ASTContext来解释AST ParseAST(compiler.getPreprocessor(), &astConsumer, compiler.getASTContext()); compiler.getDiagnosticClient().EndSourceFile(); //建立ClangTool CommonOptionsParser OptionsParser(argc, argv);//, MyToolCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); //开始匹配 MallocVarPrinter mallocVarPrinter; MatchFinder mallocVarFinder; mallocVarFinder.addMatcher(MallocVarMatcher, &mallocVarPrinter); Tool.run(newFrontendActionFactory(&mallocVarFinder)); MallocPrinter mallocPrinter; MatchFinder mallocFinder; mallocFinder.addMatcher(MallocMatcher, &mallocPrinter); Tool.run(newFrontendActionFactory(&mallocFinder)); FreeVarPrinter freeVarPrinter; MatchFinder freeVarFinder; freeVarFinder.addMatcher(FreeVarMatcher, &freeVarPrinter); Tool.run(newFrontendActionFactory(&freeVarFinder)); FreePrinter freePrinter; MatchFinder freeFinder; freeFinder.addMatcher(FreeMatcher, &freePrinter); Tool.run(newFrontendActionFactory(&freeFinder)); const RewriteBuffer *RewriteBuf =rewrite.getRewriteBufferFor(compiler.getSourceManager().getMainFileID()); if(RewriteBuf != NULL){ #ifdef DEBUG llvm::errs() << " RewriteBuf not NULL \n"; //在文件头加上改头文件,防止没有 stdlib,stdio 而不能使用printf和exit函数 #endif outFile << "#include\"plugHead.h\"\n"; outFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); }else{ #ifdef DEBUG llvm::errs() << " RewriteBuf is NULL \n"; #endif outFile << "#include\"plugHead.h\"\n"; std::ifstream infile(fileName.c_str()); if(!infile){ llvm::errs() << " fail to open the input file!\n"; exit(-1); } std::string str_in; while(std::getline(infile,str_in)){ outFile << str_in <<"\n"; } } outFile.close(); #ifdef DEBUG std::string checkStructErrorInfo; std::string checkStructFileName = "checkStruct.txt"; //新建输入到新文件的流,将已经找到的malloc过的结构体信息写入文件,供另一个处理程序读取 llvm::raw_fd_ostream csFile(checkStructFileName.c_str(),checkStructErrorInfo);//,llvm::sys::fs::F_None); if (checkStructErrorInfo.empty()){ for(unsigned int i=0;i<cpVec.size();++i){ csFile << cpVec[i].name << " " << cpVec[i].row << " " << cpVec[i].col << " " << cpVec[i].declName << " " << cpVec[i].declRow << " " << cpVec[i].declCol << "\n" ; } } csFile.close(); for(unsigned int i=0;i<cpVec.size();++i){ llvm::errs()<<cpVec[i].name<<"|"<<cpVec[i].declName<<":"<<cpVec[i].declRow<<":"<<cpVec[i].declCol<<"\n"; } #endif } else{ llvm::errs() << "Cannot open " << outName << " for writing\n"; } return 0; }
CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer, int argc, const char* const *argv, const char* llvmdir) { // Create an instance builder, passing the llvmdir and arguments. // // Initialize the llvm library. llvm::InitializeNativeTarget(); llvm::InitializeAllAsmPrinters(); llvm::sys::Path resource_path; if (llvmdir) { resource_path = llvmdir; resource_path.appendComponent("lib"); resource_path.appendComponent("clang"); resource_path.appendComponent(CLANG_VERSION_STRING); } else { // FIXME: The first arg really does need to be argv[0] on FreeBSD. // // Note: The second arg is not used for Apple, FreeBSD, Linux, // or cygwin, and can only be used on systems which support // the use of dladdr(). // // Note: On linux and cygwin this uses /proc/self/exe to find the path. // // Note: On Apple it uses _NSGetExecutablePath(). // // Note: On FreeBSD it uses getprogpath(). // // Note: Otherwise it uses dladdr(). // resource_path = CompilerInvocation::GetResourcesPath("cling", (void*)(intptr_t) locate_cling_executable ); } if (!resource_path.canRead()) { llvm::errs() << "ERROR in cling::CIFactory::createCI():\n resource directory " << resource_path.str() << " not found!\n"; resource_path = ""; } //______________________________________ DiagnosticOptions DefaultDiagnosticOptions; DefaultDiagnosticOptions.ShowColors = 1; TextDiagnosticPrinter* DiagnosticPrinter = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs()); DiagnosticsEngine* Diagnostics = new DiagnosticsEngine(DiagIDs, DiagnosticPrinter, /*Owns it*/ true); // LEAKS! std::vector<const char*> argvCompile(argv, argv + argc); // We do C++ by default; append right after argv[0] name // Only insert it if there is no other "-x": bool haveMinusX = false; for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc; ++iarg) { haveMinusX = !strcmp(*iarg, "-x"); } if (!haveMinusX) { argvCompile.insert(argvCompile.begin() + 1,"-x"); argvCompile.insert(argvCompile.begin() + 2, "c++"); } argvCompile.push_back("-c"); argvCompile.push_back("-"); bool IsProduction = false; assert(IsProduction = true && "set IsProduction if asserts are on."); clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(), "cling.out", IsProduction, *Diagnostics); //Driver.setWarnMissingInput(false); Driver.setCheckInputsExist(false); // think foo.C(12) llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size()); llvm::OwningPtr<clang::driver::Compilation> Compilation(Driver.BuildCompilation(RF)); const clang::driver::ArgStringList* CC1Args = GetCC1Arguments(Diagnostics, Compilation.get()); if (CC1Args == NULL) { return 0; } clang::CompilerInvocation* Invocation = new clang::CompilerInvocation; // LEAKS! clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1, CC1Args->data() + CC1Args->size(), *Diagnostics); Invocation->getFrontendOpts().DisableFree = true; if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes && !resource_path.empty()) { // Update ResourceDir // header search opts' entry for resource_path/include isn't // updated by providing a new resource path; update it manually. clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts(); llvm::sys::Path oldResInc(Opts.ResourceDir); oldResInc.appendComponent("include"); llvm::sys::Path newResInc(resource_path); newResInc.appendComponent("include"); bool foundOldResInc = false; for (unsigned i = 0, e = Opts.UserEntries.size(); !foundOldResInc && i != e; ++i) { HeaderSearchOptions::Entry &E = Opts.UserEntries[i]; if (!E.IsUserSupplied && !E.IsFramework && E.Group == clang::frontend::System && E.IgnoreSysRoot && E.IsInternal && !E.ImplicitExternC && oldResInc.str() == E.Path) { E.Path = newResInc.str(); foundOldResInc = true; } } Opts.ResourceDir = resource_path.str(); } // Create and setup a compiler instance. CompilerInstance* CI = new CompilerInstance(); CI->setInvocation(Invocation); CI->createDiagnostics(CC1Args->size(), CC1Args->data() + 1); { // // Buffer the error messages while we process // the compiler options. // // Set the language options, which cling needs SetClingCustomLangOpts(CI->getLangOpts()); CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__"); if (CI->getDiagnostics().hasErrorOccurred()) { delete CI; CI = 0; return 0; } } CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(), Invocation->getTargetOpts())); if (!CI->hasTarget()) { delete CI; CI = 0; return 0; } CI->getTarget().setForcedLangOptions(CI->getLangOpts()); SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget()); // Set up source and file managers CI->createFileManager(); CI->createSourceManager(CI->getFileManager()); // Set up the memory buffer if (buffer) CI->getSourceManager().createMainFileIDForMemBuffer(buffer); // Set up the preprocessor CI->createPreprocessor(); Preprocessor& PP = CI->getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); // Set up the ASTContext ASTContext *Ctx = new ASTContext(CI->getLangOpts(), PP.getSourceManager(), &CI->getTarget(), PP.getIdentifierTable(), PP.getSelectorTable(), PP.getBuiltinInfo(), /*size_reserve*/0, /*DelayInit*/false); CI->setASTContext(Ctx); // Set up the ASTConsumers CI->setASTConsumer(new DeclCollector()); // Set up Sema CodeCompleteConsumer* CCC = 0; CI->createSema(TU_Prefix, CCC); // Set CodeGen options // CI->getCodeGenOpts().DebugInfo = 1; // want debug info // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out // When asserts are on, TURN ON not compare the VerifyModule assert(CI->getCodeGenOpts().VerifyModule = 1); return CI; }
int main(int argc, char *argv[]) { if (argc != 2) { llvm::errs() << "Usage: kcov-branch-identify <filename>\n"; return 1; } // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler. CompilerInstance TheCompInst; // Diagnostics manage problems and issues in compile TheCompInst.createDiagnostics(NULL, false); // Set target platform options // Initialize target info with the default triple for our platform. TargetOptions *TO = new TargetOptions(); TO->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); TheCompInst.setTarget(TI); // FileManager supports for file system lookup, file system caching, and directory search management. TheCompInst.createFileManager(); FileManager &FileMgr = TheCompInst.getFileManager(); // SourceManager handles loading and caching of source files into memory. TheCompInst.createSourceManager(FileMgr); SourceManager &SourceMgr = TheCompInst.getSourceManager(); //global var m_srcmgr //m_srcmgr = &SourceMgr; // Prreprocessor runs within a single source file TheCompInst.createPreprocessor(); // ASTContext holds long-lived AST nodes (such as types and decls) . TheCompInst.createASTContext(); // Enable HeaderSearch option llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso( new HeaderSearchOptions()); HeaderSearch headerSearch(hso, TheCompInst.getFileManager(), TheCompInst.getDiagnostics(), TheCompInst.getLangOpts(), TI); // <Warning!!> -- Platform Specific Code lives here // This depends on A) that you're running linux and // B) that you have the same GCC LIBs installed that I do. /* $ gcc -xc -E -v - .. /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed /usr/include End of search list. */ const char *include_paths[] = {"/usr/local/include", "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include", "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed", "/usr/include"}; for (int i=0; i<4; i++) hso->AddPath(include_paths[i], clang::frontend::Angled, false, false); // </Warning!!> -- End of Platform Specific Code InitializePreprocessor(TheCompInst.getPreprocessor(), TheCompInst.getPreprocessorOpts(), *hso, TheCompInst.getFrontendOpts()); // A Rewriter helps us manage the code rewriting task. Rewriter TheRewriter; TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); // Set the main file handled by the source manager to the input file. const FileEntry *FileIn = FileMgr.getFile(argv[1]); SourceMgr.createMainFileID(FileIn); // Inform Diagnostics that processing of a source file is beginning. TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(),&TheCompInst.getPreprocessor()); // Create an AST consumer instance which is going to get called by ParseAST. MyASTConsumer TheConsumer(SourceMgr); // Parse the file to AST, registering our consumer as the AST consumer. ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext()); TheConsumer.printBranchNum(); return 0; }
LLVMResult* ClangCodeContainer::produceModule(Tree signals, const string& filename) { // Compile DSP and generate C code fCompiler->compileMultiSignal(signals); fContainer->produceClass(); #if defined(LLVM_34) || defined(LLVM_35) || defined(LLVM_36) || defined(LLVM_37) || defined(LLVM_38) || defined(LLVM_39) || defined(LLVM_40) // Compile it with 'clang' IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter* DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); Driver TheDriver("", llvm::sys::getProcessTriple(), "a.out", Diags); TheDriver.setTitle("clang interpreter"); int argc = 2; const char* argv[argc + 1]; argv[0] = "clang"; argv[1] = getTempName(); argv[argc] = 0; // NULL terminated argv SmallVector<const char*, 16> Args(argv, argv + argc); Args.push_back("-fsyntax-only"); //Args.push_back("-O3"); Args.push_back("-ffast-math"); list<string>::iterator it; for (it = gGlobal->gImportDirList.begin(); it != gGlobal->gImportDirList.end(); it++) { string path = "-I" + (*it); Args.push_back(strdup(path.c_str())); } OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args)); if (!C) { return NULL; } 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 NULL; } 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 NULL; } // Initialize a compiler invocation object from the clang (-cc1) arguments. const driver::ArgStringList &CCArgs = Cmd->getArguments(); OwningPtr<CompilerInvocation> CI(new CompilerInvocation); CompilerInvocation::CreateFromArgs(*CI, const_cast<const char**>(CCArgs.data()), const_cast<const char**>(CCArgs.data()) + CCArgs.size(), Diags); // Create a compiler instance to handle the actual work. CompilerInstance Clang; Clang.setInvocation(CI.take()); // Create the compilers actual diagnostics engine. Clang.createDiagnostics(); if (!Clang.hasDiagnostics()) { return NULL; } CompilerInvocation::setLangDefaults(Clang.getLangOpts(), IK_CXX, LangStandard::lang_unspecified); // Create and execute the frontend to generate an LLVM bitcode module. OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction()); if (!Clang.ExecuteAction(*Act)) { return NULL; } // Get the compiled LLVM module if (llvm::Module* Module = Act->takeModule()) { LLVMResult* result = static_cast<LLVMResult*>(calloc(1, sizeof(LLVMResult))); result->fModule = Module; result->fContext = Act->takeLLVMContext(); // Link LLVM modules defined in 'ffunction' set<string> S; set<string>::iterator f; char error_msg[512]; collectLibrary(S); if (S.size() > 0) { for (f = S.begin(); f != S.end(); f++) { string module_name = unquote(*f); if (endWith(module_name, ".bc") || endWith(module_name, ".ll")) { Module* module = loadModule(module_name, result->fContext); if (module) { bool res = linkModules(result->fModule, module, error_msg); if (!res) printf("Link LLVM modules %s\n", error_msg); } } } } // Possibly link with additional LLVM modules char error[256]; if (!linkAllModules(result->fContext, result->fModule, error)) { stringstream llvm_error; llvm_error << "ERROR : " << error << endl; throw faustexception(llvm_error.str()); } // Keep source files pathnames result->fPathnameList = gGlobal->gReader.listSrcFiles(); // Possibly output file if (filename != "") { std::string err; raw_fd_ostream out(filename.c_str(), err, sysfs_binary_flag); WriteBitcodeToFile(result->fModule, out); } return result; } else { return NULL; } #else return NULL; #endif }
void ModelInjector::onBodySynthesis(const NamedDecl *D) { // FIXME: what about overloads? Declarations can be used as keys but what // about file name index? Mangled names may not be suitable for that either. if (Bodies.count(D->getName()) != 0) return; SourceManager &SM = CI.getSourceManager(); FileID mainFileID = SM.getMainFileID(); AnalyzerOptionsRef analyzerOpts = CI.getAnalyzerOpts(); llvm::StringRef modelPath = analyzerOpts->Config["model-path"]; llvm::SmallString<128> fileName; if (!modelPath.empty()) fileName = llvm::StringRef(modelPath.str() + "/" + D->getName().str() + ".model"); else fileName = llvm::StringRef(D->getName().str() + ".model"); if (!llvm::sys::fs::exists(fileName.str())) { Bodies[D->getName()] = nullptr; return; } IntrusiveRefCntPtr<CompilerInvocation> Invocation( new CompilerInvocation(CI.getInvocation())); FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); InputKind IK = IK_CXX; // FIXME FrontendOpts.Inputs.clear(); FrontendOpts.Inputs.push_back(FrontendInputFile(fileName, IK)); FrontendOpts.DisableFree = true; Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; // Modules are parsed by a separate CompilerInstance, so this code mimics that // behavior for models CompilerInstance Instance; Instance.setInvocation(&*Invocation); Instance.createDiagnostics( new ForwardingDiagnosticConsumer(CI.getDiagnosticClient()), /*ShouldOwnClient=*/true); Instance.getDiagnostics().setSourceManager(&SM); Instance.setVirtualFileSystem(&CI.getVirtualFileSystem()); // The instance wants to take ownership, however DisableFree frontend option // is set to true to avoid double free issues Instance.setFileManager(&CI.getFileManager()); Instance.setSourceManager(&SM); Instance.setPreprocessor(&CI.getPreprocessor()); Instance.setASTContext(&CI.getASTContext()); Instance.getPreprocessor().InitializeForModelFile(); ParseModelFileAction parseModelFile(Bodies); const unsigned ThreadStackSize = 8 << 20; llvm::CrashRecoveryContext CRC; CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(parseModelFile); }, ThreadStackSize); Instance.getPreprocessor().FinalizeForModelFile(); Instance.resetAndLeakSourceManager(); Instance.resetAndLeakFileManager(); Instance.resetAndLeakPreprocessor(); // The preprocessor enters to the main file id when parsing is started, so // the main file id is changed to the model file during parsing and it needs // to be reseted to the former main file id after parsing of the model file // is done. SM.setMainFileID(mainFileID); }
extern "C" void* getFunctionPointer(const char *filename, const char *function) { raw_string_ostream sstream(error); error.clear(); // if no execution engine is present, create new one if (!EE) { llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); Ctx.reset(new llvm::LLVMContext()); llvm::sys::Path Path = GetExecutablePath("clang"); IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(sstream, &*DiagOpts); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); Driver TheDriver(Path.str(), llvm::sys::getProcessTriple(), "a.out", Diags); TheDriver.setTitle("clang interpreter"); // FIXME: This is a hack to try to force the driver to do something we can // recognize. We need to extend the driver library to support this use model // (basically, exactly one input, and the operation mode is hard wired). SmallVector<const char *, 16> Args(0); // argv[0] = clang - emulate program name Args.push_back("clang"); // argv[1] = file to compile Args.push_back(filename); Args.push_back("-fsyntax-only"); OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args)); if (!C) { sstream << "Can't create Compilation object (TheDriver.BuildCompilation())\n"; return NULL; } // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate. // We expect to get back exactly one command job, if we didn't something // failed. Extract that job from the compilation. const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { SmallString<256> Msg; llvm::raw_svector_ostream OS(Msg); sstream << "Wrong number of compiler jobs (see details below)\n"; C->PrintJob(OS, C->getJobs(), "; ", true); Diags.Report(diag::err_fe_expected_compiler_job) << OS.str(); return NULL; } const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { sstream << "No clang job (see details below)\n"; Diags.Report(diag::err_fe_expected_clang_command); return NULL; } // Initialize a compiler invocation object from the clang (-cc1) arguments. const driver::ArgStringList &CCArgs = Cmd->getArguments(); OwningPtr<CompilerInvocation> CI(new CompilerInvocation); CompilerInvocation::CreateFromArgs(*CI, const_cast<const char **>(CCArgs.data()), const_cast<const char **>(CCArgs.data()) + CCArgs.size(), Diags); // FIXME: This is copied from cc1_main.cpp; simplify and eliminate. // Create a compiler instance to handle the actual work. CompilerInstance Clang; Clang.setInvocation(CI.take()); // Create the compilers actual diagnostics engine. Clang.createDiagnostics(); if (!Clang.hasDiagnostics()) { sstream << "Can't create diagnostics engine\n"; return NULL; } // Create and execute the frontend to generate an LLVM bitcode module. OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction(Ctx.get())); if (!Clang.ExecuteAction(*Act)) { sstream << "Can't execute frontend action (parsing source, converting to LLVM IR)\n"; return NULL; } if (llvm::Module *Module = Act->takeModule()) { // now let's create MSCJIT instance LLVMLinkInMCJIT(); std::string Error; EE.reset(createMCJIT (Module, Error)); if (!EE) { sstream << "Unable to make execution engine: " << Error; return NULL; } // compile module, apply memory permissions EE->finalizeObject(); // retrieve requested function Function* F = Module->getFunction(function); if (!F) { sstream << "Function " << function << " couldn't be found in module\n"; return NULL; } return EE->getPointerToFunction(F); } } // Execution engine already created if (EE) { // just find damn function Function* F = EE->FindFunctionNamed(function); if (!F) { sstream << "Function " << function << " couldn't be found in module\n"; return NULL; } return EE->getPointerToFunction(F); } sstream << "Unknown error (may be no execution engine is present)\n"; return NULL; }