]> granicus.if.org Git - clang/commitdiff
Redo how PCH handles its implicit include. Instead of treating this specially in
authorDaniel Dunbar <daniel@zuster.org>
Wed, 11 Nov 2009 05:29:04 +0000 (05:29 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 11 Nov 2009 05:29:04 +0000 (05:29 +0000)
the front-end (as far as the preprocessor goes), follow the usual logic of
inserting the (original include path) name into the predefines buffer. This
pushes the responsibility for handling this to PCH instead of the front-end.  In
PCH this requires being a little more clever when we diff the predefines
buffers.

Neither of these solutions are particularly great, I think what we eventually
should do is something like gcc where we insert a special marker to indicate the
PCH file, but then run the preprocessor as usual. This would be clearer and
would allow us to drop the overly clever predefines handling.

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

include/clang/Frontend/PCHReader.h
lib/Frontend/ASTUnit.cpp
lib/Frontend/PCHReader.cpp
tools/clang-cc/clang-cc.cpp

index 0c56109f00c94c7863f0553e70394e173915e4ac..85861fab4a22d861b1ccd145148c538bfc153174 100644 (file)
@@ -88,17 +88,18 @@ public:
   /// \param PCHPredef The start of the predefines buffer in the PCH
   /// file.
   ///
-  /// \param PCHPredefLen The length of the predefines buffer in the PCH
-  /// file.
-  ///
   /// \param PCHBufferID The FileID for the PCH predefines buffer.
   ///
+  /// \param OriginalFileName The original file name for the PCH, which will
+  /// appear as an entry in the predefines buffer.
+  ///
   /// \param SuggestedPredefines If necessary, additional definitions are added
   /// here.
   ///
   /// \returns true to indicate the predefines are invalid or false otherwise.
   virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
                                     FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
                                     std::string &SuggestedPredefines) {
     return false;
   }
@@ -126,6 +127,7 @@ public:
   virtual bool ReadTargetTriple(llvm::StringRef Triple);
   virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
                                     FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
                                     std::string &SuggestedPredefines);
   virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI);
   virtual void ReadCounter(unsigned Value);
@@ -311,10 +313,13 @@ private:
   /// the PCH file.
   llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
 
-  /// \brief The original file name that was used to build the PCH
-  /// file.
+  /// \brief The original file name that was used to build the PCH file, which
+  /// may have been modified for relocatable-pch support.
   std::string OriginalFileName;
 
+  /// \brief The actual original file name that was used to build the PCH file.
+  std::string ActualOriginalFileName;
+
   /// \brief Whether this precompiled header is a relocatable PCH file.
   bool RelocatablePCH;
 
index b5e65589e32334d6fa5d4e15c7c06c3de60a9d75..82786aaa7fd1b8108b49431ef6c2378517ec9391 100644 (file)
@@ -68,6 +68,7 @@ public:
 
   virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
                                     FileID PCHBufferID,
