aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-10-31 20:59:50 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-10-31 20:59:50 +0000
commit4182ed686283b72736b287cbe28583cb641f8934 (patch)
treefc736e4110c8af9193a5aa2c0c14d6c6c8065bfc
parent724e65b18cfe6691668606cde59d44cf353282b8 (diff)
[PCH] Remove the stat cache from the PCH file.
The stat cache became essentially useless ever since we started validating all file entries in the PCH. But the motivating reason for removing it now is that it also affected correctness in this situation: -You have a header without include guards (using "#pragma once" or #import) -When creating the PCH: -The same header is referenced in an #include with different filename cases. -In the PCH, of course, we record only one file entry for the header file -But we cache in the PCH file the stat info for both filename cases -Then the source files are updated and the header file is updated in a way that its size and modification time are the same but its inode changes -When using the PCH: -We validate the headers, we check that header file and we create a file entry with its current inode -There's another #include with a filename with different case than the previously created file entry -In order to get its stat info we go through the cached stat info of the PCH and we receive the old inode -because of the different inodes, we think they are different files so we go ahead and include its contents. Removing the stat cache will potentially break clients that are attempting to use the stat cache as a way of avoiding having the actual input files available. If that use case is important, patches are welcome to bring it back in a way that will actually work correctly (i.e., emit a PCH that is self-contained, coping with literal strings, line/column computations, etc.). This fixes rdar://5502805 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167172 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/CompilerInstance.h2
-rw-r--r--include/clang/Lex/PreprocessorOptions.h6
-rw-r--r--include/clang/Serialization/ASTBitCodes.h3
-rw-r--r--include/clang/Serialization/ASTReader.h15
-rw-r--r--include/clang/Serialization/ASTWriter.h10
-rw-r--r--include/clang/Serialization/Module.h5
-rw-r--r--lib/Frontend/ASTUnit.cpp5
-rw-r--r--lib/Frontend/CompilerInstance.cpp8
-rw-r--r--lib/Frontend/FrontendAction.cpp1
-rw-r--r--lib/Serialization/ASTReader.cpp116
-rw-r--r--lib/Serialization/ASTWriter.cpp49
-rw-r--r--lib/Serialization/GeneratePCH.cpp9
-rw-r--r--lib/Serialization/Module.cpp2
-rw-r--r--test/PCH/Inputs/case-insensitive-include.h5
-rw-r--r--test/PCH/case-insensitive-include.c29
-rw-r--r--test/lit.cfg12
16 files changed, 60 insertions, 217 deletions
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 548ff86b8b..3173ad4a07 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -531,7 +531,6 @@ public:
/// context.
void createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
- bool DisableStatCache,
bool AllowPCHWithCompilerErrors,
void *DeserializationListener);
@@ -541,7 +540,6 @@ public:
static ExternalASTSource *
createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
bool DisablePCHValidation,
- bool DisableStatCache,
bool AllowPCHWithCompilerErrors,
Preprocessor &PP, ASTContext &Context,
void *DeserializationListener, bool Preamble);
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index 4f323606ee..e5fe373793 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -66,10 +66,6 @@ public:
/// precompiled headers.
bool DisablePCHValidation;
- /// \brief When true, disables the use of the stat cache within a
- /// precompiled header or AST file.
- bool DisableStatCache;
-
/// \brief When true, a PCH with compiler errors will not be rejected.
bool AllowPCHWithCompilerErrors;
@@ -168,7 +164,7 @@ public:
public:
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
DetailedRecordConditionalDirectives(false),
- DisablePCHValidation(false), DisableStatCache(false),
+ DisablePCHValidation(false),
AllowPCHWithCompilerErrors(false),
DumpDeserializedPCHDecls(false),
PrecompiledPreambleBytes(0, true),
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 4dba7b5739..8c58fb2816 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -386,9 +386,6 @@ namespace clang {
/// preloaded.
SOURCE_LOCATION_PRELOADS = 14,
- /// \brief Record code for the stat() cache.
- STAT_CACHE = 15,
-
/// \brief Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index c0d93c3607..ba26a49869 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -690,9 +690,6 @@ private:
/// headers when they are loaded.
bool DisableValidation;
- /// \brief Whether to disable the use of stat caches in AST files.
- bool DisableStatCache;
-
/// \brief Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
@@ -709,10 +706,6 @@ private:
SwitchCaseMapTy *CurrSwitchCaseStmts;
- /// \brief The number of stat() calls that hit/missed the stat
- /// cache.
- unsigned NumStatHits, NumStatMisses;
-
/// \brief The number of source location entries de-serialized from
/// the PCH file.
unsigned NumSLocEntriesRead;
@@ -1069,17 +1062,11 @@ public:
/// of its regular consistency checking, allowing the use of precompiled
/// headers that cannot be determined to be compatible.
///
- /// \param DisableStatCache If true, the AST reader will ignore the
- /// stat cache in the AST files. This performance pessimization can
- /// help when an AST file is being used in cases where the
- /// underlying files in the file system may have changed, but
- /// parsing should still continue.
- ///
/// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
/// AST file the was created out of an AST with compiler errors,
/// otherwise it will reject it.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
- bool DisableValidation = false, bool DisableStatCache = false,
+ bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false);
~ASTReader();
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 919209cc9c..ac81e2164c 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -50,7 +50,6 @@ class FPOptions;
class HeaderSearch;
class IdentifierResolver;
class MacroDefinition;
-class MemorizeStatCalls;
class OpaqueValueExpr;
class OpenCLOptions;
class ASTReader;
@@ -417,7 +416,6 @@ private:
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, const std::string &OutputFile);
void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot);
- void WriteStatCache(MemorizeStatCalls &StatCalls);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
StringRef isysroot);
@@ -467,7 +465,7 @@ private:
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
- void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ void WriteASTCore(Sema &SemaRef,
StringRef isysroot, const std::string &OutputFile,
Module *WritingModule);
@@ -482,15 +480,12 @@ public:
/// \param SemaRef a reference to the semantic analysis object that processed
/// the AST to be written into the precompiled header.
///
- /// \param StatCalls the object that cached all of the stat() calls made while
- /// searching for source files and headers.
- ///
/// \param WritingModule The module that we are writing. If null, we are
/// writing a precompiled header.
///
/// \param isysroot if non-empty, write a relocatable file whose headers
/// are relative to the given system root.
- void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ void WriteAST(Sema &SemaRef,
const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors = false);
@@ -733,7 +728,6 @@ class PCHGenerator : public SemaConsumer {
std::string isysroot;
raw_ostream *Out;
Sema *SemaPtr;
- MemorizeStatCalls *StatCalls; // owned by the FileManager
llvm::SmallVector<char, 128> Buffer;
llvm::BitstreamWriter Stream;
ASTWriter Writer;
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 2915cfc01c..39fa3d90ce 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -385,11 +385,6 @@ public:
/// \brief Diagnostic IDs and their mappings that the user changed.
SmallVector<uint64_t, 8> PragmaDiagMappings;
- /// \brief The AST stat cache installed for this file, if any.
- ///
- /// The dynamic type of this stat cache is always ASTStatCache
- void *StatCache;
-
/// \brief List of modules which depend on this module
llvm::SetVector<ModuleFile *> ImportedBy;
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index cc93d46692..da3083236b 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -779,7 +779,6 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
Reader.reset(new ASTReader(PP, Context,
/*isysroot=*/"",
/*DisableValidation=*/disableValid,
- /*DisableStatCache=*/false,
AllowPCHWithCompilerErrors));
// Recover resources if we crash before exiting this method.
@@ -2023,7 +2022,6 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
// Remap files.
PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
- PPOpts.DisableStatCache = true;
for (PreprocessorOptions::remapped_file_buffer_iterator
R = PPOpts.remapped_file_buffer_begin(),
REnd = PPOpts.remapped_file_buffer_end();
@@ -2436,7 +2434,6 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
// If the main file has been overridden due to the use of a preamble,
// make that override happen and introduce the preamble.
- PreprocessorOpts.DisableStatCache = true;
StoredDiagnostics.insert(StoredDiagnostics.end(),
stored_diag_begin(),
stored_diag_afterDriver_begin());
@@ -2509,7 +2506,7 @@ static bool serializeUnit(ASTWriter &Writer,
Sema &S,
bool hasErrors,
raw_ostream &OS) {
- Writer.WriteAST(S, 0, std::string(), 0, "", hasErrors);
+ Writer.WriteAST(S, std::string(), 0, "", hasErrors);
// Write the generated bitstream to "Out".
if (!Buffer.empty())
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 80d15c6498..c6c5fb5fe2 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -308,14 +308,12 @@ void CompilerInstance::createASTContext() {
void CompilerInstance::createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
- bool DisableStatCache,
bool AllowPCHWithCompilerErrors,
void *DeserializationListener){
OwningPtr<ExternalASTSource> Source;
bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
DisablePCHValidation,
- DisableStatCache,
AllowPCHWithCompilerErrors,
getPreprocessor(), getASTContext(),
DeserializationListener,
@@ -328,7 +326,6 @@ ExternalASTSource *
CompilerInstance::createPCHExternalASTSource(StringRef Path,
const std::string &Sysroot,
bool DisablePCHValidation,
- bool DisableStatCache,
bool AllowPCHWithCompilerErrors,
Preprocessor &PP,
ASTContext &Context,
@@ -337,7 +334,7 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
OwningPtr<ASTReader> Reader;
Reader.reset(new ASTReader(PP, Context,
Sysroot.empty() ? "" : Sysroot.c_str(),
- DisablePCHValidation, DisableStatCache,
+ DisablePCHValidation,
AllowPCHWithCompilerErrors));
Reader->setDeserializationListener(
@@ -946,8 +943,7 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
const PreprocessorOptions &PPOpts = getPreprocessorOpts();
ModuleManager = new ASTReader(getPreprocessor(), *Context,
Sysroot.empty() ? "" : Sysroot.c_str(),
- PPOpts.DisablePCHValidation,
- PPOpts.DisableStatCache);
+ PPOpts.DisablePCHValidation);
if (hasASTConsumer()) {
ModuleManager->setDeserializationListener(
getASTConsumer().GetASTDeserializationListener());
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index fa1655db79..2974334d82 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -314,7 +314,6 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
CI.createPCHExternalASTSource(
CI.getPreprocessorOpts().ImplicitPCHInclude,
CI.getPreprocessorOpts().DisablePCHValidation,
- CI.getPreprocessorOpts().DisableStatCache,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
DeserialListener);
if (!CI.getASTContext().getExternalSource())
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 874d2c4b1b..80fb464c3f 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -769,104 +769,6 @@ bool ASTReader::ParseLineTable(ModuleFile &F,
return false;
}
-namespace {
-
-class ASTStatData {
-public:
- const ino_t ino;
- const dev_t dev;
- const mode_t mode;
- const time_t mtime;
- const off_t size;
-
- ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
- : ino(i), dev(d), mode(mo), mtime(m), size(s) {}
-};
-
-class ASTStatLookupTrait {
- public:
- typedef const char *external_key_type;
- typedef const char *internal_key_type;
-
- typedef ASTStatData data_type;
-
- static unsigned ComputeHash(const char *path) {
- return llvm::HashString(path);
- }
-
- static internal_key_type GetInternalKey(const char *path) { return path; }
-
- static bool EqualKey(internal_key_type a, internal_key_type b) {
- return strcmp(a, b) == 0;
- }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
- unsigned DataLen = (unsigned) *d++;
- return std::make_pair(KeyLen + 1, DataLen);
- }
-
- static internal_key_type ReadKey(const unsigned char *d, unsigned) {
- return (const char *)d;
- }
-
- static data_type ReadData(const internal_key_type, const unsigned char *d,
- unsigned /*DataLen*/) {
- using namespace clang::io;
-
- ino_t ino = (ino_t) ReadUnalignedLE32(d);
- dev_t dev = (dev_t) ReadUnalignedLE32(d);
- mode_t mode = (mode_t) ReadUnalignedLE16(d);
- time_t mtime = (time_t) ReadUnalignedLE64(d);
- off_t size = (off_t) ReadUnalignedLE64(d);
- return data_type(ino, dev, mode, mtime, size);
- }
-};
-
-/// \brief stat() cache for precompiled headers.
-///
-/// This cache is very similar to the stat cache used by pretokenized
-/// headers.
-class ASTStatCache : public FileSystemStatCache {
- typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
- CacheTy *Cache;
-
- unsigned &NumStatHits, &NumStatMisses;
-public:
- ASTStatCache(const unsigned char *Buckets, const unsigned char *Base,
- unsigned &NumStatHits, unsigned &NumStatMisses)
- : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
- Cache = CacheTy::Create(Buckets, Base);
- }
-
- ~ASTStatCache() { delete Cache; }
-
- LookupResult getStat(const char *Path, struct stat &StatBuf,
- int *FileDescriptor) {
- // Do the lookup for the file's data in the AST file.
- CacheTy::iterator I = Cache->find(Path);
-
- // If we don't get a hit in the AST file just forward to 'stat'.
- if (I == Cache->end()) {
- ++NumStatMisses;
- return statChained(Path, StatBuf, FileDescriptor);
- }
-
- ++NumStatHits;
- ASTStatData Data = *I;
-
- StatBuf.st_ino = Data.ino;
- StatBuf.st_dev = Data.dev;
- StatBuf.st_mtime = Data.mtime;
- StatBuf.st_mode = Data.mode;
- StatBuf.st_size = Data.size;
- return CacheExists;
- }
-};
-} // end anonymous namespace
-
-
/// \brief Read a source manager block
bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
using namespace SrcMgr;
@@ -2362,18 +2264,6 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) {
break;
}
- case STAT_CACHE: {
- if (!DisableStatCache) {
- ASTStatCache *MyStatCache =
- new ASTStatCache((const unsigned char *)BlobStart + Record[0],
- (const unsigned char *)BlobStart,
- NumStatHits, NumStatMisses);
- FileMgr.addStatCache(MyStatCache);
- F.StatCache = MyStatCache;
- }
- break;
- }
-
case EXT_VECTOR_DECLS:
for (unsigned I = 0, N = Record.size(); I != N; ++I)
ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
@@ -5624,8 +5514,6 @@ void ASTReader::PrintStats() {
SelectorsLoaded.end(),
Selector());
- std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
- std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
if (unsigned TotalNumSLocEntries = getTotalNumSLocs())
std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
NumSLocEntriesRead, TotalNumSLocEntries,
@@ -7005,16 +6893,14 @@ void ASTReader::FinishedDeserializing() {
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
- bool DisableStatCache, bool AllowASTWithCompilerErrors)
+ bool AllowASTWithCompilerErrors)
: Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
Consumer(0), ModuleMgr(PP.getFileManager()),
isysroot(isysroot), DisableValidation(DisableValidation),
- DisableStatCache(DisableStatCache),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
- NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 500351f55f..a2e8b71123 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -803,7 +803,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(PP_COUNTER_VALUE);
RECORD(SOURCE_LOCATION_OFFSETS);
RECORD(SOURCE_LOCATION_PRELOADS);
- RECORD(STAT_CACHE);
RECORD(EXT_VECTOR_DECLS);
RECORD(PPD_ENTITIES_OFFSETS);
RECORD(REFERENCED_SELECTOR_POOL);
@@ -1328,46 +1327,6 @@ public:
};
} // end anonymous namespace
-/// \brief Write the stat() system call cache to the AST file.
-void ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) {
- // Build the on-disk hash table containing information about every
- // stat() call.
- OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator;
- unsigned NumStatEntries = 0;
- for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
- StatEnd = StatCalls.end();
- Stat != StatEnd; ++Stat, ++NumStatEntries) {
- StringRef Filename = Stat->first();
- Generator.insert(Filename.data(), Stat->second);
- }
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> StatCacheData;
- uint32_t BucketOffset;
- {
- llvm::raw_svector_ostream Out(StatCacheData);
- // Make sure that no bucket is at offset 0
- clang::io::Emit32(Out, 0);
- BucketOffset = Generator.Emit(Out);
- }
-
- // Create a blob abbreviation
- using namespace llvm;
- BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
- Abbrev->Add(BitCodeAbbrevOp(STAT_CACHE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev);
-
- // Write the stat cache
- RecordData Record;
- Record.push_back(STAT_CACHE);
- Record.push_back(BucketOffset);
- Record.push_back(NumStatEntries);
- Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str());
-}
-
//===----------------------------------------------------------------------===//
// Source Manager Serialization
//===----------------------------------------------------------------------===//
@@ -3404,7 +3363,7 @@ ASTWriter::~ASTWriter() {
delete I->second;
}
-void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+void ASTWriter::WriteAST(Sema &SemaRef,
const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors) {
@@ -3423,7 +3382,7 @@ void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
Context = &SemaRef.Context;
PP = &SemaRef.PP;
this->WritingModule = WritingModule;
- WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile, WritingModule);
+ WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
Context = 0;
PP = 0;
this->WritingModule = 0;
@@ -3440,7 +3399,7 @@ static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
}
}
-void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+void ASTWriter::WriteASTCore(Sema &SemaRef,
StringRef isysroot,
const std::string &OutputFile,
Module *WritingModule) {
@@ -3597,8 +3556,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// Write the remaining AST contents.
RecordData Record;
Stream.EnterSubblock(AST_BLOCK_ID, 5);
- if (StatCalls && isysroot.empty())
- WriteStatCache(*StatCalls);
// Create a lexical update block containing all of the declarations in the
// translation unit that do not come from other AST files.
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index c2b353a964..870d654895 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -18,7 +18,6 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemStatCache.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
@@ -32,11 +31,7 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP,
raw_ostream *OS)
: PP(PP), OutputFile(OutputFile), Module(Module),
isysroot(isysroot.str()), Out(OS),
- SemaPtr(0), StatCalls(0), Stream(Buffer), Writer(Stream) {
- // Install a stat() listener to keep track of all of the stat()
- // calls.
- StatCalls = new MemorizeStatCalls();
- PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/false);
+ SemaPtr(0), Stream(Buffer), Writer(Stream) {
}
PCHGenerator::~PCHGenerator() {
@@ -48,7 +43,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
// Emit the PCH file
assert(SemaPtr && "No Sema?");
- Writer.WriteAST(*SemaPtr, StatCalls, OutputFile, Module, isysroot);
+ Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot);
// Write the generated bitstream to "Out".
Out->write((char *)&Buffer.front(), Buffer.size());
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 09ea754d44..5e42ab4211 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -41,7 +41,7 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
FileSortedDecls(0), NumFileSortedDecls(0),
RedeclarationsMap(0), LocalNumRedeclarationsInMap(0),
ObjCCategoriesMap(0), LocalNumObjCCategoriesInMap(0),
- LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0)
+ LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0)
{}
ModuleFile::~ModuleFile() {
diff --git a/test/PCH/Inputs/case-insensitive-include.h b/test/PCH/Inputs/case-insensitive-include.h
new file mode 100644
index 0000000000..60bdf36dbb
--- /dev/null
+++ b/test/PCH/Inputs/case-insensitive-include.h
@@ -0,0 +1,5 @@
+#pragma once
+
+struct S {
+ int x;
+};
diff --git a/test/PCH/case-insensitive-include.c b/test/PCH/case-insensitive-include.c
new file mode 100644
index 0000000000..707de702f1
--- /dev/null
+++ b/test/PCH/case-insensitive-include.c
@@ -0,0 +1,29 @@
+// REQUIRES: case-insensitive-filesystem
+
+// Test this without pch.
+// RUN: cp %S/Inputs/case-insensitive-include.h %T
+// RUN: %clang_cc1 -fsyntax-only %s -include %s -I %T -verify
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t.pch %s -I %T
+
+// Modify inode of the header.
+// RUN: cp %T/case-insensitive-include.h %t.copy
+// RUN: touch -r %T/case-insensitive-include.h %t.copy
+// RUN: mv %t.copy %T/case-insensitive-include.h
+
+// RUN: %clang_cc1 -fsyntax-only %s -include-pch %t.pch -I %T -verify
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#include "case-insensitive-include.h"
+#include "Case-Insensitive-Include.h"
+
+#else
+
+#include "Case-Insensitive-Include.h"
+
+#endif
diff --git a/test/lit.cfg b/test/lit.cfg
index b22346e046..3cbe01384b 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -4,6 +4,7 @@ import os
import platform
import re
import subprocess
+import tempfile
# Configuration file for the 'lit' test runner.
@@ -225,6 +226,17 @@ if platform.system() in ['Darwin']:
if platform.system() not in ['Windows']:
config.available_features.add('ansi-escape-sequences')
+# Case-insensitive file system
+def is_filesystem_case_insensitive():
+ handle, path = tempfile.mkstemp(prefix='case-test')
+ isInsensitive = os.path.exists(path.upper())
+ os.close(handle)
+ os.remove(path)
+ return isInsensitive
+
+if is_filesystem_case_insensitive():
+ config.available_features.add('case-insensitive-filesystem')
+
# [PR8833] LLP64-incompatible tests
if not re.match(r'^x86_64.*-(win32|mingw32)$', config.target_triple):
config.available_features.add('LP64')