From: Douglas Gregor Date: Fri, 15 Mar 2013 22:15:07 +0000 (+0000) Subject: Introduce SDKSettings.plist as an input file dependency... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a18c3b25a2d7eb7f770ce91ee5e14433b2a1cb6;p=clang Introduce SDKSettings.plist as an input file dependency for PCH/modules. When we're building a precompiled header or module against an SDK on Darwin, there will be a file SDKSettings.plist in the sysroot. Since stat()'ing every system header on which a module or PCH file depends is performance suicide, we instead stat() just SDKSettings.plist. This hack works well on Darwin; it's unclear how we want to handle this on other platforms. If there is a canonical file, we should use it; if not, we either have to take the performance hit of stat()'ing system headers repeatedly or roll the dice by not checking anything. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177194 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 1bbf74061f..3f76a9781f 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -48,6 +48,7 @@ class CXXCtorInitializer; class FileEntry; class FPOptions; class HeaderSearch; +class HeaderSearchOptions; class IdentifierResolver; class MacroDefinition; class OpaqueValueExpr; @@ -416,7 +417,9 @@ private: void WriteBlockInfoBlock(); void WriteControlBlock(Preprocessor &PP, ASTContext &Context, StringRef isysroot, const std::string &OutputFile); - void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot); + void WriteInputFiles(SourceManager &SourceMgr, + HeaderSearchOptions &HSOpts, + StringRef isysroot); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, StringRef isysroot); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 10a80444a2..b113c76f44 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1213,11 +1213,24 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir); } - WriteInputFiles(Context.SourceMgr, isysroot); + WriteInputFiles(Context.SourceMgr, + PP.getHeaderSearchInfo().getHeaderSearchOpts(), + isysroot); Stream.ExitBlock(); } -void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { +namespace { + /// \brief An input file. + struct InputFileEntry { + const FileEntry *File; + bool IsSystemFile; + bool BufferOverridden; + }; +} + +void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, + HeaderSearchOptions &HSOpts, + StringRef isysroot) { using namespace llvm; Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4); RecordData Record; @@ -1234,7 +1247,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { // Get all ContentCache objects for files, sorted by whether the file is a // system one or not. System files go at the back, users files at the front. - std::deque SortedFiles; + std::deque SortedFiles; for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) { // Get this source location entry. const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I); @@ -1247,20 +1260,38 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { if (!Cache->OrigEntry) continue; + InputFileEntry Entry; + Entry.File = Cache->OrigEntry; + Entry.IsSystemFile = Cache->IsSystemFile; + Entry.BufferOverridden = Cache->BufferOverridden; if (Cache->IsSystemFile) - SortedFiles.push_back(Cache); + SortedFiles.push_back(Entry); else - SortedFiles.push_front(Cache); + SortedFiles.push_front(Entry); + } + + // If we have an isysroot for a Darwin SDK, include its SDKSettings.plist in + // the set of (non-system) input files. This is simple heuristic for + // detecting whether the system headers may have changed, because it is too + // expensive to stat() all of the system headers. + FileManager &FileMgr = SourceMgr.getFileManager(); + if (!HSOpts.Sysroot.empty()) { + llvm::SmallString<128> SDKSettingsFileName(HSOpts.Sysroot); + llvm::sys::path::append(SDKSettingsFileName, "SDKSettings.plist"); + if (const FileEntry *SDKSettingsFile = FileMgr.getFile(SDKSettingsFileName)) { + InputFileEntry Entry = { SDKSettingsFile, false, false }; + SortedFiles.push_front(Entry); + } } unsigned UserFilesNum = 0; // Write out all of the input files. std::vector InputFileOffsets; - for (std::deque::iterator + for (std::deque::iterator I = SortedFiles.begin(), E = SortedFiles.end(); I != E; ++I) { - const SrcMgr::ContentCache *Cache = *I; + const InputFileEntry &Entry = *I; - uint32_t &InputFileID = InputFileIDs[Cache->OrigEntry]; + uint32_t &InputFileID = InputFileIDs[Entry.File]; if (InputFileID != 0) continue; // already recorded this file. @@ -1269,7 +1300,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { InputFileID = InputFileOffsets.size(); - if (!Cache->IsSystemFile) + if (!Entry.IsSystemFile) ++UserFilesNum; Record.clear(); @@ -1277,19 +1308,19 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { Record.push_back(InputFileOffsets.size()); // Emit size/modification time for this file. - Record.push_back(Cache->OrigEntry->getSize()); - Record.push_back(Cache->OrigEntry->getModificationTime()); + Record.push_back(Entry.File->getSize()); + Record.push_back(Entry.File->getModificationTime()); // Whether this file was overridden. - Record.push_back(Cache->BufferOverridden); + Record.push_back(Entry.BufferOverridden); // Turn the file name into an absolute path, if it isn't already. - const char *Filename = Cache->OrigEntry->getName(); + const char *Filename = Entry.File->getName(); SmallString<128> FilePath(Filename); // Ask the file manager to fixup the relative path for us. This will // honor the working directory. - SourceMgr.getFileManager().FixupRelativePath(FilePath); + FileMgr.FixupRelativePath(FilePath); // FIXME: This call to make_absolute shouldn't be necessary, the // call to FixupRelativePath should always return an absolute path. @@ -1300,7 +1331,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot) { Stream.EmitRecordWithBlob(IFAbbrevCode, Record, Filename); } - + Stream.ExitBlock(); // Create input file offsets abbreviation.