<div dir="ltr">Thanks, I'll have to look into this. I've never actually written any clang-tidy checks, so I'll need to get set up for that first.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 13, 2019 at 10:16 AM Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, Sep 12, 2019 at 4:16 PM Steve Sudit <<a href="mailto:steve@beeswax.com" target="_blank">steve@beeswax.com</a>> wrote:<br>
><br>
> You're right: my example just doesn't work because standard attributes (as opposed to compiler-specific ones) are not allowed on the call site. Thanks for pointing that out.<br>
><br>
> An alternative would be to replace [[out]] with OUT, a precompiler macro which is defined but empty. Given that this is visible to clang-tidy, the semantically-neutral token could perhaps be used as an indicator. (This is similar to what was done with MIDL headers, fwiw.)<br>
><br>
> Does this seem more plausible? I wonder if clang-tidy is even the right place or if the compiler would have to be involved because it's in a position to match the call to the definition, which clang-tidy might not be.<br>
><br>
> (Ironically, clang already supports compiler-specific per-parameter attributes whose names are similar to what I'd want: read_only, write_only, read_write.)<br>
<br>
You can register that your clang-tidy check would also like to be<br>
notified of macro definitions and expansions by overriding the<br>
registerPPCallbacks function from your check, so that may be more<br>
plausible.  See MoveConstructorInitCheck in clang-tidy for an example<br>
of how to do this.<br>
<br>
~Aaron<br>
<br>
><br>
> On Thu, Sep 12, 2019 at 3:26 PM Aaron Ballman <<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>> wrote:<br>
>><br>
>> On Thu, Sep 12, 2019 at 12:33 PM Steve Sudit via cfe-dev<br>
>> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
>> ><br>
>> > I have a question about a clang-tidy feature that would be useful to me.<br>
>> ><br>
>> > The feature would be to enforce the presence of an attribute on arguments when it is present in the parameter.<br>
>> ><br>
>> > So, for example, if a function is defined like:<br>
>> >   bool tryGet(const std::string& key, [[out]] std::string& value);<br>
>> ><br>
>> > Then calls to it would need to have a matching `[[out]]` attribute, like:<br>
>> >   if (!directory.tryGet(k, [[out]] v)) {<br>
>> ><br>
>> > If the attribute is omitted at the call site, a warning would be generated. Likewise, if the attribute appeared at the call site, but not at the function declaration, that would generate a warning.<br>
>> ><br>
>> > No deeper enforcement is necessary. Presumably, which attributes would get this enforcement would be configurable.<br>
>> ><br>
>> > Is this or anything similar already supported? If not, could someone please point me towards the steps I'd need to take get it added? This could either be as a feature request for someone else to fulfill, or if necessary, my own contribution to the project.<br>
>><br>
>> Clang does not have a plugin approach for introducing new attributes,<br>
>> so there is currently not a way for a clang-tidy check to introduce a<br>
>> new attribute. Instead, you'd have to modify clang itself to support<br>
>> the attribute. Making a new parameter attribute isn't too difficult,<br>
>> there are examples in Attr.td you could use. However, the attribute<br>
>> you'd like to use at the call site is not possible -- neither C nor<br>
>> C++ allow attributes at the expression level currently so there's no<br>
>> syntax for what you want to do. That said, you may not require the<br>
>> attribute there anyway. For instance, at the call site you can look to<br>
>> the FunctionDecl for the CallExpr (if any) and inspect its parameters<br>
>> to see if any have the [[out]] attribute and use that information to<br>
>> perform your action within the clang tidy check (perhaps).<br>
>><br>
>> ~Aaron<br>
</blockquote></div>