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; }
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; }
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; }