Add PragmaHandler for MSVC pragma execution_character_set
__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.
Patch by Matt Gardner!
Differential Revision: https://reviews.llvm.org/D58530
llvm-svn: 356185
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index c82b531..5564c0c 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/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 &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) 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() : PragmaHandler("include_alias") {}
@@ -1823,6 +1887,7 @@
// MS extensions.
if (LangOpts.MicrosoftExt) {
AddPragmaHandler(new PragmaWarningHandler());
+ AddPragmaHandler(new PragmaExecCharsetHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
AddPragmaHandler(new PragmaHdrstopHandler());
}