<div dir="ltr">Richard,<div><br></div><div>Thanks for your response!</div><div><br>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?<br></div><div><br></div><div>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:</div><div><ol><li>Does it exist?</li><li>Is it trivial?</li><li>Is it implicitly defined?</li><li>If it's not implicitly defined, is it user defined or is it explicitly defaulted?</li><li>What's the Access Specifier?</li><li>If it's a copy ctor or assign, is its argument <font face="monospace">const T&</font> or <font face="monospace">T&</font>?</li><li>If it's an assignment operation, does it return <font face="monospace">T&</font>?</li></ol><div>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.)</div><div><br></div><div>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?</div><div><br></div><div>Thanks again for your help,</div><div>Weston</div><div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 19, 2020 at 2:49 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></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 dir="ltr">On Thu, 6 Feb 2020 at 12:13, Weston Carvalho via cfe-users <<a href="mailto:cfe-users@lists.llvm.org" target="_blank">cfe-users@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><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">HI,<div><br></div><div>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:</div><div><br></div><div><div style="color:rgba(0,0,0,0.87)"><div><font face="monospace">class UserDefCopy {</font></div><div><font face="monospace"> public:</font></div><div><font face="monospace">  UserDefCopy(const UserDefCopy&) {}</font></div><div><font face="monospace">  UserDefCopy& operator=(const UserDefCopy&) { return *this; }</font></div><div><font face="monospace">};</font></div></div><div style="color:rgba(0,0,0,0.87)"><div><font face="monospace">class ContainsUserDefCopy {</font></div><div><font face="monospace"> private:</font></div><div><font face="monospace">  UserDefCopy x_;</font></div><div><font face="monospace">};</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">UserDefCopy </font>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, <font face="monospace">ContainsUserDefCopy</font>'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. <font face="monospace">ContainsUserDefCopy </font><font face="arial, sans-serif">does have a declaration for its copy constructor, but AFAICT from looking at </font><a href="https://clang.llvm.org/doxygen/classclang_1_1Sema.html#a2ddba48d645ed86f2f4d11b6e7a9010a" rel="nofollow" style="text-decoration-line:none;color:rgb(41,98,255);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif" target="_blank">clang::Sema::AddImplicitlyDeclaredMembersToClass</a>, that's because special members with the <font face="monospace">needs_overload_resolution</font><font face="arial, sans-serif"> 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.</font></div></div></div><div><br></div><div>The questions I have are:</div><div><ol><li>What makes a method <font face="monospace">needs_overload_resolution</font>? The docs in <font face="monospace">CXXRecordDecl</font> just say that it "[determines] whether we need to eagerly declare a defaulted [member] for this class."</li></ol></div></div></blockquote><div>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.<br></div><div><br></div><div>This flag is just an implementation detail, and doesn't have any interesting meaning outside of the implementation of CXXRecordDecl and Sema.</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><ol><li><font face="arial, sans-serif"><span style="color:rgba(0,0,0,0.87)">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? </span>Trying to use an implicitly deleted c<span style="color:rgba(0,0,0,0.87)">opy assignment operator is a compiler error, so that information is obviously available </span><i style="color:rgba(0,0,0,0.87)">somewhere</i><span style="color:rgba(0,0,0,0.87)">.</span></font></li></ol></div></div></blockquote><div>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.</div><div><br></div><div>You should be aware that making this query may have side-effects (in particular, it may trigger template instantiations and result in errors outside of the immediate context). But that's fundamental to the question you're asking, I'm afraid.</div></div></div>
</blockquote></div>