+                                    llvm::StringRef OriginalFileName,
                                     std::string &SuggestedPredefines) {
     Predefines = PCHPredef;
     return false;
index 42aa43b81f7197391c00b03531fff4a1a2564dd5..936382482c9a629802c3259355830d90c83bb0cf 100644 (file)
@@ -156,17 +156,34 @@ static std::vector<llvm::StringRef> splitLines(llvm::StringRef Str,
 
 bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,
                                         FileID PCHBufferID,
+                                        llvm::StringRef OriginalFileName,
                                         std::string &SuggestedPredefines) {
-  // If the two predefines buffers compare equal, we're done!
-  if (PP.getPredefines() == PCHPredef)
+  // We are in the context of an implicit include, so the predefines buffer
+  // will have a #include entry for the PCH file itself. Find it and skip over
+  // it in the checking below.
+  llvm::SmallString<256> PCHInclude;
+  PCHInclude += "#include \"";
+  PCHInclude += OriginalFileName;
+  PCHInclude += "\"\n";
+  std::pair<llvm::StringRef,llvm::StringRef> Split =
+    llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
+  llvm::StringRef Left =  Split.first, Right = Split.second;
+  assert(Left != PP.getPredefines() && "Missing PCH include entry!");
+
+  // If the predefines is equal to the joined left and right halves, we're done!
+  if (Left.size() + Right.size() == PCHPredef.size() &&
+      PCHPredef.startswith(Left) && PCHPredef.endswith(Right))
     return false;
 
   SourceManager &SourceMgr = PP.getSourceManager();
 
   // The predefines buffers are different. Determine what the differences are,
   // and whether they require us to reject the PCH file.
-  std::vector<llvm::StringRef> CmdLineLines = splitLines(PP.getPredefines());
   std::vector<llvm::StringRef> PCHLines = splitLines(PCHPredef);
+  std::vector<llvm::StringRef> CmdLineLines = splitLines(Left);
+  std::vector<llvm::StringRef> CmdLineLinesRight = splitLines(Right);
+  CmdLineLines.insert(CmdLineLines.end(),
+                      CmdLineLinesRight.begin(), CmdLineLinesRight.end());
 
   // Sort both sets of predefined buffer lines, since we allow some extra
   // definitions and they may appear at any point in the output.
@@ -624,6 +641,7 @@ bool PCHReader::CheckPredefinesBuffer(llvm::StringRef PCHPredef,
                                       FileID PCHBufferID) {
   if (Listener)
     return Listener->ReadPredefinesBuffer(PCHPredef, PCHBufferID,
+                                          ActualOriginalFileName,
                                           SuggestedPredefines);
   return false;
 }
@@ -1333,7 +1351,8 @@ PCHReader::ReadPCHBlock() {
       break;
 
     case pch::ORIGINAL_FILE_NAME:
-      OriginalFileName.assign(BlobStart, BlobLen);
+      ActualOriginalFileName.assign(BlobStart, BlobLen);
+      OriginalFileName = ActualOriginalFileName;
       MaybeAddSystemRootToFilename(OriginalFileName);
       break;
 
index 85305f86fcfc20e40265b50feae951b10dd4c7a5..a13d1a4da44e9d03a7fbaf2b5a57d4281d8352a3 100644 (file)
@@ -1110,7 +1110,7 @@ static void InitializePreprocessorOptions(PreprocessorOptions &InitOpts) {
     InitOpts.addMacroInclude(ImplicitMacroIncludes[i]);
 
   if (!ImplicitIncludePTH.empty() || !ImplicitIncludes.empty() ||
-      (!ImplicitIncludePCH.empty() && ProgAction == PrintPreprocessedInput)) {
+      !ImplicitIncludePCH.empty()) {
     // We want to add these paths to the predefines buffer in order, make a
     // temporary vector to sort by their occurrence.
     llvm::SmallVector<std::pair<unsigned, std::string*>, 8> OrderedPaths;
@@ -1118,7 +1118,7 @@ static void InitializePreprocessorOptions(PreprocessorOptions &InitOpts) {
     if (!ImplicitIncludePTH.empty())
       OrderedPaths.push_back(std::make_pair(ImplicitIncludePTH.getPosition(),
                                             &ImplicitIncludePTH));
-    if (!ImplicitIncludePCH.empty() && ProgAction == PrintPreprocessedInput)
+    if (!ImplicitIncludePCH.empty())
       OrderedPaths.push_back(std::make_pair(ImplicitIncludePCH.getPosition(),
                                             &ImplicitIncludePCH));
     for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i)
@@ -1126,7 +1126,6 @@ static void InitializePreprocessorOptions(PreprocessorOptions &InitOpts) {
                                             &ImplicitIncludes[i]));
     llvm::array_pod_sort(OrderedPaths.begin(), OrderedPaths.end());
 
-
     // Now that they are ordered by position, add to the predefines buffer.
     for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i) {
       std::string *Ptr = OrderedPaths[i].second;
@@ -1142,10 +1141,10 @@ static void InitializePreprocessorOptions(PreprocessorOptions &InitOpts) {
         // file that was used to build the precompiled header.
         assert(Ptr == &ImplicitIncludePCH);
         std::string OriginalFile = PCHReader::getOriginalSourceFile(*Ptr);
-        if (!OriginalFile.empty()) {
-          InitOpts.addInclude(OriginalFile);
-          InitOpts.setImplicitPCHInclude("");
-        }
+        // FIXME: Don't fail like this.
+        if (OriginalFile.empty())
+          exit(1);
+        InitOpts.addInclude(OriginalFile);
       }
     }
   }