]> granicus.if.org Git - clang/commitdiff
[PCH] When chaining a PCH and serializing HeaderSearch, make sure the HeaderFileInfos
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 13 Nov 2011 22:08:39 +0000 (22:08 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 13 Nov 2011 22:08:39 +0000 (22:08 +0000)
from the primary PCH is deserialized, otherwise we lose info that headers were
already #imported/#included.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144510 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/HeaderSearch.h
include/clang/Serialization/ASTWriter.h
lib/Serialization/ASTWriter.cpp
test/Index/preamble-reparse-import.m [new file with mode: 0644]
test/Index/preamble-reparse-import.m-1.h [new file with mode: 0644]
test/Index/preamble-reparse-import.m-2.h [new file with mode: 0644]
test/Index/preamble-reparse-import.m-3.h [new file with mode: 0644]

index 092d5470911d670edefdc27b736a6713e005c6f0..05e66b39c932b8ac9635e31295f99ba04308e18e 100644 (file)
@@ -367,14 +367,17 @@ public:
   /// FIXME: This will need to be generalized for submodules.
   StringRef findModuleForHeader(const FileEntry *File);
   
-  typedef std::vector<HeaderFileInfo>::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<HeaderSearch*>(this)->getFileInfo(FE);
+  }
+
   // Used by external tools
   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
   search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
index 2fc75c22724d760a5ce2289bd3a1a58f9fd421b8..cdba3e9883a3abcd2c4db2031f0fcf45fa8c2e46 100644 (file)
@@ -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();
index 0a7fe4c4924afbd3287d821c231365cabcb6e237..667b3a58ddc43213091f2cea83687cde7297103b 100644 (file)
@@ -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<char, 128> FrameworkStringData;
     llvm::StringMap<unsigned> 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<const FileEntry *, 16> 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/test/Index/preamble-reparse-import.m b/test/Index/preamble-reparse-import.m
new file mode 100644 (file)
index 0000000..9bdb89a
--- /dev/null
@@ -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/test/Index/preamble-reparse-import.m-1.h b/test/Index/preamble-reparse-import.m-1.h
new file mode 100644 (file)
index 0000000..0d15823
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef PARSED2
+#error parsed twice
+#endif
+
+#define PARSED2 1
diff --git a/test/Index/preamble-reparse-import.m-2.h b/test/Index/preamble-reparse-import.m-2.h
new file mode 100644 (file)
index 0000000..8acc5c3
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef PARSED
+#error parsed twice
+#endif
+
+#define PARSED 1
diff --git a/test/Index/preamble-reparse-import.m-3.h b/test/Index/preamble-reparse-import.m-3.h
new file mode 100644 (file)
index 0000000..5369c1b
--- /dev/null
@@ -0,0 +1 @@
+#import "preamble-reparse-import.m-2.h"