[cfe-users] How to detect trait keywords that have reverted to identifiers

Andy Gibbs via cfe-users cfe-users at lists.llvm.org
Wed Aug 31 05:03:26 PDT 2016


Hi,

I'm having a problem that maybe someone here knows a good solution to.

I have headers that use the clang type-trait built-ins, for example __is_void.  
However, using these headers will throw spurious errors if certain system 
headers are included before them.

Here is a minimal bit of code that demonstrates the problem:

  #include <math.h>

  template <bool> struct Test { };
  using T = Test<__is_void(void)>;

Compiling with:
  clang++ -std=c++14 -Wall test.cpp

produces the sole error:
  test.cpp:4:30: error: expected '(' for function-style cast or type 
construction

Take out the "#include <math.h>" line, or compile on a system with a different 
system header implementation, and everything is fine.

Unfortunately, the error message is less than helpful.  The cause is due to 
math.h including, along the way, c++/6.1.1/bits/cpp_type_traits.h, which
has struct std::__is_void defined.  Now, if this segment of the header is 
placed in the source file itself, then I get the warning that __is_void has 
reverted to an identifier for the rest of the translation unit, which explains 
the reason behind the otherwise cryptic error message.

Could it not be possible for clang to manage some sort of scoping -- after 
all, why can't std::__is_void be a struct and the standalone __is_void still 
act as the built-in type-trait?!

Failing that, is there any way of detecting, in code, that a type-trait has 
reverted to an identifier, to allow something akin to...

  static_assert(!is_trait_usable(__is_void),
    "__is_void has reverted to identifier; consider re-ordering include files");

... to be placed in the header using __is_void?

If anyone has a good idea, I would love to hear!

Cheers
Andy




More information about the cfe-users mailing list