diff options
Diffstat (limited to 'lib/Lex/Pragma.cpp')
-rw-r--r-- | lib/Lex/Pragma.cpp | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 37c0a23646c59..575935119f6f1 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -31,7 +31,6 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorLexer.h" -#include "clang/Lex/PTHLexer.h" #include "clang/Lex/Token.h" #include "clang/Lex/TokenLexer.h" #include "llvm/ADT/ArrayRef.h" @@ -404,10 +403,7 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) { void Preprocessor::HandlePragmaMark() { assert(CurPPLexer && "No current lexer?"); - if (CurLexer) - CurLexer->ReadToEndOfLine(); - else - CurPTHLexer->DiscardToEndOfLine(); + CurLexer->ReadToEndOfLine(); } /// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'. @@ -810,12 +806,6 @@ void Preprocessor::HandlePragmaModuleBuild(Token &Tok) { DiscardUntilEndOfDirective(); } - if (CurPTHLexer) { - // FIXME: Support this somehow? - Diag(Loc, diag::err_pp_module_build_pth); - return; - } - CurLexer->LexingRawMode = true; auto TryConsumeIdentifier = [&](StringRef Ident) -> bool { @@ -876,6 +866,37 @@ void Preprocessor::HandlePragmaModuleBuild(Token &Tok) { 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". @@ -1099,10 +1120,6 @@ struct PragmaDebugHandler : public PragmaHandler { } void HandleCaptured(Preprocessor &PP) { - // Skip if emitting preprocessed output. - if (PP.isPreprocessedOutput()) - return; - Token Tok; PP.LexUnexpandedToken(Tok); @@ -1220,6 +1237,15 @@ public: } }; +/// "\#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 +1825,7 @@ void Preprocessor::RegisterBuiltinPragmas() { if (LangOpts.MicrosoftExt) { AddPragmaHandler(new PragmaWarningHandler()); AddPragmaHandler(new PragmaIncludeAliasHandler()); + AddPragmaHandler(new PragmaHdrstopHandler()); } // Pragmas added by plugins |