r179687 - Implemented #pragma GCC warning/error in the same mould as #pragma message.

Jordan Rose jordan_rose at apple.com
Wed Apr 17 09:48:44 PDT 2013


On Apr 17, 2013, at 9:16 , Andy Gibbs <andyg1001 at hotmail.co.uk> wrote:

> Author: andyg
> Date: Wed Apr 17 11:16:16 2013
> New Revision: 179687
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=179687&view=rev
> Log:
> Implemented #pragma GCC warning/error in the same mould as #pragma message.
> 
> Modified:
>    cfe/trunk/docs/UsersManual.rst
>    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
>    cfe/trunk/include/clang/Lex/PPCallbacks.h
>    cfe/trunk/include/clang/Lex/Preprocessor.h
>    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
>    cfe/trunk/lib/Lex/Pragma.cpp
>    cfe/trunk/test/Lexer/pragma-message.c
> 
> Modified: cfe/trunk/docs/UsersManual.rst
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=179687&r1=179686&r2=179687&view=diff
> ==============================================================================
> --- cfe/trunk/docs/UsersManual.rst (original)
> +++ cfe/trunk/docs/UsersManual.rst Wed Apr 17 11:16:16 2013
> @@ -652,6 +652,31 @@ supports the GCC pragma, Clang and GCC d
> of warnings, so even when using GCC compatible #pragmas there is no
> guarantee that they will have identical behaviour on both compilers.
> 
> +In addition to controlling warnings and errors generated by the compiler, it is
> +possible to generate custom warning and error messages through the following
> +pragmas:
> +
> +.. code-block:: c
> +
> +  // The following will produce warning messages
> +  #pragma message "some diagnostic message"
> +  #pragma GCC warning "TODO: replace deprecated feature"
> +
> +  // The following will produce an error message
> +  #pragma GCC error "Not supported"
> +
> +These pragmas operate similarly to the ``#warning`` and ``#error`` preprocessor
> +directives, except that they may also be embedded into preprocessor macros via
> +the C99 ``_Pragma`` operator, for example:
> +
> +.. code-block:: c
> +
> +  #define STR(X) #X
> +  #define DEFER(M,...) M(__VA_ARGS__)
> +  #define CUSTOM_ERROR(X) _Pragma(STR(GCC error(X " at line " DEFER(STR,__LINE__))))
> +
> +  CUSTOM_ERROR("Feature not available");
> +
> Controlling Diagnostics in System Headers
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=179687&r1=179686&r2=179687&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Wed Apr 17 11:16:16 2013
> @@ -406,13 +406,14 @@ def err__Pragma_malformed : Error<
> def err_pragma_comment_malformed : Error<
>   "pragma comment requires parenthesized identifier and optional string">;
> def err_pragma_message_malformed : Error<
> -  "pragma message requires parenthesized string">;
> +  "pragma %select{message|warning|error}0 requires parenthesized string">;
> def err_pragma_push_pop_macro_malformed : Error<
>    "pragma %0 requires a parenthesized string">;
> def warn_pragma_pop_macro_no_push : Warning<
>    "pragma pop_macro could not pop '%0', no matching push_macro">;
> def warn_pragma_message : Warning<"%0">,
>    InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
> +def err_pragma_message : Error<"%0">;
> def warn_pragma_ignored : Warning<"unknown pragma ignored">,
>    InGroup<UnknownPragmas>, DefaultIgnore;
> def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
> 
> Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=179687&r1=179686&r2=179687&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
> +++ cfe/trunk/include/clang/Lex/PPCallbacks.h Wed Apr 17 11:16:16 2013
> @@ -165,10 +165,25 @@ public:
>   virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
>   }
> 
> +  /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage.
> +  enum PragmaMessageKind {
> +    /// \brief \#pragma message has been invoked.
> +    PMK_Message,
> +
> +    /// \brief \#pragma GCC warning has been invoked.
> +    PMK_Warning,
> +
> +    /// \brief \#pragma GCC error has been invoked.
> +    PMK_Error
> +  };
> +
>   /// \brief Callback invoked when a \#pragma message directive is read.
>   /// \param Loc The location of the message directive.
> +  /// \param Namespace The namespace of the message directive.
> +  /// \param Kind The type of the message directive.
>   /// \param Str The text of the message directive.
> -  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
> +  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
> +                             PragmaMessageKind Kind, StringRef Str) {
>   }
> 
>   /// \brief Callback invoked when a \#pragma gcc dianostic push directive
> @@ -336,9 +351,10 @@ public:
>     Second->PragmaComment(Loc, Kind, Str);
>   }
> 
> -  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
> -    First->PragmaMessage(Loc, Str);
> -    Second->PragmaMessage(Loc, Str);
> +  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
> +                             PragmaMessageKind Kind, StringRef Str) {
> +    First->PragmaMessage(Loc, Namespace, Kind, Str);
> +    Second->PragmaMessage(Loc, Namespace, Kind, Str);
>   }
> 
>   virtual void PragmaDiagnosticPush(SourceLocation Loc,
> 
> Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=179687&r1=179686&r2=179687&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
> +++ cfe/trunk/include/clang/Lex/Preprocessor.h Wed Apr 17 11:16:16 2013
> @@ -1445,7 +1445,6 @@ public:
>   void HandlePragmaSystemHeader(Token &SysHeaderTok);
>   void HandlePragmaDependency(Token &DependencyTok);
>   void HandlePragmaComment(Token &CommentTok);
> -  void HandlePragmaMessage(Token &MessageTok);
>   void HandlePragmaPushMacro(Token &Tok);
>   void HandlePragmaPopMacro(Token &Tok);
>   void HandlePragmaIncludeAlias(Token &Tok);
> 
> Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=179687&r1=179686&r2=179687&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
> +++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Wed Apr 17 11:16:16 2013
> @@ -140,7 +140,8 @@ public:
>   virtual void PragmaCaptured(SourceLocation Loc, StringRef Str);
>   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
>                              const std::string &Str);
> -  virtual void PragmaMessage(SourceLocation Loc, StringRef Str);
> +  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
> +                             PragmaMessageKind Kind, StringRef Str);
>   virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType);
>   virtual void PragmaDiagnosticPush(SourceLocation Loc,
>                                     StringRef Namespace);
> @@ -407,12 +408,25 @@ void PrintPPOutputPPCallbacks::PragmaCom
> }
> 
> void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
> +                                             StringRef Namespace,
> +                                             PragmaMessageKind Kind,
>                                              StringRef Str) {
>   startNewLineIfNeeded();
>   MoveToLine(Loc);
> -  OS << "#pragma message(";
> -
> -  OS << '"';
> +  OS << "#pragma ";
> +  if (!Namespace.empty())
> +    OS << Namespace << ' ';
> +  switch (Kind) {
> +    case PMK_Message:
> +      OS << "message(\"";
> +      break;
> +    case PMK_Warning:
> +      OS << "warning(\"";
> +      break;
> +    case PMK_Error:
> +      OS << "error(\"";
> +      break;
> +  } 

Sorry to get this post-commit, but isn't this wrong because the GCC version doesn't use parens? Maybe we don't care because we don't really support preprocessing under one compiler and compiling under another, but it is strange to get this "wrong".



More information about the cfe-commits mailing list