[cfe-dev] [PATCH] New syntax and functionality for __has_attribute
Alp Toker
alp at nuanti.com
Sat Jan 11 12:02:59 PST 2014
On 11/01/2014 19:41, Aaron Ballman wrote:
> On Sat, Jan 11, 2014 at 2:31 PM, Alp Toker <alp at nuanti.com> wrote:
>> On 10/01/2014 22:07, Aaron Ballman wrote:
>>> The __has_attribute feature macro is fantastic in many respects, but
>>> is lacking the ability to determine whether a specific attribute
>>> syntax is available or not. Instead, it currently checks whether the
>>> attribute is known within the compilation target, and nothing more.
>>> This can cause problems because not all attributes are applied in the
>>> same way.
>>>
>>> Consider dllexport as a contrived example:
>>>
>>> #if __has_attribute(dllexport)
>>> void foo(void) __attribute__((dllexport));
>>> #endif
>>>
>>> This code looks fine, but is actually broken because clang only
>>> supports __declspec(dllexport) and not __attribute__((dllexport)), and
>>> __declspec must precede the declaration.
>>>
>>> The attached patch implements new syntax for __has_attribute while
>>> retaining backwards compatibility. It allows you to specify exactly
>>> which attribute syntax you desire. If no specific syntax is specified,
>>> it behaves as it always has.
>>>
>>> The supported forms are:
>>>
>>> __has_attribute(__attribute__((ident))) // GNU-style
>>> __has_attribute(__declspec(ident)) // MS-style
>>> __has_attribute([[ident]]) // C++11-style
>>> __has_attribute([[scope::ident]]) // C++11-style
>>> __has_attribute(ident) // Keywords, or "don't care"
>>>
>>> Note that attribute arguments are not supported by design -- they
>>> really don't make any sense in the context of a feature macro.
>>
>> Hi Aaron,
>>
>> This is a step forward with some long-standing problems so certainly would
>> be a step forward. The syntax is unconventional but not unreasonable.
>>
>> Have you confirmed that the new __has_attribute() syntax can still be
>> defined to an empty expansion? That pattern is important to provide source
>> compatibility with gcc / MSVC. The latter in particular has fairly different
>> expansion rules to watch out for -- I've got a feeling it'll be OK as long
>> as no commas appear in the argument list (which was a problem with the other
>> proposed "cxx, ..." syntax) but it's worth double checking.
> There's currently a test in the test suite which I think covers this case:
>
> // CHECK: has_has_attribute
> #ifdef __has_attribute
> int has_has_attribute();
> #endif
>
> Is that what you are referring to? If so, then yes, this patch does
> still meet that need.
Sorry, I wasn't particularly clear :-)
The ifdef/undef ability for __has_attribute in clang itself is clearly
fine..
I was referring rather to the compatibility, in practice, of the
following pattern (as seen in LLVM's Compiler.h):
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
This would potentially have been a problem with syntax (2) proposed by
Richard Smith in PR15853 given that commas are macro argument
delimiters, and compounded by the fact that Microsoft has a different
take on variadic macros. That would have made it difficult or impossible
to provide an empty macro definition fallback for non-clang compilers.
What I'm wondering is whether your proposed __has_attribute syntax has
any similar expansion problems, taking into account the kinds of
arguments it accepts.
I'm hopeful that there won't be a problem because you've already
intentionally excluded attribute arguments from the syntax, therefore
commas can't appear -- but it's still worth checking this to see if the
various attribute token sequences work in practice with third-party
preprocessors.
Alp.
> Thanks!
>
> ~Aaron
--
http://www.nuanti.com
the browser experts
More information about the cfe-dev
mailing list