r356185 - Add PragmaHandler for MSVC pragma execution_character_set

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 14 11:12:17 PDT 2019


Author: rnk
Date: Thu Mar 14 11:12:17 2019
New Revision: 356185

URL: http://llvm.org/viewvc/llvm-project?rev=356185&view=rev
Log:
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

Modified:
    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

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=356185&r1=356184&r2=356185&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Thu Mar 14 11:12:17 2019
@@ -506,6 +506,17 @@ def warn_pragma_warning_expected_number
   ExtWarn<"#pragma warning expected a warning number">,
   InGroup<UnknownPragmas>;
 
+// - #pragma execution_character_set(...)
+def warn_pragma_exec_charset_expected :
+  ExtWarn<"#pragma execution_character_set expected '%0'">,
+  InGroup<UnknownPragmas>;
+def warn_pragma_exec_charset_spec_invalid :
+  ExtWarn<"#pragma execution_character_set expected 'push' or 'pop'">,
+  InGroup<UnknownPragmas>;
+def warn_pragma_exec_charset_push_invalid :
+   ExtWarn<"#pragma execution_character_set invalid value '%0', only 'UTF-8' is supported">,
+   InGroup<UnknownPragmas>;
+
 def err__Pragma_malformed : Error<
   "_Pragma takes a parenthesized string literal">;
 def err_pragma_message_malformed : Error<

Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=356185&r1=356184&r2=356185&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/trunk/include/clang/Lex/PPCallbacks.h Thu Mar 14 11:12:17 2019
@@ -239,6 +239,14 @@ public:
   virtual void PragmaWarningPop(SourceLocation Loc) {
   }
 
+  /// Callback invoked when a \#pragma execution_character_set(push) directive
+  /// is read.
+  virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
+
+  /// Callback invoked when a \#pragma execution_character_set(pop) directive
+  /// is read.
+  virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
+
   /// Callback invoked when a \#pragma clang assume_nonnull begin directive
   /// is read.
   virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
@@ -477,6 +485,16 @@ public:
     Second->PragmaWarningPop(Loc);
   }
 
+  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
+    First->PragmaExecCharsetPush(Loc, Str);
+    Second->PragmaExecCharsetPush(Loc, Str);
+  }
+
+  void PragmaExecCharsetPop(SourceLocation Loc) override {
+    First->PragmaExecCharsetPop(Loc);
+    Second->PragmaExecCharsetPop(Loc);
+  }
+
   void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
     First->PragmaAssumeNonNullBegin(Loc);
     Second->PragmaAssumeNonNullBegin(Loc);

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=356185&r1=356184&r2=356185&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Thu Mar 14 11:12:17 2019
@@ -143,6 +143,8 @@ public:
                      ArrayRef<int> 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 @@ void PrintPPOutputPPCallbacks::PragmaWar
   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();

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=356185&r1=356184&r2=356185&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Thu Mar 14 11:12:17 2019
@@ -1368,6 +1368,70 @@ struct PragmaWarningHandler : public Pra
   }
 };
 
+/// "\#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 @@ void Preprocessor::RegisterBuiltinPragma
   // MS extensions.
   if (LangOpts.MicrosoftExt) {
     AddPragmaHandler(new PragmaWarningHandler());
+    AddPragmaHandler(new PragmaExecCharsetHandler());
     AddPragmaHandler(new PragmaIncludeAliasHandler());
     AddPragmaHandler(new PragmaHdrstopHandler());
   }

Modified: cfe/trunk/test/Preprocessor/pragma_microsoft.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_microsoft.c?rev=356185&r1=356184&r2=356185&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_microsoft.c (original)
+++ cfe/trunk/test/Preprocessor/pragma_microsoft.c Thu Mar 14 11:12:17 2019
@@ -198,3 +198,21 @@ void g() {}
 #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




More information about the cfe-commits mailing list