[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
This revision was automatically updated to reflect the committed changes. Closed by commit rL356185: Add PragmaHandler for MSVC pragma execution_character_set (authored by rnk, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D58530?vs=189629=190684#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 Files: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td cfe/trunk/include/clang/Lex/PPCallbacks.h cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp cfe/trunk/lib/Lex/Pragma.cpp cfe/trunk/test/Preprocessor/pragma_microsoft.c clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h Index: clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h === --- clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h +++ clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h @@ -134,6 +134,9 @@ llvm::ArrayRef Ids) override; void PragmaWarningPush(clang::SourceLocation Loc, int Level) override; void PragmaWarningPop(clang::SourceLocation Loc) override; + void PragmaExecCharsetPush(clang::SourceLocation Loc, + clang::StringRef Str) override; + void PragmaExecCharsetPop(clang::SourceLocation Loc) override; void MacroExpands(const clang::Token , const clang::MacroDefinition , clang::SourceRange Range, const clang::MacroArgs *Args) override; Index: clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp === --- clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp +++ clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp @@ -297,6 +297,22 @@ appendArgument("Loc", Loc); } +// Callback invoked when a #pragma execution_character_set(push) directive +// is read. +void PPCallbacksTracker::PragmaExecCharsetPush(clang::SourceLocation Loc, + clang::StringRef Str) { + beginCallback("PragmaExecCharsetPush"); + appendArgument("Loc", Loc); + appendArgument("Charset", Str); +} + +// Callback invoked when a #pragma execution_character_set(pop) directive +// is read. +void PPCallbacksTracker::PragmaExecCharsetPop(clang::SourceLocation Loc) { + beginCallback("PragmaExecCharsetPop"); + appendArgument("Loc", Loc); +} + // Called by Preprocessor::HandleMacroExpandedIdentifier when a // macro invocation is found. void Index: cfe/trunk/lib/Lex/Pragma.cpp === --- cfe/trunk/lib/Lex/Pragma.cpp +++ cfe/trunk/lib/Lex/Pragma.cpp @@ -1368,6 +1368,70 @@ } }; +/// "\#pragma execution_character_set(...)". MSVC supports this pragma only +/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn +/// otherwise to avoid -Wunknown-pragma warnings. +struct PragmaExecCharsetHandler : public PragmaHandler { + PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {} + + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override { +// Parse things like: +// execution_character_set(push, "UTF-8") +// execution_character_set(pop) +SourceLocation DiagLoc = Tok.getLocation(); +PPCallbacks *Callbacks = PP.getPPCallbacks(); + +PP.Lex(Tok); +if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "("; + return; +} + +PP.Lex(Tok); +IdentifierInfo *II = Tok.getIdentifierInfo(); + +if (II && II->isStr("push")) { + // #pragma execution_character_set( push[ , string ] ) + PP.Lex(Tok); + if (Tok.is(tok::comma)) { +PP.Lex(Tok); + +std::string ExecCharset; +if (!PP.FinishLexStringLiteral(Tok, ExecCharset, + "pragma execution_character_set", + /*MacroExpansion=*/false)) + return; + +// MSVC supports either of these, but nothing else. +if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") { + PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset; + return; +} + } + if (Callbacks) +Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8"); +} else if (II && II->isStr("pop")) { + // #pragma execution_character_set( pop ) + PP.Lex(Tok); + if (Callbacks) +Callbacks->PragmaExecCharsetPop(DiagLoc); +} else { + PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid); + return; +} + +if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")"; + return; +} + +PP.Lex(Tok); +if (Tok.isNot(tok::eod)) + PP.Diag(Tok,
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
thakis accepted this revision. thakis added a comment. Ah ok, then I agree this doesn't need serialization yet :) It'd be nice to at least diag that the stack use is valid (also for the warning stack), but it doesn't have to be in this change. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
sigatrev added a comment. This implementation doesn't track the push/pop stack, it just verifies the synax is valid and moves on. I modeled it after the PragmaWarningHandler which does the same, and thought it would be fine in this case since the only accepted value is a no-op. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
thakis added a comment. Does our serialization machinery serialize these correctly automatically? What happens if you compiler a header saying `execution_character_set_push, "utf-8")` in a header, compile that to a pch, then include that through the pch in a .c file that does pop? My guess is that this either needs (de)serialization code or a warning when the stack is not empty when a pch is written. (Examples: https://reviews.llvm.org/rL262493 https://reviews.llvm.org/rL262539 -- the latter one is probably a better example) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
sigatrev added a comment. Yeah, that would be great. Thanks! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. lgtm, thanks! Would you like someone to land this for you? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
sigatrev updated this revision to Diff 189629. sigatrev added a comment. Added tests, and slightly improved associated messaging. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 Files: clang-tools-extra/pp-trace/PPCallbacksTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang/include/clang/Basic/DiagnosticLexKinds.td clang/include/clang/Lex/PPCallbacks.h clang/lib/Frontend/PrintPreprocessedOutput.cpp clang/lib/Lex/Pragma.cpp clang/test/Preprocessor/pragma_microsoft.c Index: clang/test/Preprocessor/pragma_microsoft.c === --- clang/test/Preprocessor/pragma_microsoft.c +++ clang/test/Preprocessor/pragma_microsoft.c @@ -198,3 +198,21 @@ #pragma optimize("g", // expected-warning{{missing argument to '#pragma optimize'; expected 'on' or 'off'}} #pragma optimize("g",xyz // expected-warning{{unexpected argument 'xyz' to '#pragma optimize'; expected 'on' or 'off'}} #pragma optimize("g",on) // expected-warning{{#pragma optimize' is not supported}} + +#pragma execution_character_set // expected-warning {{expected '('}} +#pragma execution_character_set(// expected-warning {{expected 'push' or 'pop'}} +#pragma execution_character_set() // expected-warning {{expected 'push' or 'pop'}} +#pragma execution_character_set(asdf// expected-warning {{expected 'push' or 'pop'}} +#pragma execution_character_set(asdf) // expected-warning {{expected 'push' or 'pop'}} +#pragma execution_character_set(push// expected-warning {{expected ')'}} +#pragma execution_character_set(pop,) // expected-warning {{expected ')'}} +#pragma execution_character_set(pop,"asdf") // expected-warning {{expected ')'}} +#pragma execution_character_set(push, // expected-error {{expected string literal}} +#pragma execution_character_set(push,) // expected-error {{expected string literal}} +#pragma execution_character_set(push,asdf) // expected-error {{expected string literal}} +#pragma execution_character_set(push, "asdf") // expected-warning {{only 'UTF-8' is supported}} + +#pragma execution_character_set(push) +#pragma execution_character_set(push, "utf-8") +#pragma execution_character_set(push, "UTF-8") +#pragma execution_character_set(pop) \ No newline at end of file Index: clang/lib/Lex/Pragma.cpp === --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -1368,6 +1368,70 @@ } }; +/// "\#pragma execution_character_set(...)". MSVC supports this pragma only +/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn +/// otherwise to avoid -Wunknown-pragma warnings. +struct PragmaExecCharsetHandler : public PragmaHandler { + PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {} + + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override { +// Parse things like: +// execution_character_set(push, "UTF-8") +// execution_character_set(pop) +SourceLocation DiagLoc = Tok.getLocation(); +PPCallbacks *Callbacks = PP.getPPCallbacks(); + +PP.Lex(Tok); +if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "("; + return; +} + +PP.Lex(Tok); +IdentifierInfo *II = Tok.getIdentifierInfo(); + +if (II && II->isStr("push")) { + // #pragma execution_character_set( push[ , string ] ) + PP.Lex(Tok); + if (Tok.is(tok::comma)) { +PP.Lex(Tok); + +std::string ExecCharset; +if (!PP.FinishLexStringLiteral(Tok, ExecCharset, + "pragma execution_character_set", + /*MacroExpansion=*/false)) + return; + +// MSVC supports either of these, but nothing else. +if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") { + PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset; + return; +} + } + if (Callbacks) +Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8"); +} else if (II && II->isStr("pop")) { + // #pragma execution_character_set( pop ) + PP.Lex(Tok); + if (Callbacks) +Callbacks->PragmaExecCharsetPop(DiagLoc); +} else { + PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid); + return; +} + +if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")"; + return; +} + +PP.Lex(Tok); +if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set"; + } +}; + /// PragmaIncludeAliasHandler - "\#pragma include_alias("...")". struct PragmaIncludeAliasHandler : public PragmaHandler { PragmaIncludeAliasHandler() :
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
rnk added a comment. Looks good and thorough, but it needs tests. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D58530/new/ https://reviews.llvm.org/D58530 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set
sigatrev created this revision. sigatrev added reviewers: cfe-commits, rnk. Herald added subscribers: jdoerfert, jsji, kbarton, nemanjai. Herald added a project: clang. __pragma(execution_character_set(push, "UTF-8")) is used in TraceLoggingProvider.h. This commit implements a no-op handler for compatability, similar to how the flag -fexec_charset is handled. Repository: rC Clang https://reviews.llvm.org/D58530 Files: clang-tools-extra/pp-trace/PPCallbacksTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang/include/clang/Basic/DiagnosticLexKinds.td clang/include/clang/Lex/PPCallbacks.h clang/lib/Frontend/PrintPreprocessedOutput.cpp clang/lib/Lex/Pragma.cpp Index: clang/lib/Lex/Pragma.cpp === --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -1368,6 +1368,70 @@ } }; +/// "\#pragma execution_character_set(...)". MSVC supports this pragma only +/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn +/// otherwise to avoid -Wunknown-pragma warnings. +struct PragmaExecCharsetHandler : public PragmaHandler { + PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {} + + void HandlePragma(Preprocessor , PragmaIntroducerKind Introducer, +Token ) override { +// Parse things like: +// execution_character_set(push, "UTF-8") +// execution_character_set(pop) +SourceLocation DiagLoc = Tok.getLocation(); +PPCallbacks *Callbacks = PP.getPPCallbacks(); + +PP.Lex(Tok); +if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "("; + return; +} + +PP.Lex(Tok); +IdentifierInfo *II = Tok.getIdentifierInfo(); + +if (II && II->isStr("push")) { + // #pragma execution_character_set( push[ , string ] ) + PP.Lex(Tok); + if (Tok.is(tok::comma)) { +PP.Lex(Tok); + +std::string ExecCharset; +if (!PP.FinishLexStringLiteral(Tok, ExecCharset, + "pragma execution_character_set", + /*MacroExpansion=*/false)) + return; + +// MSVC supports either of these, but nothing else. +if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") { + PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid); + return; +} + } + if (Callbacks) +Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8"); +} else if (II && II->isStr("pop")) { + // #pragma execution_character_set( pop ) + PP.Lex(Tok); + if (Callbacks) +Callbacks->PragmaExecCharsetPop(DiagLoc); +} else { + PP.Diag(Tok, diag::warn_pragma_exec_charset_invalid_token); + return; +} + +if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")"; + return; +} + +PP.Lex(Tok); +if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set"; + } +}; + /// PragmaIncludeAliasHandler - "\#pragma include_alias("...")". struct PragmaIncludeAliasHandler : public PragmaHandler { PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {} @@ -1823,6 +1887,7 @@ // MS extensions. if (LangOpts.MicrosoftExt) { AddPragmaHandler(new PragmaWarningHandler()); +AddPragmaHandler(new PragmaExecCharsetHandler()); AddPragmaHandler(new PragmaIncludeAliasHandler()); AddPragmaHandler(new PragmaHdrstopHandler()); } Index: clang/lib/Frontend/PrintPreprocessedOutput.cpp === --- clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -143,6 +143,8 @@ ArrayRef Ids) override; void PragmaWarningPush(SourceLocation Loc, int Level) override; void PragmaWarningPop(SourceLocation Loc) override; + void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override; + void PragmaExecCharsetPop(SourceLocation Loc) override; void PragmaAssumeNonNullBegin(SourceLocation Loc) override; void PragmaAssumeNonNullEnd(SourceLocation Loc) override; @@ -553,6 +555,24 @@ setEmittedDirectiveOnThisLine(); } +void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc, + StringRef Str) { + startNewLineIfNeeded(); + MoveToLine(Loc); + OS << "#pragma character_execution_set(push"; + if (!Str.empty()) +OS << ", " << Str; + OS << ')'; + setEmittedDirectiveOnThisLine(); +} + +void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) { + startNewLineIfNeeded(); + MoveToLine(Loc); + OS << "#pragma character_execution_set(pop)"; + setEmittedDirectiveOnThisLine(); +} + void PrintPPOutputPPCallbacks:: PragmaAssumeNonNullBegin(SourceLocation Loc) { startNewLineIfNeeded(); Index: