diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Lex/PPDirectives.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 11 |
4 files changed, 52 insertions, 13 deletions
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index f9a97505bf4..ca3e70fd106 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -350,7 +350,7 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) { /// If ElseOk is true, then \#else directives are ok, if not, then we have /// already seen one so a \#else directive is a duplicate. When this returns, /// the caller can lex the first valid token. -void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, +void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc, bool FoundNonSkipPortion, bool FoundElse, @@ -358,8 +358,11 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, ++NumSkipped; assert(!CurTokenLexer && CurPPLexer && "Lexing a macro, not a file?"); - CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false, - FoundNonSkipPortion, FoundElse); + if (PreambleConditionalStack.reachedEOFWhileSkipping()) + PreambleConditionalStack.clearSkipInfo(); + else + CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/ false, + FoundNonSkipPortion, FoundElse); if (CurPTHLexer) { PTHSkipExcludedConditionalBlock(); @@ -385,6 +388,9 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, // We don't emit errors for unterminated conditionals here, // Lexer::LexEndOfFile can do that propertly. // Just return and let the caller lex after this #include. + if (PreambleConditionalStack.isRecording()) + PreambleConditionalStack.SkipInfo.emplace( + HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc); break; } @@ -554,7 +560,7 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, if (Callbacks) Callbacks->SourceRangeSkipped( - SourceRange(HashToken.getLocation(), CurPPLexer->getSourceLocation()), + SourceRange(HashTokenLoc, CurPPLexer->getSourceLocation()), Tok.getLocation()); } @@ -2676,7 +2682,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, if (MacroNameTok.is(tok::eod)) { // Skip code until we get to #endif. This helps with recovery by not // emitting an error when the #endif is reached. - SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), + DirectiveTok.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); return; } @@ -2725,7 +2732,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, /*foundelse*/false); } else { // No, skip the contents of this block. - SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), + DirectiveTok.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); } @@ -2772,7 +2780,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken, /*foundnonskip*/true, /*foundelse*/false); } else { // No, skip the contents of this block. - SkipExcludedConditionalBlock(HashToken, IfToken.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), IfToken.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); } @@ -2837,7 +2845,8 @@ void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) { } // Finally, skip the rest of the contents of this block. - SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true, + SkipExcludedConditionalBlock(HashToken.getLocation(), CI.IfLoc, + /*Foundnonskip*/ true, /*FoundElse*/ true, Result.getLocation()); } @@ -2881,7 +2890,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken, } // Finally, skip the rest of the contents of this block. - SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true, - /*FoundElse*/ CI.FoundElse, - ElifToken.getLocation()); + SkipExcludedConditionalBlock( + HashToken.getLocation(), CI.IfLoc, /*Foundnonskip*/ true, + /*FoundElse*/ CI.FoundElse, ElifToken.getLocation()); } diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 65df6a57f1d..d80899de8f8 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -550,6 +550,13 @@ void Preprocessor::replayPreambleConditionalStack() { "CurPPLexer is null when calling replayPreambleConditionalStack."); CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); PreambleConditionalStack.doneReplaying(); + if (PreambleConditionalStack.reachedEOFWhileSkipping()) + SkipExcludedConditionalBlock( + PreambleConditionalStack.SkipInfo->HashTokenLoc, + PreambleConditionalStack.SkipInfo->IfTokenLoc, + PreambleConditionalStack.SkipInfo->FoundNonSkipPortion, + PreambleConditionalStack.SkipInfo->FoundElse, + PreambleConditionalStack.SkipInfo->ElseLoc); } } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5a3423a3eca..dacdac66586 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2995,8 +2995,20 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case PP_CONDITIONAL_STACK: if (!Record.empty()) { + unsigned Idx = 0, End = Record.size() - 1; + bool ReachedEOFWhileSkipping = Record[Idx++]; + llvm::Optional<Preprocessor::PreambleSkipInfo> SkipInfo; + if (ReachedEOFWhileSkipping) { + SourceLocation HashToken = ReadSourceLocation(F, Record, Idx); + SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx); + bool FoundNonSkipPortion = Record[Idx++]; + bool FoundElse = Record[Idx++]; + SourceLocation ElseLoc = ReadSourceLocation(F, Record, Idx); + SkipInfo.emplace(HashToken, IfTokenLoc, FoundNonSkipPortion, + FoundElse, ElseLoc); + } SmallVector<PPConditionalInfo, 4> ConditionalStack; - for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) { + while (Idx < End) { auto Loc = ReadSourceLocation(F, Record, Idx); bool WasSkipping = Record[Idx++]; bool FoundNonSkip = Record[Idx++]; @@ -3004,7 +3016,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { ConditionalStack.push_back( {Loc, WasSkipping, FoundNonSkip, FoundElse}); } - PP.setReplayablePreambleConditionalStack(ConditionalStack); + PP.setReplayablePreambleConditionalStack(ConditionalStack, SkipInfo); } break; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index dec8d8f7d77..3834314109b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2407,6 +2407,17 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) { assert(!IsModule); + auto SkipInfo = PP.getPreambleSkipInfo(); + if (SkipInfo.hasValue()) { + Record.push_back(true); + AddSourceLocation(SkipInfo->HashTokenLoc, Record); + AddSourceLocation(SkipInfo->IfTokenLoc, Record); + Record.push_back(SkipInfo->FoundNonSkipPortion); + Record.push_back(SkipInfo->FoundElse); + AddSourceLocation(SkipInfo->ElseLoc, Record); + } else { + Record.push_back(false); + } for (const auto &Cond : PP.getPreambleConditionalStack()) { AddSourceLocation(Cond.IfLoc, Record); Record.push_back(Cond.WasSkipping); |