Re: [cfe-users] How to check whether a type is_copy_assignable?

2020-02-20 Thread Weston Carvalho via cfe-users
Richard,

Thanks for your response!

I'm currently getting all the CXXRecordDecls using the ASTMatchFinfer.
AFAICT, I can't access Sema since the MatchFinder is an ASTConsumer instead
of a SemaConsumer. I guess I can make my own MatchFinderWithSema; do you
know of a better way?

Also, is_copy_assignable is only one of the pieces of info I'm looking for.
The full list if what I'm trying to get for each special member is:

   1. Does it exist?
   2. Is it trivial?
   3. Is it implicitly defined?
   4. If it's not implicitly defined, is it user defined or is it
   explicitly defaulted?
   5. What's the Access Specifier?
   6. If it's a copy ctor or assign, is its argument const T& or T&?
   7. If it's an assignment operation, does it return T&?

I think I can get all of these by constructing type traits or expressions
with Sema, at least modulo the weird stuff you mentioned. (It would be nice
if I could detect/exclude those cases, but I don't think it's essential.)

I don't understand how this could trigger template instantiations or
errors; could you elaborate? Would that only be possible if the class I'm
checking is an instantiation of a template class itself or if its copy
constructor was templated?

Thanks again for your help,
Weston

On Wed, Feb 19, 2020 at 2:49 PM Richard Smith  wrote:

