diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 092d5470911d..05e66b39c932 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -367,14 +367,17 @@ public: /// FIXME: This will need to be generalized for submodules. StringRef findModuleForHeader(const FileEntry *File); - typedef std::vector::const_iterator header_file_iterator; - header_file_iterator header_file_begin() const { return FileInfo.begin(); } - header_file_iterator header_file_end() const { return FileInfo.end(); } unsigned header_file_size() const { return FileInfo.size(); } // Used by ASTReader. void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); + /// getFileInfo - Return the HeaderFileInfo structure for the specified + /// FileEntry. + const HeaderFileInfo &getFileInfo(const FileEntry *FE) const { + return const_cast(this)->getFileInfo(FE); + } + // Used by external tools typedef std::vector::const_iterator search_dir_iterator; search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); } diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 2fc75c22724d..cdba3e9883a3 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -377,7 +377,7 @@ private: const Preprocessor &PP, StringRef isysroot); void WritePreprocessor(const Preprocessor &PP, bool IsModule); - void WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot); + void WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot); void WritePreprocessorDetail(PreprocessingRecord &PPRec); void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag); void WriteCXXBaseSpecifiersOffsets(); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 0a7fe4c4924a..667b3a58ddc4 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1220,14 +1220,14 @@ namespace { // Trait used for the on-disk hash table of header search information. class HeaderFileInfoTrait { ASTWriter &Writer; - HeaderSearch &HS; + const HeaderSearch &HS; // Keep track of the framework names we've used during serialization. SmallVector FrameworkStringData; llvm::StringMap FrameworkNameOffset; public: - HeaderFileInfoTrait(ASTWriter &Writer, HeaderSearch &HS) + HeaderFileInfoTrait(ASTWriter &Writer, const HeaderSearch &HS) : Writer(Writer), HS(HS) { } typedef const char *key_type; @@ -1306,7 +1306,7 @@ namespace { /// \param HS The header search structure to save. /// /// \param Chain Whether we're creating a chained AST file. -void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot) { +void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) { SmallVector FilesByUID; HS.getFileMgr().GetUniqueIDMapping(FilesByUID); @@ -1322,7 +1322,9 @@ void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot) { if (!File) continue; - const HeaderFileInfo &HFI = HS.header_file_begin()[UID]; + // Use HeaderSearch's getFileInfo to make sure we get the HeaderFileInfo + // from the external source if it was not provided already. + const HeaderFileInfo &HFI = HS.getFileInfo(File); if (HFI.External && Chain) continue; diff --git a/clang/test/Index/preamble-reparse-import.m b/clang/test/Index/preamble-reparse-import.m new file mode 100644 index 000000000000..9bdb89a1dc50 --- /dev/null +++ b/clang/test/Index/preamble-reparse-import.m @@ -0,0 +1,12 @@ +// RUN: c-index-test -write-pch %t.h.pch -x objective-c %s-2.h +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_FAILONERROR=1 \ +// RUN: c-index-test -test-load-source-reparse 3 local %s -include %t.h +// RUN: c-index-test -write-pch %t.h.pch -x objective-c %s-3.h +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_FAILONERROR=1 \ +// RUN: c-index-test -test-load-source-reparse 3 local %s -include %t.h + +#import "preamble-reparse-import.m-1.h" + +void foo(); +#import "preamble-reparse-import.m-2.h" +#import "preamble-reparse-import.m-1.h" diff --git a/clang/test/Index/preamble-reparse-import.m-1.h b/clang/test/Index/preamble-reparse-import.m-1.h new file mode 100644 index 000000000000..0d15823481d1 --- /dev/null +++ b/clang/test/Index/preamble-reparse-import.m-1.h @@ -0,0 +1,5 @@ +#ifdef PARSED2 +#error parsed twice +#endif + +#define PARSED2 1 diff --git a/clang/test/Index/preamble-reparse-import.m-2.h b/clang/test/Index/preamble-reparse-import.m-2.h new file mode 100644 index 000000000000..8acc5c38c33d --- /dev/null +++ b/clang/test/Index/preamble-reparse-import.m-2.h @@ -0,0 +1,5 @@ +#ifdef PARSED +#error parsed twice +#endif + +#define PARSED 1 diff --git a/clang/test/Index/preamble-reparse-import.m-3.h b/clang/test/Index/preamble-reparse-import.m-3.h new file mode 100644 index 000000000000..5369c1bec50d --- /dev/null +++ b/clang/test/Index/preamble-reparse-import.m-3.h @@ -0,0 +1 @@ +#import "preamble-reparse-import.m-2.h"