[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set

2019-03-06 Thread Matt Gardner via Phabricator via cfe-commits
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 &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() : Prag

[PATCH] D58530: Add PragmaHandler for MSVC pragma execution_character_set

2019-03-07 Thread Matt Gardner via Phabricator via cfe-commits
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

2019-03-08 Thread Matt Gardner via Phabricator via cfe-commits
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

2019-02-21 Thread Matt Gardner via Phabricator via cfe-commits
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 &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_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: clang/include/clang