本文整理汇总了C++中OwningPtr::getBufferSize方法的典型用法代码示例。如果您正苦于以下问题:C++ OwningPtr::getBufferSize方法的具体用法?C++ OwningPtr::getBufferSize怎么用?C++ OwningPtr::getBufferSize使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类OwningPtr
的用法示例。
在下文中一共展示了OwningPtr::getBufferSize方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: InitializeSourceManager
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;
}
示例2: main
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
if (OutputFilename == "-") {
errs() << argv[0] << ": error: Can't update standard output\n";
return 1;
}
// Get the input data.
OwningPtr<MemoryBuffer> In;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), In)) {
errs() << argv[0] << ": error: Unable to get input '"
<< InputFilename << "': " << ec.message() << '\n';
return 1;
}
// Get the output data.
OwningPtr<MemoryBuffer> Out;
MemoryBuffer::getFile(OutputFilename.c_str(), Out);
// If the output exists and the contents match, we are done.
if (Out && In->getBufferSize() == Out->getBufferSize() &&
memcmp(In->getBufferStart(), Out->getBufferStart(),
Out->getBufferSize()) == 0) {
if (!Quiet)
errs() << argv[0] << ": Not updating '" << OutputFilename
<< "', contents match input.\n";
return 0;
}
// Otherwise, overwrite the output.
if (!Quiet)
errs() << argv[0] << ": Updating '" << OutputFilename
<< "', contents changed.\n";
std::string ErrorStr;
tool_output_file OutStream(OutputFilename.c_str(), ErrorStr,
raw_fd_ostream::F_Binary);
if (!ErrorStr.empty()) {
errs() << argv[0] << ": Unable to write output '"
<< OutputFilename << "': " << ErrorStr << '\n';
return 1;
}
OutStream.os().write(In->getBufferStart(), In->getBufferSize());
// Declare success.
OutStream.keep();
return 0;
}
示例3: InitializeSourceManager
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;
}
示例4: format
// Returns true on error.
static bool format(std::string FileName) {
FileManager Files((FileSystemOptions()));
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager Sources(Diagnostics, Files);
OwningPtr<MemoryBuffer> Code;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
llvm::errs() << ec.message() << "\n";
return true;
}
if (Code->getBufferSize() == 0)
return true; // Empty files are formatted correctly.
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
std::vector<CharSourceRange> Ranges;
if (fillRanges(Sources, ID, Code.get(), Ranges))
return true;
FormatStyle FormatStyle = getStyle(Style, FileName);
Lexer Lex(ID, Sources.getBuffer(ID), Sources,
getFormattingLangOpts(FormatStyle.Standard));
tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
if (OutputXML) {
llvm::outs()
<< "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
for (tooling::Replacements::const_iterator I = Replaces.begin(),
E = Replaces.end();
I != E; ++I) {
llvm::outs() << "<replacement "
<< "offset='" << I->getOffset() << "' "
<< "length='" << I->getLength() << "'>"
<< I->getReplacementText() << "</replacement>\n";
}
llvm::outs() << "</replacements>\n";
} else {
Rewriter Rewrite(Sources, LangOptions());
tooling::applyAllReplacements(Replaces, Rewrite);
if (Inplace) {
if (Replaces.size() == 0)
return false; // Nothing changed, don't touch the file.
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
llvm::sys::fs::F_Binary);
if (!ErrorInfo.empty()) {
llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
return true;
}
Rewrite.getEditBuffer(ID).write(FileStream);
FileStream.flush();
} else {
if (Cursor.getNumOccurrences() != 0)
outs() << "{ \"Cursor\": " << tooling::shiftedCodePosition(
Replaces, Cursor) << " }\n";
Rewrite.getEditBuffer(ID).write(outs());
}
}
return false;
}
示例5: createModuleFromFile
Module* createModuleFromFile(const std::string & fileName) {
std::string errorMessage;
//create memory buffer for file
OwningPtr<MemoryBuffer> fileBuffer;
error_code e = MemoryBuffer::getFile(fileName.c_str(), fileBuffer);
if (e) {
errs() << "Error reading file '"
<< fileName << "': " << e.message() << "\n";
return NULL;
}
if (!fileBuffer) {
errs() << "Error reading file '" << fileName << "'.\n";
return NULL;
}
if (fileBuffer->getBufferSize() & 3) {
errs() << "Error: Bitcode stream should be "
<< "a multiple of 4 bytes in length\n";
return NULL;
}
//parse file
Module* mod = ParseBitcodeFile(fileBuffer.get(), getGlobalContext(), &errorMessage);
if (errorMessage != "") {
errs() << "Error reading bitcode file: " << errorMessage << "\n";
return NULL;
}
if (!mod) {
errs() << "Error reading bitcode file.\n";
return NULL;
}
return mod;
}
示例6: format
// Returns true on error.
static bool format(std::string FileName) {
FileManager Files((FileSystemOptions()));
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager Sources(Diagnostics, Files);
OwningPtr<MemoryBuffer> Code;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
llvm::errs() << ec.message() << "\n";
return true;
}
FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
if (Offsets.empty())
Offsets.push_back(0);
if (Offsets.size() != Lengths.size() &&
!(Offsets.size() == 1 && Lengths.empty())) {
llvm::errs()
<< "error: number of -offset and -length arguments must match.\n";
return true;
}
std::vector<CharSourceRange> Ranges;
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
if (Offsets[i] >= Code->getBufferSize()) {
llvm::errs() << "error: offset " << Offsets[i]
<< " is outside the file\n";
return true;
}
SourceLocation Start =
Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
SourceLocation End;
if (i < Lengths.size()) {
if (Offsets[i] + Lengths[i] > Code->getBufferSize()) {
llvm::errs() << "error: invalid length " << Lengths[i]
<< ", offset + length (" << Offsets[i] + Lengths[i]
<< ") is outside the file.\n";
return true;
}
End = Start.getLocWithOffset(Lengths[i]);
} else {
End = Sources.getLocForEndOfFile(ID);
}
Ranges.push_back(CharSourceRange::getCharRange(Start, End));
}
tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
if (OutputXML) {
llvm::outs()
<< "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
for (tooling::Replacements::const_iterator I = Replaces.begin(),
E = Replaces.end();
I != E; ++I) {
llvm::outs() << "<replacement "
<< "offset='" << I->getOffset() << "' "
<< "length='" << I->getLength() << "'>"
<< I->getReplacementText() << "</replacement>\n";
}
llvm::outs() << "</replacements>\n";
} else {
Rewriter Rewrite(Sources, LangOptions());
tooling::applyAllReplacements(Replaces, Rewrite);
if (Inplace) {
if (Replaces.size() == 0)
return false; // Nothing changed, don't touch the file.
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
llvm::raw_fd_ostream::F_Binary);
if (!ErrorInfo.empty()) {
llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
return true;
}
Rewrite.getEditBuffer(ID).write(FileStream);
FileStream.flush();
} else {
Rewrite.getEditBuffer(ID).write(outs());
}
}
return false;
}
示例7: main
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
SourceMgr SM;
// Read the expected strings from the check file.
std::vector<CheckString> CheckStrings;
if (ReadCheckFile(SM, CheckStrings))
return 2;
// Open the file to check and add it to SourceMgr.
OwningPtr<MemoryBuffer> File;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
errs() << "Could not open input file '" << InputFilename << "': "
<< ec.message() << '\n';
return 2;
}
if (File->getBufferSize() == 0) {
errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
return 2;
}
// Remove duplicate spaces in the input file if requested.
// Remove DOS style line endings.
MemoryBuffer *F =
CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace);
SM.AddNewSourceBuffer(F, SMLoc());
/// VariableTable - This holds all the current filecheck variables.
StringMap<StringRef> VariableTable;
// Check that we have all of the expected strings, in order, in the input
// file.
StringRef Buffer = F->getBuffer();
const char *LastMatch = Buffer.data();
for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
const CheckString &CheckStr = CheckStrings[StrNo];
StringRef SearchFrom = Buffer;
// Find StrNo in the file.
size_t MatchLen = 0;
size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable);
Buffer = Buffer.substr(MatchPos);
// If we didn't find a match, reject the input.
if (MatchPos == StringRef::npos) {
PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
return 1;
}
StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);
// If this check is a "CHECK-NEXT", verify that the previous match was on
// the previous line (i.e. that there is one newline between them).
if (CheckStr.IsCheckNext) {
// Count the number of newlines between the previous match and this one.
assert(LastMatch != F->getBufferStart() &&
"CHECK-NEXT can't be the first check in a file");
unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
if (NumNewLines == 0) {
SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
CheckPrefix+"-NEXT: is on the same line as previous match");
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
SourceMgr::DK_Note, "'next' match was here");
SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
"previous match was here");
return 1;
}
if (NumNewLines != 1) {
SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error, CheckPrefix+
"-NEXT: is not on the line after the previous match");
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
SourceMgr::DK_Note, "'next' match was here");
SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
"previous match was here");
return 1;
}
}
// If this match had "not strings", verify that they don't exist in the
// skipped region.
for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
ChunkNo != e; ++ChunkNo) {
size_t MatchLen = 0;
size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
MatchLen,
VariableTable);
if (Pos == StringRef::npos) continue;
SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), SourceMgr::DK_Error,
//.........这里部分代码省略.........
示例8: AnalyzeBitcode
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
// Read the input file.
OwningPtr<MemoryBuffer> MemBuf;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), MemBuf))
return Error("Error reading '" + InputFilename + "': " + ec.message());
if (MemBuf->getBufferSize() & 3)
return Error("Bitcode stream should be a multiple of 4 bytes in length");
const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize();
// If we have a wrapper header, parse it and ignore the non-bc file contents.
// The magic number is 0x0B17C0DE stored in little endian.
if (isBitcodeWrapper(BufPtr, EndBufPtr))
if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true))
return Error("Invalid bitcode wrapper header");
BitstreamReader StreamFile(BufPtr, EndBufPtr);
BitstreamCursor Stream(StreamFile);
StreamFile.CollectBlockInfoNames();
// Read the stream signature.
char Signature[6];
Signature[0] = Stream.Read(8);
Signature[1] = Stream.Read(8);
Signature[2] = Stream.Read(4);
Signature[3] = Stream.Read(4);
Signature[4] = Stream.Read(4);
Signature[5] = Stream.Read(4);
// Autodetect the file contents, if it is one we know.
CurStreamType = UnknownBitstream;
if (Signature[0] == 'B' && Signature[1] == 'C' &&
Signature[2] == 0x0 && Signature[3] == 0xC &&
Signature[4] == 0xE && Signature[5] == 0xD)
CurStreamType = LLVMIRBitstream;
unsigned NumTopBlocks = 0;
// Parse the top-level structure. We only allow blocks at the top-level.
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code != bitc::ENTER_SUBBLOCK)
return Error("Invalid record at top-level");
unsigned BlockID = Stream.ReadSubBlockID();
if (ParseBlock(Stream, BlockID, 0))
return true;
++NumTopBlocks;
}
if (Dump) outs() << "\n\n";
uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
// Print a summary of the read file.
outs() << "Summary of " << InputFilename << ":\n";
outs() << " Total size: ";
PrintSize(BufferSizeBits);
outs() << "\n";
outs() << " Stream type: ";
switch (CurStreamType) {
case UnknownBitstream: outs() << "unknown\n"; break;
case LLVMIRBitstream: outs() << "LLVM IR\n"; break;
}
outs() << " # Toplevel Blocks: " << NumTopBlocks << "\n";
outs() << "\n";
// Emit per-block stats.
outs() << "Per-block Summary:\n";
for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
E = BlockIDStats.end(); I != E; ++I) {
outs() << " Block ID #" << I->first;
if (const char *BlockName = GetBlockName(I->first, StreamFile))
outs() << " (" << BlockName << ")";
outs() << ":\n";
const PerBlockIDStats &Stats = I->second;
outs() << " Num Instances: " << Stats.NumInstances << "\n";
outs() << " Total Size: ";
PrintSize(Stats.NumBits);
outs() << "\n";
double pct = (Stats.NumBits * 100.0) / BufferSizeBits;
outs() << " Percent of file: " << format("%2.4f%%", pct) << "\n";
if (Stats.NumInstances > 1) {
outs() << " Average Size: ";
PrintSize(Stats.NumBits/(double)Stats.NumInstances);
outs() << "\n";
outs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
<< Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
outs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
<< Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
outs() << " Tot/Avg Records: " << Stats.NumRecords << "/"
<< Stats.NumRecords/(double)Stats.NumInstances << "\n";
} else {
outs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
//.........这里部分代码省略.........
示例9: LinkInFile
/// LinkInFile - opens a bitcode file and links in all objects which
/// provide symbols that are currently undefined.
///
/// Inputs:
/// File - The pathname of the bitcode file.
///
/// Outputs:
/// ErrorMessage - A C++ string detailing what error occurred, if any.
///
/// Return Value:
/// TRUE - An error occurred.
/// FALSE - No errors.
///
bool Linker::LinkInFile(const sys::Path &File, bool &is_native) {
is_native = false;
// Check for a file of name "-", which means "read standard input"
if (File.str() == "-") {
std::auto_ptr<Module> M;
OwningPtr<MemoryBuffer> Buffer;
error_code ec;
if (!(ec = MemoryBuffer::getSTDIN(Buffer))) {
if (!Buffer->getBufferSize()) {
Error = "standard input is empty";
} else {
M.reset(ParseBitcodeFile(Buffer.get(), Context, &Error));
if (M.get())
if (!LinkInModule(M.get(), &Error))
return false;
}
}
return error("Cannot link stdin: " + ec.message());
}
// Determine what variety of file it is.
std::string Magic;
if (!File.getMagicNumber(Magic, 64))
return error("Cannot find linker input '" + File.str() + "'");
switch (sys::IdentifyFileType(Magic.c_str(), 64)) {
default: llvm_unreachable("Bad file type identification");
case sys::Unknown_FileType:
return warning("Ignoring file '" + File.str() +
"' because does not contain bitcode.");
case sys::Archive_FileType:
// A user may specify an ar archive without -l, perhaps because it
// is not installed as a library. Detect that and link the archive.
if (LinkInArchive(File, is_native))
return true;
break;
case sys::Bitcode_FileType: {
verbose("Linking bitcode file '" + File.str() + "'");
std::auto_ptr<Module> M(LoadObject(File));
if (M.get() == 0)
return error("Cannot load file '" + File.str() + "': " + Error);
if (LinkInModule(M.get(), &Error))
return error("Cannot link file '" + File.str() + "': " + Error);
verbose("Linked in file '" + File.str() + "'");
break;
}
case sys::ELF_Relocatable_FileType:
case sys::ELF_SharedObject_FileType:
case sys::Mach_O_Object_FileType:
case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
case sys::COFF_FileType:
is_native = true;
break;
}
return false;
}
示例10: ArchiveFile
// Write the entire archive to the file specified when the archive was created.
// This writes to a temporary file first. Options are for creating a symbol
// table, flattening the file names (no directories, 15 chars max) and
// compressing each archive member.
bool
Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames,
std::string* ErrMsg)
{
// Make sure they haven't opened up the file, not loaded it,
// but are now trying to write it which would wipe out the file.
if (members.empty() && mapfile && mapfile->getBufferSize() > 8) {
if (ErrMsg)
*ErrMsg = "Can't write an archive not opened for writing";
return true;
}
// Create a temporary file to store the archive in
sys::Path TmpArchive = archPath;
if (TmpArchive.createTemporaryFileOnDisk(ErrMsg))
return true;
// Make sure the temporary gets removed if we crash
sys::RemoveFileOnSignal(TmpArchive);
// Create archive file for output.
std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
std::ios::binary;
std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode);
// Check for errors opening or creating archive file.
if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
TmpArchive.eraseFromDisk();
if (ErrMsg)
*ErrMsg = "Error opening archive file: " + archPath.str();
return true;
}
// If we're creating a symbol table, reset it now
if (CreateSymbolTable) {
symTabSize = 0;
symTab.clear();
}
// Write magic string to archive.
ArchiveFile << ARFILE_MAGIC;
// Loop over all member files, and write them out. Note that this also
// builds the symbol table, symTab.
for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
if (writeMember(*I, ArchiveFile, CreateSymbolTable,
TruncateNames, ErrMsg)) {
TmpArchive.eraseFromDisk();
ArchiveFile.close();
return true;
}
}
// Close archive file.
ArchiveFile.close();
// Write the symbol table
if (CreateSymbolTable) {
// At this point we have written a file that is a legal archive but it
// doesn't have a symbol table in it. To aid in faster reading and to
// ensure compatibility with other archivers we need to put the symbol
// table first in the file. Unfortunately, this means mapping the file
// we just wrote back in and copying it to the destination file.
sys::Path FinalFilePath = archPath;
// Map in the archive we just wrote.
{
OwningPtr<MemoryBuffer> arch;
if (error_code ec = MemoryBuffer::getFile(TmpArchive.c_str(), arch)) {
if (ErrMsg)
*ErrMsg = ec.message();
return true;
}
const char* base = arch->getBufferStart();
// Open another temporary file in order to avoid invalidating the
// mmapped data
if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg))
return true;
sys::RemoveFileOnSignal(FinalFilePath);
std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
if (!FinalFile.is_open() || FinalFile.bad()) {
TmpArchive.eraseFromDisk();
if (ErrMsg)
*ErrMsg = "Error opening archive file: " + FinalFilePath.str();
return true;
}
// Write the file magic number
FinalFile << ARFILE_MAGIC;
// If there is a foreign symbol table, put it into the file now. Most
// ar(1) implementations require the symbol table to be first but llvm-ar
// can deal with it being after a foreign symbol table. This ensures
// compatibility with other ar(1) implementations as well as allowing the
//.........这里部分代码省略.........
示例11: BenchmarkIRParsing
void BenchmarkIRParsing() {
outs() << "Benchmarking IR parsing...\n";
OwningPtr<MemoryBuffer> FileBuf;
error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), FileBuf);
if (ec) {
report_fatal_error("Could not open input file: " + ec.message());
}
size_t BufSize = FileBuf->getBufferSize();
const uint8_t *BufPtr =
reinterpret_cast<const uint8_t*>(FileBuf->getBufferStart());
const uint8_t *EndBufPtr =
reinterpret_cast<const uint8_t*>(FileBuf->getBufferEnd());
// Since MemoryBuffer may use mmap, make sure to first touch all bytes in the
// input buffer to make sure it's actually in memory.
volatile uint8_t *Slot = new uint8_t;
for (const uint8_t *S = BufPtr; S != EndBufPtr; ++S) {
*Slot = *S;
}
delete Slot;
outs() << "Read bitcode into buffer. Size=" << BufSize << "\n";
// Trivial copy into a new buffer with a cascading XOR that simulates
// "touching" every byte in the buffer in a simple way.
{
TimingOperationBlock T("Simple XOR copy", BufSize);
volatile uint8_t *OutBuf = new uint8_t[BufSize];
OutBuf[0] = 1;
size_t N = 1;
// Run over the input buffer from start to end-1; run over the output buffer
// from 1 to end.
for (const uint8_t *S = BufPtr; S != EndBufPtr - 1; ++S, ++N) {
OutBuf[N] = OutBuf[N - 1] ^ *S;
}
delete[] OutBuf;
}
// Bitcode parsing without any additional operations. This is the minimum
// required to actually extract information from PNaCl bitcode.
{
TimingOperationBlock T("Bitcode block parsing", BufSize);
NaClBitcodeHeader Header;
if (Header.Read(BufPtr, EndBufPtr)) {
report_fatal_error("Invalid PNaCl bitcode header");
}
if (!Header.IsSupported()) {
errs() << "Warning: " << Header.Unsupported() << "\n";
}
if (!Header.IsReadable()) {
report_fatal_error("Bitcode file is not readable");
}
NaClBitstreamReader StreamFile(BufPtr, EndBufPtr);
NaClBitstreamCursor Stream(StreamFile);
StreamFile.CollectBlockInfoNames();
DummyBitcodeParser Parser(Stream);
while (!Stream.AtEndOfStream()) {
if (Parser.Parse()) {
report_fatal_error("Parsing failed");
}
}
}
// Actual LLVM IR parsing and formation from the bitcode
{
TimingOperationBlock T("LLVM IR parsing", BufSize);
SMDiagnostic Err;
Module *M = NaClParseIRFile(InputFilename, PNaClFormat,
Err, getGlobalContext());
if (!M) {
report_fatal_error("Unable to NaClParseIRFile");
}
}
}