[cfe-dev] How to compare Attr location with Decl location?
Richard Smith via cfe-dev
cfe-dev at lists.llvm.org
Sat May 5 20:18:02 PDT 2018
On 5 May 2018 at 13:33, Jacob Bandes-Storch via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> I am using an AST matcher and would like to prevent an annotation
> attribute from being placed on an out-of-line constructor definition.
>
> class Foo {
> explicit Foo(int); // ok
> [[clang::annotate("implicit")]] Foo(int); // ok
> };
>
> explicit Foo::Foo() {} // *disallowed*
> [[clang::annotate("implicit")]] Foo::Foo(int) {} // *should be
> disallowed*
>
>
> However it seems that when I match the out-of-line decl,
> `decl->specific_attrs<AnnotateAttr>()` contains the attribute *even if it
> was placed on the original in-class declaration* and not on the
> out-of-line definition.
>
> How can I determine whether an Attr* was written on the out-of-line decl?
>
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.
> 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.
>
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.
> I couldn't find any documentation about attribute source locations being
> negative.
>
The documentation comment for the SourceLocation class describes the
encoding we currently use:
/// Technically, a source location is simply an offset into the manager's
view
/// of the input source, which is all input buffers (including macro
/// expansions) concatenated in an effectively arbitrary order. The manager
/// actually maintains two blocks of input buffers. One, starting at offset
/// 0 and growing upwards, contains all buffers from this module. The other,
/// starting at the highest possible offset and growing downwards, contains
/// buffers of loaded modules.
///
/// In addition, one bit of SourceLocation is used for quick access to the
/// information whether the location is in a file or a macro expansion.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180505/15c37994/attachment.html>
More information about the cfe-dev
mailing list