[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
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 37c0a23..0a63ed7 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -876,6 +876,37 @@
StringRef(Start, End - Start));
}
+void Preprocessor::HandlePragmaHdrstop(Token &Tok) {
+ Lex(Tok);
+ if (Tok.is(tok::l_paren)) {
+ Diag(Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);
+
+ std::string FileName;
+ if (!LexStringLiteral(Tok, FileName, "pragma hdrstop", false))
+ return;
+
+ if (Tok.isNot(tok::r_paren)) {
+ Diag(Tok, diag::err_expected) << tok::r_paren;
+ return;
+ }
+ Lex(Tok);
+ }
+ if (Tok.isNot(tok::eod))
+ Diag(Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)
+ << "pragma hdrstop";
+
+ if (creatingPCHWithPragmaHdrStop() &&
+ SourceMgr.isInMainFile(Tok.getLocation())) {
+ assert(CurLexer && "no lexer for #pragma hdrstop processing");
+ Token &Result = Tok;
+ Result.startToken();
+ CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
+ CurLexer->cutOffLexing();
+ }
+ if (usingPCHWithPragmaHdrStop())
+ SkippingUntilPragmaHdrStop = false;
+}
+
/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
/// If 'Namespace' is non-null, then it is a token required to exist on the
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
@@ -1220,6 +1251,15 @@
}
};
+/// "\#pragma hdrstop [<header-name-string>]"
+struct PragmaHdrstopHandler : public PragmaHandler {
+ PragmaHdrstopHandler() : PragmaHandler("hdrstop") {}
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &DepToken) override {
+ PP.HandlePragmaHdrstop(DepToken);
+ }
+};
+
/// "\#pragma warning(...)". MSVC's diagnostics do not map cleanly to clang's
/// diagnostics, so we don't really implement this pragma. We parse it and
/// ignore it to avoid -Wunknown-pragma warnings.
@@ -1799,6 +1839,7 @@
if (LangOpts.MicrosoftExt) {
AddPragmaHandler(new PragmaWarningHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
+ AddPragmaHandler(new PragmaHdrstopHandler());
}
// Pragmas added by plugins