aboutsummaryrefslogtreecommitdiff
path: root/lib/Basic/SourceManager.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-12-06 05:43:36 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-12-06 05:43:36 +0000
commit21a8bed504a95df019771ab1a3dc9ecccfd9cfaa (patch)
treeeb0091140327707f4b84d3c4d121608bc38f01ed /lib/Basic/SourceManager.cpp
parentc9c1e9c4b513e83146eff1728142683980df26a7 (diff)
Add a pretty horrible hack to prevent clang from crashing with inconsistent PCH
files. - The issue is that PCH uses a stat cache, which may reference files which have been deleted or moved. In such cases ContentCache::getBuffer was returning 0 but most clients are incapable of dealing with this (i.e., they don't). For the time being, resolve this issue by just making up some invalid file contents and. Eventually we should detect that we are in an inconsistent situation and error out with a nice message that the PCH is out of date. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90699 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
-rw-r--r--lib/Basic/SourceManager.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index a3e72e8b40..354bf7befb 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -56,9 +56,25 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
const llvm::MemoryBuffer *ContentCache::getBuffer(std::string *ErrorStr) const {
// Lazily create the Buffer for ContentCaches that wrap files.
if (!Buffer && Entry) {
- // FIXME: Should we support a way to not have to do this check over
- // and over if we cannot open the file?
Buffer = MemoryBuffer::getFile(Entry->getName(), ErrorStr,Entry->getSize());
+
+ // 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
+ // exists. Most likely, we were using a stat cache with an invalid entry but
+ // the file could also have been removed during processing. Since we can't
+ // really deal with this situation, just create an empty buffer.
+ //
+ // FIXME: This is definitely not ideal, but our immediate clients can't
+ // currently handle returning a null entry here. Ideally we should detect
+ // that we are in an inconsistent situation and error out as quickly as
+ // possible.
+ if (!Buffer) {
+ const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
+ Buffer = MemoryBuffer::getNewMemBuffer(Entry->getSize(), "<invalid>");
+ char *Ptr = const_cast<char*>(Buffer->getBufferStart());
+ for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
+ Ptr[i] = FillStr[i % FillStr.size()];
+ }
}
return Buffer;
}