<div dir="ltr">Thank you, isInherited() is what I was looking for :)<div><br></div><div>On the topic of attributes in general, I found it curious that clang completely drops unrecognized attributes and they aren't made available in any Attr (as far as I could tell), and thus can't be checked by custom plugins, etc. Do you know if there's a specific reason for this? Why not keep the original spelling around in something like "UnrecognizedAttr"?<br><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>Jacob</div></div></div></div>
<br><div class="gmail_quote">On Sun, May 6, 2018 at 7:08 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron.ballman@gmail.com" target="_blank">aaron.ballman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sat, May 5, 2018 at 11:26 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> +Aaron<br>
><br>
> Tangentially related:<br>
><br>
> It strikes me our current inheritance behavior for AnnotateAttr (ie, inherit<br>
> unless already present) makes no sense, as we have no idea what the<br>
> attribute means or how it should be inherited from one declaration to<br>
> another. If one declaration has the attribute and a redeclaration has the<br>
> attribute with a different string, under what circumstances should we drop<br>
> the old attribute? It seems to me that the only sensible options are<br>
> "inherit all attributes even if one is already present on the new<br>
> declaration" (eg, set InheritEvenIfAlreadyPresent) and "never inherit an<br>
> AnnotateAttr" (eg, make it not be an InheritableAttr).<br>
><br>
> I have no particular preference between those two; either option seems like<br>
> it creates some extra hassle for some users of the attribute, and less<br>
> hassle for others, but the status quo seems wrong. Aaron, what do you think?<br>
<br>
</span>I agree that the status quo is wrong, but I don't have a strong sense<br>
for whether we should always inherit or never inherit. I kind of feel<br>
that always inheriting but only if there's a difference in attributes<br>
would be in the spirit of the annotate attribute's "this is totally<br>
generic and can mean anything" design. However, I don't think there's<br>
a "clearly correct" behavior here, which also suggests that perhaps it<br>
should be an error (or at least a warning) to try to inherit annotate<br>
attributes with different arguments.<br>
<span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
><br>
> On 5 May 2018 at 20:18, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
>><br>
>> On 5 May 2018 at 13:33, Jacob Bandes-Storch via cfe-dev<br>
>> <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>
>>><br>
>>> I am using an AST matcher and would like to prevent an annotation<br>
>>> attribute from being placed on an out-of-line constructor definition.<br>
>>><br>
>>>     class Foo {<br>
>>>         explicit Foo(int);  // ok<br>
>>>         [[clang::annotate("implicit")]<wbr>] Foo(int);  // ok<br>
>>>     };<br>
>>><br>
>>>     explicit Foo::Foo() {}  // disallowed<br>
>>>     [[clang::annotate("implicit")]<wbr>] Foo::Foo(int) {}  // should be<br>
>>> disallowed<br>
>>><br>
>>><br>
>>> However it seems that when I match the out-of-line decl,<br>
>>> `decl->specific_attrs<<wbr>AnnotateAttr>()` contains the attribute even if it was<br>
>>> placed on the original in-class declaration and not on the out-of-line<br>
>>> definition.<br>
>>><br>
>>> How can I determine whether an Attr* was written on the out-of-line decl?<br>
>><br>
>><br>
>> You can look over the AnnotateAttr(s) on the out-of-line declaration and<br>
>> check !Attr::isInherited() to see whether they were written on that<br>
>> declaration.<br>
>><br>
>>><br>
>>> I tried checking (!(attr->getLocation() < decl->getLocStart()) &&<br>
>>> !(decl->getLocEnd() < attr->getLocation())), however it seems the two<br>
>>> locations are not comparable. When I look at their getRawEncoding()s, the<br>
>>> attribute has values in ranges like 2147587494-2147587527 while the decl's<br>
>>> values are more reasonable, such as 3049-3079.<br>
>><br>
>><br>
>> The numerical values of source locations (and their comparison order under<br>
>> <) have no strong relation to the semantics of the program and should be<br>
>> thought of as arbitrary; we give a total order under operator< to facilitate<br>
>> use of SourceLocations in std::map and the like. (You can use<br>
>> SourceManager::<wbr>isBeforeInTranslationUnit if you want to compare source<br>
>> locations in order of appearance, in cases where that makes sense.)<br>
>> Currently, the high bit of source locations indicates that they represent a<br>
>> location within a macro expansion (presumably in your actual testcase the<br>
>> attribute was coming from a macro expansion), but it would be unwise to rely<br>
>> on that and you should use the high-level semantically-aware functionality<br>
>> in SourceManager instead.<br>
>><br>
>>><br>
>>> I couldn't find any documentation about attribute source locations being<br>
>>> negative.<br>
>><br>
>><br>
>> The documentation comment for the SourceLocation class describes the<br>
>> encoding we currently use:<br>
>><br>
>> /// Technically, a source location is simply an offset into the manager's<br>
>> view<br>
>> /// of the input source, which is all input buffers (including macro<br>
>> /// expansions) concatenated in an effectively arbitrary order. The<br>
>> manager<br>
>> /// actually maintains two blocks of input buffers. One, starting at<br>
>> offset<br>
>> /// 0 and growing upwards, contains all buffers from this module. The<br>
>> other,<br>
>> /// starting at the highest possible offset and growing downwards,<br>
>> contains<br>
>> /// buffers of loaded modules.<br>
>> ///<br>
>> /// In addition, one bit of SourceLocation is used for quick access to the<br>
>> /// information whether the location is in a file or a macro expansion.<br>
><br>
><br>
</div></div></blockquote></div><br></div></div></div>