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<
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) {}
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);
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;
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();
}
};
+/// "\#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") {}
// MS extensions.
if (LangOpts.MicrosoftExt) {
AddPragmaHandler(new PragmaWarningHandler());
+ AddPragmaHandler(new PragmaExecCharsetHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
AddPragmaHandler(new PragmaHdrstopHandler());
}
#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