<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 30 May 2017 at 04:54, Erik Verbruggen via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: erikjv<br>
Date: Tue May 30 06:54:55 2017<br>
New Revision: 304207<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=304207&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=304207&view=rev</a><br>
Log:<br>
Allow for unfinished #if blocks in preambles<br>
<br>
Previously, a preamble only included #if blocks (and friends like<br>
ifdef) if there was a corresponding #endif before any declaration or<br>
definition. The problem is that any header file that uses include guards<br>
will not have a preamble generated, which can make code-completion very<br>
slow.<br>
<br>
To prevent errors about unbalanced preprocessor conditionals in the<br>
preamble, and unbalanced preprocessor conditionals after a preamble<br>
containing unfinished conditionals, the conditional stack is stored<br>
in the pch file.<br>
<br>
This fixes PR26045.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D15994" rel="noreferrer" target="_blank">http://reviews.llvm.org/D15994</a><br>
<br>
<br>
Added:<br>
    cfe/trunk/test/Lexer/<wbr>preamble2.c<br>
Modified:<br>
    cfe/trunk/include/clang/Lex/<wbr>Preprocessor.h<br>
    cfe/trunk/include/clang/Lex/<wbr>PreprocessorLexer.h<br>
    cfe/trunk/include/clang/Lex/<wbr>PreprocessorOptions.h<br>
    cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp<br>
    cfe/trunk/lib/Lex/Lexer.cpp<br>
    cfe/trunk/lib/Lex/<wbr>PPLexerChange.cpp<br>
    cfe/trunk/lib/Lex/<wbr>Preprocessor.cpp<br>
    cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
    cfe/trunk/test/Lexer/preamble.<wbr>c<br>
<br>
Modified: cfe/trunk/include/clang/Lex/<wbr>Preprocessor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Lex/Preprocessor.h?rev=<wbr>304207&r1=304206&r2=304207&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Lex/<wbr>Preprocessor.h (original)<br>
+++ cfe/trunk/include/clang/Lex/<wbr>Preprocessor.h Tue May 30 06:54:55 2017<br>
@@ -283,6 +283,44 @@ class Preprocessor {<br>
   /// This is used when loading a precompiled preamble.<br>
   std::pair<int, bool> SkipMainFilePreamble;<br>
<br>
+  class PreambleConditionalStackStore {<br>
+    enum State {<br>
+      Off = 0,<br>
+      Recording = 1,<br>
+      Replaying = 2,<br>
+    };<br>
+<br>
+  public:<br>
+    PreambleConditionalStackStore(<wbr>) : ConditionalStackState(Off) {}<br>
+<br>
+    void startRecording() { ConditionalStackState = Recording; }<br>
+    void startReplaying() { ConditionalStackState = Replaying; }<br>
+    bool isRecording() const { return ConditionalStackState == Recording; }<br>
+    bool isReplaying() const { return ConditionalStackState == Replaying; }<br>
+<br>
+    ArrayRef<PPConditionalInfo> getStack() const {<br>
+      return ConditionalStack;<br>
+    }<br>
+<br>
+    void doneReplaying() {<br>
+      ConditionalStack.clear();<br>
+      ConditionalStackState = Off;<br>
+    }<br>
+<br>
+    void setStack(ArrayRef<<wbr>PPConditionalInfo> s) {<br>
+      if (!isRecording() && !isReplaying())<br>
+        return;<br>
+      ConditionalStack.clear();<br>
+      ConditionalStack.append(s.<wbr>begin(), s.end());<br>
+    }<br>
+<br>
+    bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }<br>
+<br>
+  private:<br>
+    SmallVector<PPConditionalInfo, 4> ConditionalStack;<br>
+    State ConditionalStackState;<br>
+  } PreambleConditionalStack;<br>
+<br>
   /// \brief The current top of the stack that we're lexing from if<br>
   /// not expanding a macro and we are lexing directly from source code.<br>
   ///<br>
@@ -1695,6 +1733,11 @@ public:<br>
   /// \brief Return true if we're in the top-level file, not in a \#include.<br>
   bool isInPrimaryFile() const;<br>
<br>
+  /// \brief Return true if we're in the main file (specifically, if we are 0<br>
+  /// (zero) levels deep \#include. This is used by the lexer to determine if<br>
+  /// it needs to generate errors about unterminated \#if directives.<br>
+  bool isInMainFile() const;<br>
+<br>
   /// \brief Handle cases where the \#include name is expanded<br>
   /// from a macro as multiple tokens, which need to be glued together.<br>
   ///<br>
