diff options
author | Mike Rice <michael.p.rice@intel.com> | 2018-09-11 17:10:44 +0000 |
---|---|---|
committer | Mike Rice <michael.p.rice@intel.com> | 2018-09-11 17:10:44 +0000 |
commit | 58df1affedc0d68eda16b87984a31dea217ff930 (patch) | |
tree | 055ccfe2a9023cdc9d883947849814a3d50e3a2d /clang/lib/Lex/Preprocessor.cpp | |
parent | 12fd6bd4ad8f472304dc51120c11125f5627160b (diff) | |
download | bcm5719-llvm-58df1affedc0d68eda16b87984a31dea217ff930.tar.gz bcm5719-llvm-58df1affedc0d68eda16b87984a31dea217ff930.zip |
[clang-cl, PCH] Support for /Yc and /Yu without filename and #pragma hdrstop
With clang-cl, when the user specifies /Yc or /Yu without a filename
the compiler uses a #pragma hdrstop in the main source file to
determine the end of the PCH. If a header is specified with /Yc or
/Yu #pragma hdrstop has no effect.
The optional #pragma hdrstop filename argument is not yet supported.
Differential Revision: https://reviews.llvm.org/D51391
llvm-svn: 341963
Diffstat (limited to 'clang/lib/Lex/Preprocessor.cpp')
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index c7da41172f8..dcff51ad61b 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -149,6 +149,10 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, Ident_AbnormalTermination = nullptr; } + // If using a PCH where a #pragma hdrstop is expected, start skipping tokens. + if (usingPCHWithPragmaHdrStop()) + SkippingUntilPragmaHdrStop = true; + // If using a PCH with a through header, start skipping tokens. if (!this->PPOpts->PCHThroughHeader.empty() && !this->PPOpts->ImplicitPCHInclude.empty()) @@ -576,8 +580,9 @@ void Preprocessor::EnterMainSourceFile() { } // Skip tokens from the Predefines and if needed the main file. - if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) - SkipTokensUntilPCHThroughHeader(); + if ((usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) || + (usingPCHWithPragmaHdrStop() && SkippingUntilPragmaHdrStop)) + SkipTokensWhileUsingPCH(); } void Preprocessor::setPCHThroughHeaderFileID(FileID FID) { @@ -602,12 +607,23 @@ bool Preprocessor::usingPCHWithThroughHeader() { PCHThroughHeaderFileID.isValid(); } -/// Skip tokens until after the #include of the through header. -/// Tokens in the predefines file and the main file may be skipped. If the end -/// of the predefines file is reached, skipping continues into the main file. -/// If the end of the main file is reached, it's a fatal error. -void Preprocessor::SkipTokensUntilPCHThroughHeader() { +bool Preprocessor::creatingPCHWithPragmaHdrStop() { + return TUKind == TU_Prefix && PPOpts->PCHWithHdrStop; +} + +bool Preprocessor::usingPCHWithPragmaHdrStop() { + return TUKind != TU_Prefix && PPOpts->PCHWithHdrStop; +} + +/// Skip tokens until after the #include of the through header or +/// until after a #pragma hdrstop is seen. Tokens in the predefines file +/// and the main file may be skipped. If the end of the predefines file +/// is reached, skipping continues into the main file. If the end of the +/// main file is reached, it's a fatal error. +void Preprocessor::SkipTokensWhileUsingPCH() { bool ReachedMainFileEOF = false; + bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader; + bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop; Token Tok; while (true) { bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID()); @@ -616,12 +632,18 @@ void Preprocessor::SkipTokensUntilPCHThroughHeader() { ReachedMainFileEOF = true; break; } - if (!SkippingUntilPCHThroughHeader) + if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader) + break; + if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop) break; } - if (ReachedMainFileEOF) - Diag(SourceLocation(), diag::err_pp_through_header_not_seen) - << PPOpts->PCHThroughHeader << 1; + if (ReachedMainFileEOF) { + if (UsingPCHThroughHeader) + Diag(SourceLocation(), diag::err_pp_through_header_not_seen) + << PPOpts->PCHThroughHeader << 1; + else if (!PPOpts->PCHWithHdrStopCreate) + Diag(SourceLocation(), diag::err_pp_pragma_hdrstop_not_seen); + } } void Preprocessor::replayPreambleConditionalStack() { |