[cfe-commits] r127052 - in /cfe/trunk: include/clang/Basic/SourceManager.h include/clang/Frontend/ASTUnit.h lib/AST/ASTImporter.cpp lib/Basic/SourceManager.cpp lib/Frontend/ASTUnit.cpp lib/Frontend/CacheTokens.cpp lib/Serialization/ASTWriter.cpp tools/libclang/CIndexInclusionStack.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Mar 4 17:03:53 PST 2011
Author: akirtzidis
Date: Fri Mar 4 19:03:53 2011
New Revision: 127052
URL: http://llvm.org/viewvc/llvm-project?rev=127052&view=rev
Log:
Currently we can only remap a file by creating a MemoryBuffer and replacing the file contents with it.
Allow remapping a file by specifying another filename whose contents should be loaded if the original
file gets loaded. This allows to override files without having to create & load buffers in advance.
Modified:
cfe/trunk/include/clang/Basic/SourceManager.h
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/Basic/SourceManager.cpp
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Frontend/CacheTokens.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndexInclusionStack.cpp
Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Fri Mar 4 19:03:53 2011
@@ -66,10 +66,16 @@
mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
public:
- /// Reference to the file entry. This reference does not own
- /// the FileEntry object. It is possible for this to be NULL if
+ /// Reference to the file entry representing this ContentCache.
+ /// This reference does not own the FileEntry object.
+ /// It is possible for this to be NULL if
/// the ContentCache encapsulates an imaginary text buffer.
- const FileEntry *Entry;
+ const FileEntry *OrigEntry;
+
+ /// \brief References the file which the contents were actually loaded from.
+ /// Can be different from 'Entry' if we overridden the contents of one file
+ /// with the contents of another file.
+ const FileEntry *ContentsEntry;
/// SourceLineCache - A bump pointer allocated array of offsets for each
/// source line. This is lazily computed. This is owned by the
@@ -132,7 +138,12 @@
}
ContentCache(const FileEntry *Ent = 0)
- : Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {}
+ : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
+ SourceLineCache(0), NumLines(0) {}
+
+ ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
+ : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
+ SourceLineCache(0), NumLines(0) {}
~ContentCache();
@@ -142,7 +153,8 @@
ContentCache(const ContentCache &RHS)
: Buffer(0, false), SourceLineCache(0)
{
- Entry = RHS.Entry;
+ OrigEntry = RHS.OrigEntry;
+ ContentsEntry = RHS.ContentsEntry;
assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0
&& "Passed ContentCache object cannot own a buffer.");
@@ -380,6 +392,9 @@
/// non-null, FileEntry pointers.
llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
+ /// \brief Files that have been overriden with the contents from another file.
+ llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
+
/// MemBufferInfos - Information about various memory buffers that we have
/// read in. All FileEntry* within the stored ContentCache objects are NULL,
/// as they do not refer to a file.
@@ -527,6 +542,15 @@
const llvm::MemoryBuffer *Buffer,
bool DoNotFree = false);
+ /// \brief Override the the given source file with another one.
+ ///
+ /// \param SourceFile the source file which will be overriden.
+ ///
+ /// \param NewFile the file whose contents will be used as the
+ /// data instead of the contents of the given source file.
+ void overrideFileContents(const FileEntry *SourceFile,
+ const FileEntry *NewFile);
+
//===--------------------------------------------------------------------===//
// FileID manipulation methods.
//===--------------------------------------------------------------------===//
@@ -547,7 +571,7 @@
/// getFileEntryForID - Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
- return getSLocEntry(FID).getFile().getContentCache()->Entry;
+ return getSLocEntry(FID).getFile().getContentCache()->OrigEntry;
}
/// getBufferData - Return a StringRef to the source buffer data for the
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri Mar 4 19:03:53 2011
@@ -535,9 +535,11 @@
/// that might still be used as a precompiled header or preamble.
bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; }
+ typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *>
+ FilenameOrMemBuf;
/// \brief A mapping from a file name to the memory buffer that stores the
/// remapped contents of that file.
- typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
+ typedef std::pair<std::string, FilenameOrMemBuf> RemappedFile;
/// \brief Create a ASTUnit from an AST file.
///
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Mar 4 19:03:53 2011
@@ -4156,12 +4156,12 @@
// Map the FileID for to the "to" source manager.
FileID ToID;
const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (Cache->Entry) {
+ if (Cache->OrigEntry) {
// FIXME: We probably want to use getVirtualFile(), so we don't hit the
// disk again
// FIXME: We definitely want to re-use the existing MemoryBuffer, rather
// than mmap the files several times.
- const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
+ const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
ToID = ToSM.createFileID(Entry, ToIncludeLoc,
FromSLoc.getFile().getFileCharacteristic());
} else {
Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Fri Mar 4 19:03:53 2011
@@ -52,7 +52,7 @@
/// file is not lazily brought in from disk to satisfy this query.
unsigned ContentCache::getSize() const {
return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
- : (unsigned) Entry->getSize();
+ : (unsigned) ContentsEntry->getSize();
}
void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
@@ -71,7 +71,7 @@
bool *Invalid) const {
// Lazily create the Buffer for ContentCaches that wrap files. If we already
// computed it, jsut return what we have.
- if (Buffer.getPointer() || Entry == 0) {
+ if (Buffer.getPointer() || ContentsEntry == 0) {
if (Invalid)
*Invalid = isBufferInvalid();
@@ -79,7 +79,7 @@
}
std::string ErrorStr;
- Buffer.setPointer(SM.getFileManager().getBufferForFile(Entry, &ErrorStr));
+ Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, &ErrorStr));
// If we were unable to open the file, then we are in an inconsistent
// situation where the content cache referenced a file which no longer
@@ -93,18 +93,18 @@
// possible.
if (!Buffer.getPointer()) {
const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
- Buffer.setPointer(MemoryBuffer::getNewMemBuffer(Entry->getSize(),
+ Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(),
"<invalid>"));
char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
- for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
+ for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i)
Ptr[i] = FillStr[i % FillStr.size()];
if (Diag.isDiagnosticInFlight())
Diag.SetDelayedDiagnostic(diag::err_cannot_open_file,
- Entry->getName(), ErrorStr);
+ ContentsEntry->getName(), ErrorStr);
else
Diag.Report(Loc, diag::err_cannot_open_file)
- << Entry->getName() << ErrorStr;
+ << ContentsEntry->getName() << ErrorStr;
Buffer.setInt(Buffer.getInt() | InvalidFlag);
@@ -114,13 +114,13 @@
// Check that the file's size is the same as in the file entry (which may
// have come from a stat cache).
- if (getRawBuffer()->getBufferSize() != (size_t)Entry->getSize()) {
+ if (getRawBuffer()->getBufferSize() != (size_t)ContentsEntry->getSize()) {
if (Diag.isDiagnosticInFlight())
Diag.SetDelayedDiagnostic(diag::err_file_modified,
- Entry->getName());
+ ContentsEntry->getName());
else
Diag.Report(Loc, diag::err_file_modified)
- << Entry->getName();
+ << ContentsEntry->getName();
Buffer.setInt(Buffer.getInt() | InvalidFlag);
if (Invalid) *Invalid = true;
@@ -147,7 +147,7 @@
if (BOM) {
Diag.Report(Loc, diag::err_unsupported_bom)
- << BOM << Entry->getName();
+ << BOM << ContentsEntry->getName();
Buffer.setInt(Buffer.getInt() | InvalidFlag);
}
@@ -395,7 +395,16 @@
unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
EntryAlign = std::max(8U, EntryAlign);
Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
- new (Entry) ContentCache(FileEnt);
+
+ // If the file contents are overridden with contents from another file,
+ // pass that file to ContentCache.
+ llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
+ overI = OverriddenFiles.find(FileEnt);
+ if (overI == OverriddenFiles.end())
+ new (Entry) ContentCache(FileEnt);
+ else
+ new (Entry) ContentCache(FileEnt, overI->second);
+
return Entry;
}
@@ -531,6 +540,17 @@
const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree);
}
+void SourceManager::overrideFileContents(const FileEntry *SourceFile,
+ const FileEntry *NewFile) {
+ assert(SourceFile->getSize() == NewFile->getSize() &&
+ "Different sizes, use the FileManager to create a virtual file with "
+ "the correct size");
+ assert(FileInfos.count(SourceFile) == 0 &&
+ "This function should be called at the initialization stage, before "
+ "any parsing occurs.");
+ OverriddenFiles[SourceFile] = NewFile;
+}
+
llvm::StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
bool MyInvalid = false;
const SLocEntry &SLoc = getSLocEntry(FID.ID);
@@ -1071,8 +1091,8 @@
// before the MemBuffer as this will avoid unnecessarily paging in the
// MemBuffer.
const char *Filename;
- if (C->Entry)
- Filename = C->Entry->getName();
+ if (C->OrigEntry)
+ Filename = C->OrigEntry->getName();
else
Filename = C->getBuffer(Diag, *this)->getBufferIdentifier();
bool Invalid = false;
@@ -1158,12 +1178,12 @@
= MainSLoc.getFile().getContentCache();
if (!MainContentCache) {
// Can't do anything
- } else if (MainContentCache->Entry == SourceFile) {
+ } else if (MainContentCache->OrigEntry == SourceFile) {
FirstFID = MainFileID;
} else {
// Fall back: check whether we have the same base name and inode
// as the main file.
- const FileEntry *MainFile = MainContentCache->Entry;
+ const FileEntry *MainFile = MainContentCache->OrigEntry;
SourceFileName = llvm::sys::path::filename(SourceFile->getName());
if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) {
SourceFileInode = getActualFileInode(SourceFile);
@@ -1188,7 +1208,7 @@
const SLocEntry &SLoc = getSLocEntry(I);
if (SLoc.isFile() &&
SLoc.getFile().getContentCache() &&
- SLoc.getFile().getContentCache()->Entry == SourceFile) {
+ SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
FirstFID = FileID::get(I);
break;
}
@@ -1208,7 +1228,7 @@
if (SLoc.isFile()) {
const ContentCache *FileContentCache
= SLoc.getFile().getContentCache();
- const FileEntry *Entry =FileContentCache? FileContentCache->Entry : 0;
+ const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0;
if (Entry &&
*SourceFileName == llvm::sys::path::filename(Entry->getName())) {
if (llvm::Optional<ino_t> EntryInode = getActualFileInode(Entry)) {
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri Mar 4 19:03:53 2011
@@ -508,22 +508,50 @@
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
for (unsigned I = 0; I != NumRemappedFiles; ++I) {
- // Create the file entry for the file that we're mapping from.
- const FileEntry *FromFile
- = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
- RemappedFiles[I].second->getBufferSize(),
- 0);
- if (!FromFile) {
- AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
- << RemappedFiles[I].first;
- delete RemappedFiles[I].second;
- continue;
+ FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
+ if (const llvm::MemoryBuffer *
+ memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
+ // Create the file entry for the file that we're mapping from.
+ const FileEntry *FromFile
+ = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
+ memBuf->getBufferSize(),
+ 0);
+ if (!FromFile) {
+ AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
+ << RemappedFiles[I].first;
+ delete memBuf;
+ continue;
+ }
+
+ // Override the contents of the "from" file with the contents of
+ // the "to" file.
+ AST->getSourceManager().overrideFileContents(FromFile, memBuf);
+
+ } else {
+ const char *fname = fileOrBuf.get<const char *>();
+ const FileEntry *ToFile = AST->FileMgr->getFile(fname);
+ if (!ToFile) {
+ AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file)
+ << RemappedFiles[I].first << fname;
+ continue;
+ }
+
+ // Create the file entry for the file that we're mapping from.
+ const FileEntry *FromFile
+ = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
+ ToFile->getSize(),
+ 0);
+ if (!FromFile) {
+ AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
+ << RemappedFiles[I].first;
+ delete memBuf;
+ continue;
+ }
+
+ // Override the contents of the "from" file with the contents of
+ // the "to" file.
+ AST->getSourceManager().overrideFileContents(FromFile, ToFile);
}
-
- // Override the contents of the "from" file with the contents of
- // the "to" file.
- AST->getSourceManager().overrideFileContents(FromFile,
- RemappedFiles[I].second);
}
// Gather Info for preprocessor construction later on.
@@ -1391,7 +1419,7 @@
FEnd = SourceMgr.fileinfo_end();
F != FEnd;
++F) {
- const FileEntry *File = F->second->Entry;
+ const FileEntry *File = F->second->OrigEntry;
if (!File || F->second->getRawBuffer() == MainFileBuffer)
continue;
@@ -1612,9 +1640,16 @@
}
// Override any files that need remapping
- for (unsigned I = 0; I != NumRemappedFiles; ++I)
- CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
- RemappedFiles[I].second);
+ for (unsigned I = 0; I != NumRemappedFiles; ++I) {
+ FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
+ if (const llvm::MemoryBuffer *
+ memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
+ CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf);
+ } else {
+ const char *fname = fileOrBuf.get<const char *>();
+ CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname);
+ }
+ }
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
@@ -1665,9 +1700,18 @@
delete R->second;
}
Invocation->getPreprocessorOpts().clearRemappedFiles();
- for (unsigned I = 0; I != NumRemappedFiles; ++I)
- Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
- RemappedFiles[I].second);
+ for (unsigned I = 0; I != NumRemappedFiles; ++I) {
+ FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
+ if (const llvm::MemoryBuffer *
+ memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
+ Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+ memBuf);
+ } else {
+ const char *fname = fileOrBuf.get<const char *>();
+ Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+ fname);
+ }
+ }
// If we have a preamble file lying around, or if we might try to
// build a precompiled preamble, do so now.
@@ -2000,9 +2044,15 @@
PreprocessorOpts.clearRemappedFiles();
PreprocessorOpts.RetainRemappedFileBuffers = true;
for (unsigned I = 0; I != NumRemappedFiles; ++I) {
- PreprocessorOpts.addRemappedFile(RemappedFiles[I].first,
- RemappedFiles[I].second);
- OwnedBuffers.push_back(RemappedFiles[I].second);
+ FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
+ if (const llvm::MemoryBuffer *
+ memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
+ PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf);
+ OwnedBuffers.push_back(memBuf);
+ } else {
+ const char *fname = fileOrBuf.get<const char *>();
+ PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname);
+ }
}
// Use the code completion consumer we were given, but adding any cached
Modified: cfe/trunk/lib/Frontend/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CacheTokens.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CacheTokens.cpp (original)
+++ cfe/trunk/lib/Frontend/CacheTokens.cpp Fri Mar 4 19:03:53 2011
@@ -473,7 +473,7 @@
for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(),
E = SM.fileinfo_end(); I != E; ++I) {
const SrcMgr::ContentCache &C = *I->second;
- const FileEntry *FE = C.Entry;
+ const FileEntry *FE = C.OrigEntry;
// FIXME: Handle files with non-absolute paths.
if (llvm::sys::path::is_relative(FE->getName()))
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Mar 4 19:03:53 2011
@@ -1428,7 +1428,7 @@
// Figure out which record code to use.
unsigned Code;
if (SLoc->isFile()) {
- if (SLoc->getFile().getContentCache()->Entry)
+ if (SLoc->getFile().getContentCache()->OrigEntry)
Code = SM_SLOC_FILE_ENTRY;
else
Code = SM_SLOC_BUFFER_ENTRY;
@@ -1445,16 +1445,19 @@
Record.push_back(File.hasLineDirectives());
const SrcMgr::ContentCache *Content = File.getContentCache();
- if (Content->Entry) {
+ if (Content->OrigEntry) {
+ assert(Content->OrigEntry == Content->ContentsEntry &&
+ "Writing to AST an overriden file is not supported");
+
// The source location entry is a file. The blob associated
// with this entry is the file name.
// Emit size/modification time for this file.
- Record.push_back(Content->Entry->getSize());
- Record.push_back(Content->Entry->getModificationTime());
+ Record.push_back(Content->OrigEntry->getSize());
+ Record.push_back(Content->OrigEntry->getModificationTime());
// Turn the file name into an absolute path, if it isn't already.
- const char *Filename = Content->Entry->getName();
+ const char *Filename = Content->OrigEntry->getName();
llvm::SmallString<128> FilePath(Filename);
llvm::sys::fs::make_absolute(FilePath);
Filename = FilePath.c_str();
Modified: cfe/trunk/tools/libclang/CIndexInclusionStack.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexInclusionStack.cpp?rev=127052&r1=127051&r2=127052&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexInclusionStack.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexInclusionStack.cpp Fri Mar 4 19:03:53 2011
@@ -47,7 +47,7 @@
continue;
const SrcMgr::FileInfo &FI = SL.getFile();
- if (!FI.getContentCache()->Entry)
+ if (!FI.getContentCache()->OrigEntry)
continue;
// Build the inclusion stack.
@@ -61,7 +61,7 @@
// Callback to the client.
// FIXME: We should have a function to construct CXFiles.
- CB((CXFile) FI.getContentCache()->Entry,
+ CB((CXFile) FI.getContentCache()->OrigEntry,
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
More information about the cfe-commits
mailing list