@@ -1932,6 +1975,27 @@ public:<br>
                                                           Module *M,<br>
                                                           SourceLocation MLoc);<br>
<br>
+  bool isRecordingPreamble() const {<br>
+    return PreambleConditionalStack.<wbr>isRecording();<br>
+  }<br>
+<br>
+  bool hasRecordedPreamble() const {<br>
+    return PreambleConditionalStack.<wbr>hasRecordedPreamble();<br>
+  }<br>
+<br>
+  ArrayRef<PPConditionalInfo> getPreambleConditionalStack() const {<br>
+      return PreambleConditionalStack.<wbr>getStack();<br>
+  }<br>
+<br>
+  void setRecordedPreambleConditional<wbr>Stack(ArrayRef<<wbr>PPConditionalInfo> s) {<br>
+    PreambleConditionalStack.<wbr>setStack(s);<br>
+  }<br>
+<br>
+  void setReplayablePreambleCondition<wbr>alStack(ArrayRef<<wbr>PPConditionalInfo> s) {<br>
+    PreambleConditionalStack.<wbr>startReplaying();<br>
+    PreambleConditionalStack.<wbr>setStack(s);<br>
+  }<br>
+<br>
 private:<br>
   // Macro handling.<br>
   void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef<wbr>);<br>
<br>
Modified: cfe/trunk/include/clang/Lex/<wbr>PreprocessorLexer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessorLexer.h?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Lex/PreprocessorLexer.h?<wbr>rev=304207&r1=304206&r2=<wbr>304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Lex/<wbr>PreprocessorLexer.h (original)<br>
+++ cfe/trunk/include/clang/Lex/<wbr>PreprocessorLexer.h Tue May 30 06:54:55 2017<br>
@@ -17,6 +17,7 @@<br>
<br>
 #include "clang/Lex/MultipleIncludeOpt.<wbr>h"<br>
 #include "clang/Lex/Token.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
<br>
 namespace clang {<br>
@@ -176,6 +177,11 @@ public:<br>
   conditional_iterator conditional_end() const {<br>
     return ConditionalStack.end();<br>
   }<br>
+<br>
+  void setConditionalLevels(ArrayRef<<wbr>PPConditionalInfo> CL) {<br>
+    ConditionalStack.clear();<br>
+    ConditionalStack.append(CL.<wbr>begin(), CL.end());<br>
+  }<br>
 };<br>
<br>
 }  // end namespace clang<br>
<br>
Modified: cfe/trunk/include/clang/Lex/<wbr>PreprocessorOptions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessorOptions.h?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Lex/PreprocessorOptions.<wbr>h?rev=304207&r1=304206&r2=<wbr>304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Lex/<wbr>PreprocessorOptions.h (original)<br>
+++ cfe/trunk/include/clang/Lex/<wbr>PreprocessorOptions.h Tue May 30 06:54:55 2017<br>
@@ -80,7 +80,14 @@ public:<br>
   /// The boolean indicates whether the preamble ends at the start of a new<br>
   /// line.<br>
   std::pair<unsigned, bool> PrecompiledPreambleBytes;<br>
-<br>
+<br>
+  /// \brief True indicates that a preamble is being generated.<br>
+  ///<br>
+  /// When the lexer is done, one of the things that need to be preserved is the<br>
+  /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when<br>
+  /// processing the rest of the file.<br>
+  bool GeneratePreamble;<br>
+<br>
   /// The implicit PTH input included at the start of the translation unit, or<br>
   /// empty.<br>
   std::string ImplicitPTHInclude;<br>
@@ -144,6 +151,7 @@ public:<br>
                           AllowPCHWithCompilerErrors(<wbr>false),<br>
                           DumpDeserializedPCHDecls(<wbr>false),<br>
                           PrecompiledPreambleBytes(0, true),<br>
+                          GeneratePreamble(false),<br>
                           RemappedFilesKeepOriginalName(<wbr>true),<br>
                           RetainRemappedFileBuffers(<wbr>false),<br>
                           ObjCXXARCStandardLibrary(<wbr>ARCXX_nolib) { }<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Serialization/<wbr>ASTBitCodes.h?rev=304207&r1=<wbr>304206&r2=304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h Tue May 30 06:54:55 2017<br>
