<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">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="gmail-m_-2927510384891060441gmail-Apple-interchange-newline">    explicit Foo::Foo() {}  // </span><b>disallowed</b><br class="gmail-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<<wbr>AnnotateAttr>()` 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><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><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><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::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><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="gmail-Apple-interchange-newline">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>