bool CompilerInstance::InitializeSourceManager(StringRef InputFile, SrcMgr::CharacteristicKind Kind, DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { // Figure out where to get and map in the main file. if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } SourceMgr.createMainFileID(File, Kind); } else { OwningPtr<llvm::MemoryBuffer> SB; if (llvm::MemoryBuffer::getSTDIN(SB)) { // FIXME: Give ec.message() in this diag. Diags.Report(diag::err_fe_error_reading_stdin); return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), SB->getBufferSize(), 0); SourceMgr.createMainFileID(File, Kind); SourceMgr.overrideFileContents(File, SB.take()); } assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; }
bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, Diagnostic &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { // Figure out where to get and map in the main file, unless it's already // been created (e.g., by a precompiled preamble). if (!SourceMgr.getMainFileID().isInvalid()) { // Do nothing: the main file has already been set. } else if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } SourceMgr.createMainFileID(File); } else { llvm::OwningPtr<llvm::MemoryBuffer> SB; if (llvm::MemoryBuffer::getSTDIN(SB)) { // FIXME: Give ec.message() in this diag. Diags.Report(diag::err_fe_error_reading_stdin); return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), SB->getBufferSize(), 0); SourceMgr.createMainFileID(File); SourceMgr.overrideFileContents(File, SB.take()); } assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; }
bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { SrcMgr::CharacteristicKind Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; if (Input.isBuffer()) { SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind); assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; } StringRef InputFile = Input.getFile(); // Figure out where to get and map in the main file. if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } // The natural SourceManager infrastructure can't currently handle named // pipes, but we would at least like to accept them for the main // file. Detect them here, read them with the more generic MemoryBuffer // function, and simply override their contents as we do for STDIN. if (File->isNamedPipe()) { OwningPtr<llvm::MemoryBuffer> MB; if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) { Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message(); return false; } // Create a new virtual file that will have the correct size. File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); SourceMgr.overrideFileContents(File, MB.take()); } SourceMgr.createMainFileID(File, Kind); } else { OwningPtr<llvm::MemoryBuffer> SB; if (llvm::MemoryBuffer::getSTDIN(SB)) { // FIXME: Give ec.message() in this diag. Diags.Report(diag::err_fe_error_reading_stdin); return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), SB->getBufferSize(), 0); SourceMgr.createMainFileID(File, Kind); SourceMgr.overrideFileContents(File, SB.take()); } assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; }
bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, Diagnostic &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { // Figure out where to get and map in the main file. if (Opts.EmptyInputOnly) { const char *EmptyStr = ""; llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<empty input>"); SourceMgr.createMainFileIDForMemBuffer(SB); } else if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (File) SourceMgr.createMainFileID(File, SourceLocation()); if (SourceMgr.getMainFileID().isInvalid()) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } } else { llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN(); SourceMgr.createMainFileIDForMemBuffer(SB); if (SourceMgr.getMainFileID().isInvalid()) { Diags.Report(diag::err_fe_error_reading_stdin); return false; } } return true; }
int main() { llvm::raw_stdout_ostream ost; //DiagnosticOptions dops; TextDiagnosticPrinter tdp(ost);//, dops); Diagnostic diag(&tdp); LangOptions lang; //lang.GNUMode = 1; SourceManager sm; FileManager fm; HeaderSearch headers(fm); InitHeaderSearch init(headers); init.AddDefaultSystemIncludePaths(lang); init.Realize(); TargetInfo *ti = TargetInfo::CreateTargetInfo(LLVM_HOSTTRIPLE); Preprocessor pp(diag, lang, *ti, sm, headers); PreprocessorInitOptions ppio; InitializePreprocessor(pp, ppio); const FileEntry *file = fm.getFile("foo.c"); sm.createMainFileID(file, SourceLocation()); pp.EnterMainSourceFile(); IdentifierTable tab(lang); MyAction action(pp); Parser p(pp, action); p.ParseTranslationUnit(); return 0; }
void testClang() { return; //maks:teste std::string InFile = "E:/GAMEDEVELOPMENT/output/dots.c"; // Create a file manager object to provide access to and cache the filesystem. FileManager FileMgr; char *PredefineBuffer = ""; ASTConsumer *consumer = new ASTDumper(); // Create the diagnostic client for reporting errors or for // implementing -verify. DiagnosticClient* TextDiagClient = 0; TextDiagClient = new TextDiagnosticPrinter(); llvm::OwningPtr<DiagnosticClient> DiagClient(TextDiagClient); Diagnostic Diags(DiagClient.get()); LangOptions LangInfo; SourceManager SourceMgr; HeaderSearch HeaderInfo(FileMgr); TargetInfo *Target; std::string Triple = CreateTargetTriple(); //llvm::OwningPtr<TargetInfo> Target(TargetInfo::CreateTargetInfo(Triple)); Target = TargetInfo::CreateTargetInfo(Triple); // Set up the preprocessor with these options. Preprocessor PP(Diags, LangInfo, *Target, SourceMgr, HeaderInfo); PP.setPredefines(PredefineBuffer); const FileEntry *File = FileMgr.getFile(InFile); if (File) SourceMgr.createMainFileID(File, SourceLocation()); ParseAST(PP, consumer, false); }
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; }
static int do_assemble(SourceManager& source_mgr, DiagnosticsEngine& diags) { // Apply warning settings ApplyWarningSettings(diags); // Determine objfmt_bits based on -32 and -64 options std::string objfmt_bits = GetBitsSetting(); FileManager& file_mgr = source_mgr.getFileManager(); Assembler assembler("x86", YGAS_OBJFMT_BASE + objfmt_bits, diags, dump_object); HeaderSearch headers(file_mgr); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set object filename if specified. if (!obj_filename.empty()) assembler.setObjectFilename(obj_filename); // Set parser. assembler.setParser("gas", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set debug format to dwarf2pass if it's legal for this object format. if (assembler.isOkDebugFormat("dwarf2pass")) { assembler.setDebugFormat("dwarf2pass", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; } // open the input file or STDIN (for filename of "-") if (in_filename == "-") { OwningPtr<MemoryBuffer> my_stdin; if (llvm::error_code err = MemoryBuffer::getSTDIN(my_stdin)) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename << err.message(); return EXIT_FAILURE; } source_mgr.createMainFileIDForMemBuffer(my_stdin.take()); } else { const FileEntry* in = file_mgr.getFile(in_filename); if (!in) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename; return EXIT_FAILURE; } source_mgr.createMainFileID(in); } // Initialize the object. if (!assembler.InitObject(source_mgr, diags)) return EXIT_FAILURE; // Configure object per command line parameters. ConfigureObject(*assembler.getObject()); // Predefine symbols. for (std::vector<std::string>::const_iterator i=defsym.begin(), end=defsym.end(); i != end; ++i) { StringRef str(*i); size_t equalpos = str.find('='); if (equalpos == StringRef::npos) { diags.Report(diag::fatal_bad_defsym) << str; continue; } StringRef name = str.slice(0, equalpos); StringRef vstr = str.slice(equalpos+1, StringRef::npos); IntNum value; if (!vstr.empty()) { // determine radix unsigned int radix; if (vstr[0] == '0' && vstr.size() > 1 && (vstr[1] == 'x' || vstr[1] == 'X')) { vstr = vstr.substr(2); radix = 16; } else if (vstr[0] == '0') { vstr = vstr.substr(1); radix = 8; } else radix = 10; // check validity const char* ptr = vstr.begin(); const char* end = vstr.end(); if (radix == 16) { while (ptr != end && isxdigit(*ptr)) ++ptr; } else if (radix == 8) { while (ptr != end && (*ptr >= '0' && *ptr <= '7')) ++ptr; } else { while (ptr != end && isdigit(*ptr)) ++ptr; } if (ptr != end) { diags.Report(diag::fatal_bad_defsym) << name; continue; } value.setStr(vstr, radix); } // define equ assembler.getObject()->getSymbol(name)->DefineEqu(Expr(value)); } if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Initialize the parser. assembler.InitParser(source_mgr, diags, headers); // Assemble the input. if (!assembler.Assemble(source_mgr, diags)) { // An error occurred during assembly. return EXIT_FAILURE; } // open the object file for output std::string err; raw_fd_ostream out(assembler.getObjectFilename().str().c_str(), err, raw_fd_ostream::F_Binary); if (!err.empty()) { diags.Report(SourceLocation(), diag::err_cannot_open_file) << obj_filename << err; return EXIT_FAILURE; } if (!assembler.Output(out, diags)) { // An error occurred during output. // If we had an error at this point, we also need to delete the output // object file (to make sure it's not left newer than the source). out.close(); remove(assembler.getObjectFilename().str().c_str()); return EXIT_FAILURE; } // close object file out.close(); return EXIT_SUCCESS; }