@@ -607,6 +607,9 @@ namespace clang {<br>
<br>
       /// \brief Record code for \#pragma pack options.<br>
       PACK_PRAGMA_OPTIONS = 61,<br>
+<br>
+      /// \brief The stack of open #ifs/#ifdefs recorded in a preamble.<br>
+      PP_CONDITIONAL_STACK = 62,<br>
     };<br>
<br>
     /// \brief Record types used within a source manager block.<br>
<br>
Modified: cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Frontend/ASTUnit.cpp?rev=<wbr>304207&r1=304206&r2=304207&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/<wbr>ASTUnit.cpp Tue May 30 06:54:55 2017<br>
@@ -1999,6 +1999,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(<br>
   PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();<br>
   PPOpts.<wbr>RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;<br>
   PPOpts.<wbr>AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;<br>
+  PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0;<br>
<br>
   // Override the resources path.<br>
   CI->getHeaderSearchOpts().<wbr>ResourceDir = ResourceFilesPath;<br>
<br>
Modified: cfe/trunk/lib/Lex/Lexer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Lex/<wbr>Lexer.cpp?rev=304207&r1=<wbr>304206&r2=304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Lex/Lexer.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Lexer.cpp Tue May 30 06:54:55 2017<br>
@@ -550,8 +550,6 @@ namespace {<br>
<br>
   enum PreambleDirectiveKind {<br>
     PDK_Skipped,<br>
-    PDK_StartIf,<br>
-    PDK_EndIf,<br>
     PDK_Unknown<br>
   };<br>
<br>
@@ -574,8 +572,6 @@ std::pair<unsigned, bool> Lexer::Compute<br>
<br>
   bool InPreprocessorDirective = false;<br>
   Token TheTok;<br>
-  Token IfStartTok;<br>
-  unsigned IfCount = 0;<br>
   SourceLocation ActiveCommentLoc;<br>
<br>
   unsigned MaxLineOffset = 0;<br>
@@ -658,33 +654,18 @@ std::pair<unsigned, bool> Lexer::Compute<br>
               .Case("sccs", PDK_Skipped)<br>
               .Case("assert", PDK_Skipped)<br>
               .Case("unassert", PDK_Skipped)<br>
-              .Case("if", PDK_StartIf)<br>
-              .Case("ifdef", PDK_StartIf)<br>
-              .Case("ifndef", PDK_StartIf)<br>
+              .Case("if", PDK_Skipped)<br>
+              .Case("ifdef", PDK_Skipped)<br>
+              .Case("ifndef", PDK_Skipped)<br>
               .Case("elif", PDK_Skipped)<br>
               .Case("else", PDK_Skipped)<br>
-              .Case("endif", PDK_EndIf)<br>
+              .Case("endif", PDK_Skipped)<br>
               .Default(PDK_Unknown);<br>
<br>
         switch (PDK) {<br>
         case PDK_Skipped:<br>
           continue;<br>
<br>
-        case PDK_StartIf:<br>
-          if (IfCount == 0)<br>
-            IfStartTok = HashTok;<br>
-<br>
-          ++IfCount;<br>
-          continue;<br>
-<br>
-        case PDK_EndIf:<br>
-          // Mismatched #endif. The preamble ends here.<br>
-          if (IfCount == 0)<br>
-            break;<br>
-<br>
-          --IfCount;<br>
-          continue;<br>
-<br>
         case PDK_Unknown:<br>
           // We don't know what this directive is; stop at the '#'.<br>
           break;<br>
@@ -705,16 +686,13 @@ std::pair<unsigned, bool> Lexer::Compute<br>
   } while (true);<br>
<br>
   SourceLocation End;<br>
-  if (IfCount)<br>
-    End = IfStartTok.getLocation();<br>
-  else if (ActiveCommentLoc.isValid())<br>
+  if (ActiveCommentLoc.isValid())<br>
     End = ActiveCommentLoc; // don't truncate a decl comment.<br>
   else<br>
     End = TheTok.getLocation();<br>
<br>
   return std::make_pair(End.<wbr>getRawEncoding() - StartLoc.getRawEncoding(),<br>
-                        IfCount? IfStartTok.isAtStartOfLine()<br>
-                               : TheTok.isAtStartOfLine());<br>
+                        TheTok.isAtStartOfLine());<br>
 }<br>
<br>
 /// AdvanceToTokenCharacter - Given a location that specifies the start of a<br>
@@ -2570,6 +2548,11 @@ bool Lexer::LexEndOfFile(Token &Result,<br>
     return true;<br>
   }<br>
