CXX11 attribute spelling and LateParsed=1

Hi,

I'm new to Clang hacking. Recently -prior to addition of a new attribute-, I tried adding a C++11 spelling of the DiagnoseIf attribute in the file
`tools/clang/include/clang/Basic/Attr.td':

  let Spellings = [GNU<"diagnose_if">,
                   CXX11<"", "diagnose_if", 201603>];

but the parser complains if the expression contains references to
function arguments, even if `LateParsed = 1' is specified, i.e. this
works

  int foo(int arg) __attribute__((diagnose_if(arg == 0, "text",
"warning")));

but this will not:

  [[diagnose_if(arg == 0, "text", "warning")]] int foo(int arg);

Am I missing something? Any help will be much appreciated.

Regards.

There is nowhere that a C++11-syntax attribute can be written where it
appertains to the function entity and the function parameter names are in
scope. The two locations where attributes can be applied to a name
introduced by a declarator are:

  [[here]] int f [[and_here]] (int x);

... and neither of them follows the "x" parameter's declaration. After some
discussion with Aaron, we think the best way forward is to recast such
attributes as attributes on the function *type* (that perhaps don't change
the canonical type, but do affect how the function declarator is
interpreted as forming a function in some way). That'd mean you'd put the
attributes:

  int f(int x) [[here]];

... which conveniently is a place where the function parameters are in
scope. The downside is that we don't have parsing support for attributes
that appertain to function types yet. That would need to be added.

Hi,

I'm new to Clang hacking. Recently -prior to addition of a new
attribute-, I tried adding a C++11 spelling of the DiagnoseIf attribute in
the file
`tools/clang/include/clang/Basic/Attr.td':

  let Spellings = [GNU<"diagnose_if">,
                   CXX11<"", "diagnose_if", 201603>];

but the parser complains if the expression contains references to
function arguments, even if `LateParsed = 1' is specified, i.e. this
works

  int foo(int arg) __attribute__((diagnose_if(arg == 0, "text",
"warning")));

but this will not:

  [[diagnose_if(arg == 0, "text", "warning")]] int foo(int arg);

Am I missing something? Any help will be much appreciated.

There is nowhere that a C++11-syntax attribute can be written where it
appertains to the function entity and the function parameter names are in
scope. The two locations where attributes can be applied to a name
introduced by a declarator are:

  [[here]] int f [[and_here]] (int x);

... and neither of them follows the "x" parameter's declaration. After
some discussion with Aaron, we think the best way forward is to recast such
attributes as attributes on the function *type* (that perhaps don't change
the canonical type, but do affect how the function declarator is
interpreted as forming a function in some way). That'd mean you'd put the
attributes:

  int f(int x) [[here]];

... which conveniently is a place where the function parameters are in
scope. The downside is that we don't have parsing support for attributes
that appertain to function types yet. That would need to be added.

I've been working on a fix for this; But if you want to hack on this, I'm
happy to yield.

Yes, I will be working on this for the next days. Thanks.


I have an update on this, but I forgot to post it here.

The fix turned out to be simple. Given that the attribute subject in the Attr.td file is
let Subjects = SubjectsList<[Function]>

The only thing to do is to move the type attribute to the attribute list of the declarator. That is accomplished by the following lines:

In lib/Sema/SemaType.cpp, function processTypeAttrs():

case AttributeList::AT_TheAttribute:
moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
state.getDeclarator().getAttrListRef());
break;

Regards.