<div dir="ltr">+Aaron<div><br></div><div>Tangentially related:<br><div><br></div><div>It strikes me our current inheritance behavior for AnnotateAttr (ie, inherit unless already present) makes no sense, as we have no idea what the attribute means or how it should be inherited from one declaration to another. If one declaration has the attribute and a redeclaration has the attribute with a different string, under what circumstances should we drop the old attribute? It seems to me that the only sensible options are "inherit all attributes even if one is already present on the new declaration" (eg, set InheritEvenIfAlreadyPresent) and "never inherit an AnnotateAttr" (eg, make it not be an InheritableAttr).</div><div><br></div><div>I have no particular preference between those two; either option seems like it creates some extra hassle for some users of the attribute, and less hassle for others, but the status quo seems wrong. Aaron, what do you think?</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 5 May 2018 at 20:18, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On 5 May 2018 at 13:33, Jacob Bandes-Storch via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I am using an AST matcher and would like to prevent an annotation attribute from being placed on an out-of-line constructor definition.<div><br></div><div>    class Foo {</div><div>        explicit Foo(int);  // ok</div><div>        [[clang::annotate("implicit")]<wbr>] Foo(int);  // ok</div><div>    };</div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="font-weight:400"><br class="m_-4397678545761245407gmail-m_-2927510384891060441gmail-Apple-interchange-newline">    explicit Foo::Foo() {}  // </span><b>disallowed</b><br class="m_-4397678545761245407gmail-m_-2927510384891060441gmail-Apple-interchange-newline" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial"><span style="font-weight:400;color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">    [[clang::annotate("implicit")]<wbr>] Foo::Foo(int)</span> {}  // </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><b>should be disallowed</b></span></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="font-weight:400;font-style:normal;color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">However it seems that when I match the out-of-line decl, `decl->specific_attrs<Annotate<wbr>Attr>()` contains the attribute </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><b>even if it was placed on the original in-class declaration</b></span><span style="font-weight:400;color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> and </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">not on the out-of-line definition.</span></div><br><div>How can I determine whether an Attr* was written on the out-of-line decl?</div></div></div></blockquote><div><br></div></span><div>You can look over the AnnotateAttr(s) on the out-of-line declaration and check !Attr::isInherited() to see whether they were written on that declaration.</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>I tried checking (!(attr->getLocation() < decl->getLocStart()) && !(decl->getLocEnd() < attr->getLocation())), however it seems the two locations are not comparable. When I look at their getRawEncoding()s, the attribute has values in ranges like 2147587494-2147587527 while the decl's values are more reasonable, such as 3049-3079.</div></div></div></blockquote><div><br></div></span><div>The numerical values of source locations (and their comparison order under <) have no strong relation to the semantics of the program and should be thought of as arbitrary; we give a total order under operator< to facilitate use of SourceLocations in std::map and the like. (You can use SourceManager::<wbr>isBeforeInTranslationUnit if you want to compare source locations in order of appearance, in cases where that makes sense.) Currently, the high bit of source locations indicates that they represent a location within a macro expansion (presumably in your actual testcase the attribute was coming from a macro expansion), but it would be unwise to rely on that and you should use the high-level semantically-aware functionality in SourceManager instead.</div><div> <br></div><div><span class=""><blockquote class="gmail_quote" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>I couldn't find any documentation about attribute source locations being negative.</div></div></div></blockquote><br class="m_-4397678545761245407gmail-Apple-interchange-newline"></span>The documentation comment for the SourceLocation class describes the encoding we currently use:</div><div><br></div><div><div>/// Technically, a source location is simply an offset into the manager's view</div><div>/// of the input source, which is all input buffers (including macro</div><div>/// expansions) concatenated in an effectively arbitrary order. The manager</div><div>/// actually maintains two blocks of input buffers. One, starting at offset</div><div>/// 0 and growing upwards, contains all buffers from this module. The other,</div><div>/// starting at the highest possible offset and growing downwards, contains</div><div>/// buffers of loaded modules.</div></div><div><div>///</div><div>/// In addition, one bit of SourceLocation is used for quick access to the</div><div>/// information whether the location is in a file or a macro expansion.</div></div></div></div></div>
</blockquote></div><br></div></div>