<br>
+  if (PP->isRecordingPreamble() && !PP->isInMainFile()) {<br></blockquote><div><br></div><div>You've picked up a bogus ! on the second condition between the review and the commit. We want to store and clear the preamble when we get to the end of the main file, not when we get to the end of every file other than the main file.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    PP-><wbr>setRecordedPreambleConditional<wbr>Stack(ConditionalStack);<br>
+    ConditionalStack.clear();<br>
+  }<br>
+<br>
   // Issue diagnostics for unterminated #if and missing newline.<br>
<br>
   // If we are in a #if directive, emit an error.<br>
<br>
Modified: cfe/trunk/lib/Lex/<wbr>PPLexerChange.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Lex/<wbr>PPLexerChange.cpp?rev=304207&<wbr>r1=304206&r2=304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Lex/<wbr>PPLexerChange.cpp (original)<br>
+++ cfe/trunk/lib/Lex/<wbr>PPLexerChange.cpp Tue May 30 06:54:55 2017<br>
@@ -46,6 +46,12 @@ bool Preprocessor::isInPrimaryFile(<wbr>) con<br>
   });<br>
 }<br>
<br>
+bool Preprocessor::isInMainFile() const {<br>
+  if (IsFileLexer())<br>
+    return IncludeMacroStack.size() == 0; </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  return true;<br>
+}<br></blockquote><div><br></div><div>Looks like Preprocessor::isInPrimaryFile already exists and does the same thing (but handles some corner cases better).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
 /// getCurrentLexer - Return the current file lexer being lexed from.  Note<br>
 /// that this ignores any potentially active macro expansions and _Pragma<br>
 /// expansions going on at the time.<br>
<br>
Modified: cfe/trunk/lib/Lex/<wbr>Preprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Lex/<wbr>Preprocessor.cpp?rev=304207&<wbr>r1=304206&r2=304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Lex/<wbr>Preprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Lex/<wbr>Preprocessor.cpp Tue May 30 06:54:55 2017<br>
@@ -150,6 +150,9 @@ Preprocessor::Preprocessor(<wbr>std::shared_p<br>
     Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr;<br>
     Ident_AbnormalTermination = nullptr;<br>
   }<br>
+<br>
+  if (this->PPOpts-><wbr>GeneratePreamble)<br>
+    PreambleConditionalStack.<wbr>startRecording();<br>
 }<br>
<br>
 Preprocessor::~Preprocessor() {<br>
@@ -532,6 +535,12 @@ void Preprocessor::<wbr>EnterMainSourceFile()<br>
<br>
   // Start parsing the predefines.<br>
   EnterSourceFile(FID, nullptr, SourceLocation());<br>
+<br>
+  // Restore the conditional stack from the preamble, if there is one.<br>
+  if (PreambleConditionalStack.<wbr>isReplaying()) {<br>
+    CurPPLexer-><wbr>setConditionalLevels(<wbr>PreambleConditionalStack.<wbr>getStack());<br>
+    PreambleConditionalStack.<wbr>doneReplaying();<br>
+  }<br>
 }<br>
