Pragma message in Clang?

What's Clang's equivalent to `#pragma message` as used in [GCC][1] and
[MSVC][2]?

  [1]: Diagnostic Pragmas (Using the GNU Compiler Collection (GCC))
  [2]: message pragma | Microsoft Docs

clang implements #pragma message but it is currently only enabled in
Microsoft mode (-fms-extensions).

Since GCC also support it, it would make sense to enable it by default.

It does, enabling it however seems to drop recognition (I assume C99
is out the window) of _Bool:

./cpfs.h(27) : error: unknown type name '_Bool'

subprocess.CalledProcessError: Command '['clang', '-c', 'bitmap.c',
'-o', '/tmp/bitmap.c.o.mbECeS', '-fms-extensions', '-Winline',
'-Wshadow', '-Wextra', '-Wmissing-format-attribute', '-Wall',
'-Wfloat-equal', '-fdiagnostics-show-option',
'-Werror-implicit-function-declaration', '-Werror=return-type',
'-fno-exceptions', '-std=gnu99', '-D_GNU_SOURCE',
'-D_FILE_OFFSET_BITS=64', '-DCPFS_SIMD_ALIGNED', '-DCPFS_USE_SSSE3',
'-DFUSE_USE_VERSION=28', '-O3', '-g', '-DNDEBUG',
'-DCPFS_LOG_LEVEL=WARNING']' returned non-zero exit status 1

I don't imagine this is intentional, or -fms-extensions is sneakily
switching language to C++, or clobbering the C standard in use.

It does, enabling it however seems to drop recognition (I assume C99
is out the window) of _Bool:

./cpfs.h(27) : error: unknown type name '_Bool'

subprocess.CalledProcessError: Command '['clang', '-c', 'bitmap.c',
'-o', '/tmp/bitmap.c.o.mbECeS', '-fms-extensions', '-Winline',
'-Wshadow', '-Wextra', '-Wmissing-format-attribute', '-Wall',
'-Wfloat-equal', '-fdiagnostics-show-option',
'-Werror-implicit-function-declaration', '-Werror=return-type',
'-fno-exceptions', '-std=gnu99', '-D_GNU_SOURCE',
'-D_FILE_OFFSET_BITS=64', '-DCPFS_SIMD_ALIGNED', '-DCPFS_USE_SSSE3',
'-DFUSE_USE_VERSION=28', '-O3', '-g', '-DNDEBUG',
'-DCPFS_LOG_LEVEL=WARNING']' returned non-zero exit status 1

I don't imagine this is intentional, or -fms-extensions is sneakily
switching language to C++, or clobbering the C standard in use.

The reason for this is because MSVC doesn't support _Bool and actually
typedefs it in some headers. I however would like a way for _Bool to
be used with -fms-extensions, but it would require special case code.

As for the pragma, I assumed it was MSVC only. Adding it to
non-ms-extensions is trivial. I'll fix it today, just need to add
support for not requiring parens.

- Michael Spencer

Thanks very much! I'll be watching the trunk with special interest.

Patch attached. Please verify.

- Michael Spencer

lexer-gcc-pragma-message.patch (3.73 KB)

Looks good to me, please commit. Feel free to enable it by default in GNU mode also if it hasn’t already been done.

-Chris

Hi, patch works. However using pragma message will generate a warning traceback:

data.c:447:1: warning: TODO: i need to do X
TODO("i need to do X")
^
In file included from data.c:1:
In file included from ./data.h:2:
In file included from ./types.h:3:
./utility.h:70:20: note: instantiated from:
#define TODO(todo) MESSAGE("TODO: " todo)
                   ^
./utility.h:68:22: note: instantiated from:
#define MESSAGE(msg) MESSAGE2(message(msg))
                     ^
./utility.h:67:25: note: instantiated from:
#define MESSAGE2(pslit) _Pragma(#pslit)
                        ^
<scratch space>:237:2: note: instantiated from:
message("TODO: " "i need to do X")
^

Where GCC only generates a single line:
data.c:447: note: #pragma message: TODO: i need to do X

Here are the convoluted macros clang shows instantiation from:

#define MESSAGE2(pslit) _Pragma(#pslit)
#define MESSAGE(msg) MESSAGE2(message(msg))

#define TODO(todo) MESSAGE("TODO: " todo)

I love the text in test/Lexer/pragma-message.c, lots of fun.

I think that this is a feature, not a bug. Making all the diagnostics consistent is good for simplicity of the code.

-Chris

Perhaps, but #pragma message is hijacking the warning machinery,
rather than generating a "note" as in GCC and MSVC. For code with many
such messages, this would be irritating. If "message" isn't
standardized however, I can understand your lack of interest in it.

Thanks everyone for your time!

Committed in r114814.

As for the macro instantiation backtrace, I'm undecided. In this case
it would be nice to suppress it, however there are other cases where
it may be desired.

- Michael Spencer

Perhaps, but #pragma message is hijacking the warning machinery,
rather than generating a "note" as in GCC and MSVC. For code with many
such messages, this would be irritating. If "message" isn't
standardized however, I can understand your lack of interest in it.

I originally tried to emit a note, but I couldn't get clang to print
it. Implementing this was actually my first patch to clang, so I never
tried to figure out exactly how to get that working.

I'm all for changing this to a note as long as clang prints it without
any extra flags.

A note wouldn't be appropriate; notes are always subordinate to other diagnostics.

John.

Right, GCC doesn't have a lot of structure or regularity to its diagnostics. In clang, a "note" is always part of the diagnostic before it. This is why trying to emit a note as the first diagnostic doesn't work. If a note comes out after a warning that is disabled, the note is disabled as well.

-Chris

Sorry I used the term "note" as that's the text GCC prepends, I wasn't
aware of internal Clang construct by that name.
Regardless of the machinery used, MSVC (and GCC to a lesser degree),
attempt to implement these messages as unconfrontational notices, they
don't generate alarm bells or macro pasting tracebacks.

It seems they're very specific about this part:

User-defined messages are displayed as messages, not warnings.