> On Thu, 6 Feb 2020 at 12:13, Weston Carvalho via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
>> HI,
>>
>> I'm trying to write a tool that uses the AST to look at all the class
>> declarations in our codebase and get some metrics on our use of special
>> member functions. (How many classes are copyable, how many have
>> ctors without the corresponding assignment operator, etc.) I'm running into
>> some problems with implicitly declared special members. For example:
>>
>> class UserDefCopy {
>>  public:
>>   UserDefCopy(const UserDefCopy&) {}
>>   UserDefCopy& operator=(const UserDefCopy&) { return *this; }
>> };
>> class ContainsUserDefCopy {
>>  private:
>>   UserDefCopy x_;
>> };
>>
>> UserDefCopy has a CXXConstructorDecl for its copy constructor and a
>> CXXMethodDecl for the copy-assign operator, so I can use the methods on the
>> decls to get the info I need (isDeleted, isExplicitlyDefaulted, getAccess,
>> etc.) However, ContainsUserDefCopy's copy-assign operator is implicit,
>> so there's no decl for it. Since there's no decl, I can't differentiate
>> between a class with an implicitly defaulted copy-assign and one with an
>> implicitly deleted copy-assign. ContainsUserDefCopy does have a
>> declaration for its copy constructor, but AFAICT from looking at
>> clang::Sema::AddImplicitlyDeclaredMembersToClass
>> ,
>> that's because special members with the needs_overload_resolution tag
>> are eagerly generated while others are deferred. I don't understand why the
>> ctor has the tag while the assign operator doesn't, though.
>>
>> The questions I have are:
>>
>>1. What makes a method needs_overload_resolution? The docs in
>>CXXRecordDecl just say that it "[determines] whether we need to
>>eagerly declare a defaulted [member] for this class."
>>
>> Once the class is completely defined, the definition data accessors on
> CXXRecordDecl (eg, hasTrivialCopyConstructor) are required to return
> accurate information about the class. The "needs overload resolution" flag
> is set by CXXRecordDecl if it couldn't work those properties out by itself
> and needs Sema to help. For example, if it's not trivially obvious what
> constructor would be used to copy a subobject of a class (see
> CXXRecordDecl::hasSimpleCopyConstructor), CXXRecordDecl sets the "need
> overload resolution" flag so that Sema can properly work out whether that
> class's copy constructor is trivial.
>
> This flag is just an implementation detail, and doesn't have any
> interesting meaning outside of the implementation of CXXRecordDecl and Sema.
>
>>
>>1. Is there a different way I should query the AST so that I see any
>>decls that were deferred during the Sema step? Or some other way to get
>>this information? Trying to use an implicitly deleted copy assignment
>>operator is a compiler error, so that information is obviously available
>>*somewhere*.
>>
>> It depends on what question you want the answer to. I'd guess (based on
> the subject of your email) that you want the same answer that
> is_copy_assignable would give, which means you want to know whether a
> certain assignment expression would be valid (and note that the assignment
> expression might be implemented by something other than a copy-assignment
> operator in general, C++ being what it is). Probably the easiest way to
> query that would be to call Sema::BuildTypeTrait and call
> TypeTraitExpr::getValue() on the result.
>
> You should be aware that making this query may have side-effects (in
> particular, it may trigger template instantiations and result in errors
> outs

Re: [cfe-users] cfe-users Digest, Vol 85, Issue 8

2020-02-20 Thread Robert Ankeney via cfe-users
David - thanks for your suggestions, but no luck here. I had hoped for
something like a isTemplateTypeParam() function in QualType, but no such
luck. In many cases, if I do a getCanonicalType().getAsString() I get a
"type-parameter-0-0" as a result. Though not always. I don't even always
see "Type" returned if I do a getUnqualifiedType().getAsString(). I had
hoped for a simple function call, as these template parameters seem like
generic types.

Robert

On Mon, Feb 17, 2020 at 11:58 AM via cfe-users 
wrote:

> Send cfe-users mailing list submissions to
> cfe-users@lists.llvm.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
> or, via email, send a message with subject or body 'help' to
> cfe-users-requ...@lists.llvm.org
>
> You can reach the person managing the list at
> cfe-users-ow...@lists.llvm.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of cfe-users digest..."
>
>
> Today's Topics:
>
>1. How to determine if variable is templated?
>   (Robert Ankeney via cfe-users)
>2. Re: How to determine if variable is templated?
>   (David Blaikie via cfe-users)
>
>
> --
>
> Message: 1
> Date: Sun, 16 Feb 2020 17:43:19 -0800
> From: Robert Ankeney via cfe-users 
> To: via cfe-users 
> Subject: [cfe-users] How to determine if variable is templated?
> Message-ID:
> <
> cajl6gzpylbnx8iydxnzzsxobnf5_jaege+wvxdw233cvo-t...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Suppose I have some code like:
>
> template
> Type tVar;
> function(tVar);
>
> How can I determine that tVar is templated from the VarDecl or a
> MemberExpr? I don't see any obvious function in QualType or Type.
>
> Thanks,
> Robert
> -- next part --
> An HTML attachment was scrubbed...
> URL: <
> http://lists.llvm.org/pipermail/cfe-users/attachments/20200216/2a886f3a/attachment-0001.html
> >
>
> --
>
> Message: 2
> Date: Mon, 17 Feb 2020 09:28:51 -0800
> From: David Blaikie via cfe-users 
> To: Robert Ankeney 
> Cc: via cfe-users 
> Subject: Re: [cfe-users] How to determine if variable is templated?
> Message-ID:
> <
> caens6evh8eyvo+h4ezju8gkdkxoxj7uzkt8bjyty+2inhkd...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Guessing these sort of functions would be relevant:
>
> https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html#a617bcdd5baaab0ccba71a96cd9c2ed03
>
> On Sun, Feb 16, 2020 at 5:43 PM Robert Ankeney via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
> > Suppose I have some code like:
> >
> > template
> > Type tVar;
> > function(tVar);
> >
> > How can I determine that tVar is templated from the VarDecl or a
> > MemberExpr? I don't see any obvious function in QualType or Type.
> >
> > Thanks,
> > Robert
> >
> > ___
> > cfe-users mailing list
> > cfe-users@lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
> >
> -- next part --
> An HTML attachment was scrubbed...
> URL: <
> http://lists.llvm.org/pipermail/cfe-users/attachments/20200217/fda6a48f/attachment-0001.html
> >
>
> --
>
> Subject: Digest Footer
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
>
> --
>
> End of cfe-users Digest, Vol 85, Issue 8
> 
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to determine if variable is templated?

2020-02-20 Thread David Blaikie via cfe-users
I don't understand - you'll need to be more specific. (anything that's
"this doesn't /always/ happen" sounds like there's a /lot/ going on that's
not specified in your question... compilers in general and clang in
particular are /very/ deterministic, so they do do the same thing every
time - so if there's some variation it's likely because you're looking at
different things)

If you're looking at a particular instantiation of the variable template
tVar, well, once you ask for the type of that particular instantiation
you'll be looking at a concrete type and probably too late to find out
anything about the template-y-ness.

But if you are actually looking at the DeclRef for the variable template
instantiation, then you can get the VarDecl from that DeclRef and then you
can query the VarDecl to see if it's a template as I mentioned in the link
previously - "getTemplateSpecializationKind" on the VarDecl should tell you
if it's a template at all.

At least I think that's how you'd go about it...

- Dave

On Sun, Feb 20, 2020 at 4:08 PM Robert Ankeney via cfe-users <
cfe-users@lists.llvm.org> wrote:

> David - thanks for your suggestions, but no luck here. I had hoped for
> something like a isTemplateTypeParam() function in QualType, but no such
> luck. In many cases, if I do a getCanonicalType().getAsString() I get a
> "type-parameter-0-0" as a result. Though not always. I don't even always
> see "Type" returned if I do a getUnqualifiedType().getAsString(). I had
> hoped for a simple function call, as these template parameters seem like
> generic types.
>
> Robert
>

>
On Mon, Feb 17, 2020 at 9:28 AM David Blaikie  wrote:
>
Guessing these sort of functions would be relevant:
>> https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html#a617bcdd5baaab0ccba71a96cd9c2ed03
>>
>>
>
>>
> On Sun, Feb 16, 2020 at 5:43 PM Robert Ankeney via cfe-users <
>> cfe-users@lists.llvm.org> wrote:
>>
>>> Suppose I have some code like:
>>>
>>> template
>>> Type tVar;
>>> function(tVar);
>>>
>>> How can I determine that tVar is templated from the VarDecl or a
>>> MemberExpr? I don't see any obvious function in QualType or Type.
>>>
>>> Thanks,
>>> Robert
>>>
>>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to check whether a type is_copy_assignable?

2020-02-20 Thread Richard Smith via cfe-users
On Thu, 20 Feb 2020 at 09:33, Weston Carvalho 
wrote:

> Richard,
>
> Thanks for your response!
>
> I'm currently getting all the CXXRecordDecls using the ASTMatchFinfer.
> AFAICT, I can't access Sema since the MatchFinder is an ASTConsumer instead
> of a SemaConsumer. I guess I can make my own MatchFinderWithSema; do you
> know of a better way?
>

I don't know if there's any prebuilt way to do this.


> Also, is_copy_assignable is only one of the pieces of info I'm looking
> for. The full list if what I'm trying to get for each special member is:
>
>1. Does it exist?
>2. Is it trivial?
>3. Is it implicitly defined?
>4. If it's not implicitly defined, is it user defined or is it
>explicitly defaulted?
>5. What's the Access Specifier?
>6. If it's a copy ctor or assign, is its argument const T& or T&?
>7. If it's an assignment operation, does it return T&?
>
> I think I can get all of these by constructing type traits or expressions
> with Sema, at least modulo the weird stuff you mentioned. (It would be nice
> if I could detect/exclude those cases, but I don't think it's essential.)
>

Do you actually want information about special members, or do you want to
know what (eg) a construction or assignment expression would do? These are
different questions in C++, because overload resolution might pick
something other than a special member function in order to answer them.
is_copy_assignable answers the question of whether an expression of the
form "a = b;" would be valid, which might or might not involve special
member functions.

If you actually want information about special members, then the various
methods on CXXRecordDecl may be the best way to go. Note that some of the
questions above are then trivial, and don't have dedicated accessor
methods. For example, the answer for "Does it exist?" for a copy assignment
operator is simply "yes", for every class. (If you don't declare one, one
is always declared for you.) Alternatively, you can call
Sema::ForceDeclarationOfImplicitMembers and then look for the methods you
care about.

I don't understand how this could trigger template instantiations or
> errors; could you elaborate? Would that only be possible if the class I'm
> checking is an instantiation of a template class itself or if its copy
> constructor was templated?
>

It depends. If what you want is to ask questions about the special member
functions, then most of those can be answered without triggering
instantiations (or at least, we will have already triggered those
instantiations when the answers weren't easy). If you instead want to know
"would `a = b;` invoke a trivial assignment operator?" then determining
that can involve evaluating arbitrary metaprogramming constructs, which can
result in errors.

Thanks again for your help,
> Weston
>
> On Wed, Feb 19, 2020 at 2:49 PM Richard Smith 
> wrote:
>
>> On Thu, 6 Feb 2020 at 12:13, Weston Carvalho via cfe-users <
>> cfe-users@lists.llvm.org> wrote:
>>
>>> HI,
>>>
>>> I'm trying to write a tool that uses the AST to look at all the class
>>> declarations in our codebase and get some metrics on our use of special
>>> member functions. (How many classes are copyable, how many have
>>> ctors without the corresponding assignment operator, etc.) I'm running into
>>> some problems with implicitly declared special members. For example:
>>>
>>> class UserDefCopy {
>>>  public:
>>>   UserDefCopy(const UserDefCopy&) {}
>>>   UserDefCopy& operator=(const UserDefCopy&) { return *this; }
>>> };
>>> class ContainsUserDefCopy {
>>>  private:
>>>   UserDefCopy x_;
>>> };
>>>
>>> UserDefCopy has a CXXConstructorDecl for its copy constructor and a
>>> CXXMethodDecl for the copy-assign operator, so I can use the methods on the
>>> decls to get the info I need (isDeleted, isExplicitlyDefaulted, getAccess,
>>> etc.) However, ContainsUserDefCopy's copy-assign operator is implicit,
>>> so there's no decl for it. Since there's no decl, I can't differentiate
>>> between a class with an implicitly defaulted copy-assign and one with an
>>> implicitly deleted copy-assign. ContainsUserDefCopy does have a
>>> declaration for its copy constructor, but AFAICT from looking at
>>> clang::Sema::AddImplicitlyDeclaredMembersToClass
>>> ,
>>> that's because special members with the needs_overload_resolution tag
>>> are eagerly generated while others are deferred. I don't understand why the
>>> ctor has the tag while the assign operator doesn't, though.
>>>
>>> The questions I have are:
>>>
>>>1. What makes a method needs_overload_resolution? The docs in
>>>CXXRecordDecl just say that it "[determines] whether we need to
>>>eagerly declare a defaulted [member] for this class."
>>>
>>> Once the class is completely defined, the definition data accessors on
>> CXXRecordDecl (eg, hasTrivialCopyConstructor) are required to return
>> accurate information about the cl