<br>
 void Preprocessor::EndSourceFile() {<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTReader.cpp?<wbr>rev=304207&r1=304206&r2=<wbr>304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTReader.cpp Tue May 30 06:54:55 2017<br>
@@ -2925,6 +2925,21 @@ ASTReader::ReadASTBlock(<wbr>ModuleFile &F, u<br>
       }<br>
       break;<br>
<br>
+    case PP_CONDITIONAL_STACK:<br>
+      if (!Record.empty()) {<br>
+        SmallVector<PPConditionalInfo, 4> ConditionalStack;<br>
+        for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {<br>
+          auto Loc = ReadSourceLocation(F, Record, Idx);<br>
+          bool WasSkipping = Record[Idx++];<br>
+          bool FoundNonSkip = Record[Idx++];<br>
+          bool FoundElse = Record[Idx++];<br>
+          ConditionalStack.push_back(<br>
+              {Loc, WasSkipping, FoundNonSkip, FoundElse});<br>
+        }<br>
+        PP.<wbr>setReplayablePreambleCondition<wbr>alStack(ConditionalStack);<br>
+      }<br>
+      break;<br>
+<br>
     case PP_COUNTER_VALUE:<br>
       if (!Record.empty() && Listener)<br>
         Listener->ReadCounter(F, Record[0]);<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTWriter.cpp?<wbr>rev=304207&r1=304206&r2=<wbr>304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp Tue May 30 06:54:55 2017<br>
@@ -1093,6 +1093,7 @@ void ASTWriter::<wbr>WriteBlockInfoBlock() {<br>
   RECORD(UNUSED_LOCAL_TYPEDEF_<wbr>NAME_CANDIDATES);<br>
   RECORD(DELETE_EXPRS_TO_<wbr>ANALYZE);<br>
   RECORD(CUDA_PRAGMA_FORCE_HOST_<wbr>DEVICE_DEPTH);<br>
+  RECORD(PP_CONDITIONAL_STACK);<br>
<br>
   // SourceManager Block.<br>
   BLOCK(SOURCE_MANAGER_BLOCK);<br>
@@ -2302,6 +2303,18 @@ void ASTWriter::WritePreprocessor(<wbr>const<br>
     Stream.EmitRecord(PP_COUNTER_<wbr>VALUE, Record);<br>
   }<br>
<br>
+  if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) {<br>
+    assert(!IsModule);<br>
+    for (const auto &Cond : PP.<wbr>getPreambleConditionalStack()) {<br>
+      AddSourceLocation(Cond.IfLoc, Record);<br>
+      Record.push_back(Cond.<wbr>WasSkipping);<br>
+      Record.push_back(Cond.<wbr>FoundNonSkip);<br>
+      Record.push_back(Cond.<wbr>FoundElse);<br>
+    }<br>
+    Stream.EmitRecord(PP_<wbr>CONDITIONAL_STACK, Record);<br>
+    Record.clear();<br>
+  }<br>
+<br>
   // Enter the preprocessor block.<br>
   Stream.EnterSubblock(<wbr>PREPROCESSOR_BLOCK_ID, 3);<br>
<br>
<br>
Modified: cfe/trunk/test/Lexer/preamble.<wbr>c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/preamble.c?rev=304207&r1=304206&r2=304207&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Lexer/<wbr>preamble.c?rev=304207&r1=<wbr>304206&r2=304207&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Lexer/preamble.<wbr>c (original)<br>
+++ cfe/trunk/test/Lexer/preamble.<wbr>c Tue May 30 06:54:55 2017<br>
@@ -9,15 +9,12 @@<br>
 #pragma unknown<br>
 #endif<br>
 #ifdef WIBBLE<br>
-#include "honk"<br>
-#else<br>
-int foo();<br>
+#include "foo"<br>
+int bar;<br>
 #endif<br>
<br>
 // This test checks for detection of the preamble of a file, which<br>
-// includes all of the starting comments and #includes. Note that any<br>
-// changes to the preamble part of this file must be mirrored in<br>
-// Inputs/preamble.txt, since we diff against it.<br>
+// includes all of the starting comments and #includes.<br>
<br>
 // RUN: %clang_cc1 -print-preamble %s > %t<br>
 // RUN: echo END. >> %t<br>
@@ -33,4 +30,6 @@ int foo();<br>
 // CHECK-NEXT: #endif<br>
 // CHECK-NEXT: #pragma unknown<br>
 // CHECK-NEXT: #endif<br>
+// CHECK-NEXT: #ifdef WIBBLE<br>
+// CHECK-NEXT: #include "foo"<br>
 // CHECK-NEXT: END.<br>
<br>
Added: cfe/trunk/test/Lexer/<wbr>preamble2.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/preamble2.c?rev=304207&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Lexer/<wbr>preamble2.c?rev=304207&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Lexer/<wbr>preamble2.c (added)<br>
+++ cfe/trunk/test/Lexer/<wbr>preamble2.c Tue May 30 06:54:55 2017<br>
@@ -0,0 +1,19 @@<br>
+// Preamble detection test: header with an include guard.<br>
+#ifndef HEADER_H<br>
+#define HEADER_H<br>
+#include "foo"<br>
+int bar;<br>
+#endif<br>
+<br>
+// This test checks for detection of the preamble of a file, which<br>
+// includes all of the starting comments and #includes.<br>
+<br>
+// RUN: %clang_cc1 -print-preamble %s > %t<br>
+// RUN: echo END. >> %t<br>
+// RUN: FileCheck < %t %s<br>
+<br>
+// CHECK: // Preamble detection test: header with an include guard.<br>
+// CHECK-NEXT: #ifndef HEADER_H<br>
+// CHECK-NEXT: #define HEADER_H<br>
+// CHECK-NEXT: #include "foo"<br>
+// CHECK-NEXT: END.<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>