<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 23 June 2017 at 13:34, Benjamin Kramer 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Since this change went in I'm seeing spurious errors whenever editing<br>
a header file, filed <a href="https://bugs.llvm.org/show_bug.cgi?id=33574" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_<wbr>bug.cgi?id=33574</a> for<br>
that.</blockquote><div><br></div><div>Does fixing the reversed condition I pointed out fix that?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">
On Tue, May 30, 2017 at 1:54 PM, Erik Verbruggen via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
> 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>
> +    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;<br>
> +  return true;<br>
> +}<br>
> +<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>
______________________________<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>
</div></div></blockquote></div><br></div></div>