<html>
<head></head>
<body>
<blockquote class="replyBlock" style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><p>Why do you care whether the default constructor is trivial? Wouldn't you also want to delete trivial constructors here?</p>
</blockquote><blockquote class="replyBlock" style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>What doesn't match here is hasMethod(constructorDecl(isDefinition())).</div><div>hasMethod will *not* loop over all declarations, but just the ones made in the recordDecl.</div><p><br />To your specific problem (and tying into my above question): why not just constructorDecl(parameterCountIs(0), unless(isImplicit())</p>
</blockquote><br/>
<p>Well, my purpose is to delete it so that the compiler provides one. It is pointless to delete it if the compiler is going to provide the same constructor again. There is no change, but if there isn't another option...</p>
<p>Maybe, I can look for the matcher you suggest "constructorDecl(parameterCountIs(0), unless(isImplicit())" and then only go on with the process determining if the constructor matched is a definition and it is not trivial as I was trying to do inside the matcher. Is that ok?</p>
<p>Thanks,</p>
<p>Pedro.</p>
<br/>
<br/>
<br/>
<br/>
<div><em>El dia 10 jun 2013 11:49, Manuel Klimek <klimek@google.com> escribió:</em></div><blockquote class="replyBlock" style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div dir="ltr">On Mon, Jun 10, 2013 at 10:13 AM, Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgado@uca.es" target="_blank">pedro.delgado@uca.es</a>></span> wrote:<br /><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div><p>Hi,</p>
<p>Well, I'm going to rewind and try to give as much information of the problem as possible to clarify it to everyone.</p>
<p>My intention is the next: I want to retrieve the default constructor of a class (not trivial if possible) and then to delete it so that the compiler provides one. For this purpose, I need to verify that the class that default</p>
</div></blockquote><div>Why do you care whether the default constructor is trivial? Wouldn't you also want to delete trivial constructors here?</div><blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div><p>constructor belongs to, doesn't have any other constructors (with at least another constructor, the compiler doesn't provide the default constructor).</p>
<p>So, I created the next matcher:</p>
<p>DeclarationMatcher DefaultConstructorMatcher =<br /> recordDecl(<br /> unless(hasMethod(constructorDecl(<br /> allOf(hasAnyParameter(anything()), unless(isImplicit()))))),<br /> hasMethod(constructorDecl(isDefinition(), parameterCountIs(0),<br /> anyOf(hasAnyConstructorInitializer(isWritten()), has(compoundStmt(has(stmt())))</p>
</div></blockquote><div>What doesn't match here is hasMethod(constructorDecl(isDefinition())).</div><div>hasMethod will *not* loop over all declarations, but just the ones made in the recordDecl.</div><div><br />To your specific problem (and tying into my above question): why not just constructorDecl(parameterCountIs(0), unless(isImplicit()))?</div><div> </div><blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div><p>)).bind("default_constructor"))<br /> ).bind("class_default_constructor");</p>
<p>The first part helps me to discard classes with a constructor different from the default constructor and the second part gives me the default constructor I'm looking for.</p>
<p>(Note: I put "unless(isImplicit())" to avoid other implicit constructors provides by the compiler)</p>
<p>Then, I can do:</p>
<p> if (Result.Nodes.getNodeAs<clang::CXXRecordDecl>("class_default_constructor"))<br /> const CXXConstructorDecl *FS = Result.Nodes.getNodeAs<clang::CXXConstructorDecl>("default_constructor");</p>
<p>The problem now is:</p>
<p>- Case 1:</p>
<div class="im"><br />class E{<br /> public:<br /> E(){int a = 3;}; <br /> int e;<br />};</div><br/>
<br/>
<p>Constructor E() is retrieved.</p>
<p>- Case 2: </p>
<div class="im">class E{<br /> public:<br /> E(); <br /> int e;<br />};</div><br/>
<br/>
<div class="im"><p>E::E(){<br /> int a = 3;<br />}</p>
</div><p>Constructor E() is not retrieved. I think the problem is that there are two CXXConstructors in the AST, I suppose one for the declaration and the other for the definition:</p>
<div class="im"><p><CXXConstructor ptr="0xc7de070" name="E" prototype="true"><br /> <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040"><br /> <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/><br /> <parameters/><br /> </FunctionProtoType><br /> </CXXConstructor></p>
<p>....</p>
<p><CXXConstructor used="1" ptr="0xc7de270" name="E" previous="0xc7de070" prototype="true"><br /> <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040"><br /> <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/><br /> <parameters/><br /> </FunctionProtoType><br /> <Stmt><br />CompoundStmt 0xc7de378 <./ABC.h:8:7, line:10:1><br />`-DeclStmt 0xc7de368 <line:9:2, col:11><br /> `-VarDecl 0xc7de320 <col:2, col:10> a 'int'<br /> `-IntegerLiteral 0xc7de350 <col:10> 'int' 3<br /><br /> </Stmt><br /> </CXXConstructor></p>
<br/>
</div><p>With all this information everyone could test that this is true. Now, responding your message:</p>
<div class="im"><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>> <em>Did you mean "clang::Redeclarable< decl_type >" class?</em></div><div><em><br /></em></div><div>Yes.<em><br /></em></div></blockquote></div><p>I've been looking for a solution with this, but I definitively have no idea what can I do with it.</p>
<div class="im"><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>> <em>I think your suggestion might be useful to me, so that the second declaration is not taken into account</em></div><div><em><br /></em></div><div>Yes, that is the idea.<em><br /></em></div></blockquote></div><p>Yes, but I need this only for the first part of the matcher, not for the second part as I need to determine whether the constructor is trivial or not.</p>
<div class="im"><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>> <em>the matcher you are suggesting is previous to this or is included in the same matcher I'm trying to build?</em></div><div><em><br /></em></div><p>I don't understand what you mean.</p>
</blockquote></div><p>What I was asking was whether I needed to change my matcher "DefaultConstructorMatcher" to do what you proposed or I had to create a new one to act before my matcher.</p>
<p>Thanks for your concern,</p>
<p>Pedro.</p>
<br/>
<br/>
<div><em>El dia 10 jun 2013 00:50, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><div><div class="h5"><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div dir="ltr"><div>Hi,</div><div>I reread your previous e-mail, and I do not know why your matcher is not working as intended in the example - I cannot find any problems with it. Did you try filtering out the methods that have been declared before, to see whether the E(); line or the E::E() line causes the matcher to fail?</div><div>> <em>Did you mean "clang::Redeclarable< decl_type >" class?</em></div><div><em><br /></em></div><div>Yes.<em><br /></em></div><div>> <em>I think your suggestion might be useful to me, so that the second declaration is not taken into account</em></div><div><em><br /></em></div><div>Yes, that is the idea.<em><br /></em></div><div>> <em>but I can't still understand why the matcher is doing that if the second declaration doesn't fit that matcher's conditions.</em></div><div><em><br /></em></div><div>Me neither, it appears that we're missing something.<em><br /></em></div><div>> <em>the matcher you are suggesting is previous to this or is included in the same matcher I'm trying to build?</em></div><div><em><br /></em></div><div>I don't understand what you mean.<em><br /></em></div><div>Gabor</div></div><div class="gmail_extra"><br /><br /><div class="gmail_quote">2013/5/31 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgado@uca.es" target="_blank">pedro.delgado@uca.es</a>></span><br /><blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div><p>Did you mean "clang::Redeclarable< decl_type >" class? I think your suggestion might be useful to me, so that the second declaration is not taken into account, but I can't still understand why the matcher is doing that if the second declaration doesn't fit that matcher's conditions.</p>
<p>I will look into this, but the matcher you are suggesting is previous to this or is included in the same matcher I'm trying to build?</p>
<p>Thanks,</p>
<p>Pedro.</p>
<div><em>El dia 30 may 2013 21:36, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><div><div><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div dir="ltr"><div>Well, try filtering out declarations that are not first declarations - it looks to me that would solve your issue.</div><div>I think you'll need to create a new matcher for this. In fact, this might be useful to implement generally and contribute to Clang. I believe there is a base class for redeclarable AST nodes, but can't remember the exact name - you should use that for your matcher.</div></div><div class="gmail_extra"><br /><br /><div class="gmail_quote">2013/5/30 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgado@uca.es" target="_blank">pedro.delgado@uca.es</a>></span><br /><blockquote class="gmail_quote" style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div><p>Hi,</p>
<div><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><p>Default, copy, and move constructors are provided implicitly (under various conditions - obviously if you have members that aren't default, copy, or move constructible, you might not/cannot get all of those) </p>
</blockquote></div><p>Ok, but this keeps giving me trouble. I've used the isImplicit() matcher to avoid those implicit constructors, but it isn't working how I need yet.</p>
<p>recordDecl(<br /> unless(hasMethod(constructorDecl(<br /> allOf(hasAnyParameter(anything()), unless(isImplicit()))</p>
<p>I know I shouldn't use the -ast-dump-xml option, but look at this. If I have a class like this:</p>
<p>class E{<br /> public:<br /> E(){int a = 3;}; <br /> int e;<br />};</p>
<p>This is the dump of the constructor:</p>
<p><CXXConstructor used="1" ptr="0xd7d8070" name="E" prototype="true"><br /> <FunctionProtoType ptr="0xd7d8040" canonical="0xd7d8040"><br /> <BuiltinType ptr="0xd7d7c30" canonical="0xd7d7c30"/><br /> <parameters/><br /> </FunctionProtoType><br /> <Stmt><br />CompoundStmt 0xd7d81a8 <./ABC.h:4:6, col:17><br />`-DeclStmt 0xd7d8198 <col:7, col:16><br /> `-VarDecl 0xd7d8150 <col:7, col:15> a 'int'<br /> `-IntegerLiteral 0xd7d8180 <col:15> 'int' 3<br /><br /> </Stmt><br /> </CXXConstructor></p>
<p>And this case is working fine. But when the class is this other way:</p>
<p>class E{<br /> public:<br /> E(); <br /> int e;<br />};</p>
<p>E::E(){<br /> int a = 3;<br />}</p>
<p>The dump creates two CXXConstructors, I suppose one for the declaration and the other for the definition:</p>
<p><CXXConstructor ptr="0xc7de070" name="E" prototype="true"><br /> <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040"><br /> <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/><br /> <parameters/><br /> </FunctionProtoType><br /> </CXXConstructor></p>
<p>....</p>
<p><CXXConstructor used="1" ptr="0xc7de270" name="E" previous="0xc7de070" prototype="true"><br /> <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040"><br /> <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/><br /> <parameters/><br /> </FunctionProtoType><br /> <Stmt><br />CompoundStmt 0xc7de378 <./ABC.h:8:7, line:10:1><br />`-DeclStmt 0xc7de368 <line:9:2, col:11><br /> `-VarDecl 0xc7de320 <col:2, col:10> a 'int'<br /> `-IntegerLiteral 0xc7de350 <col:10> 'int' 3<br /><br /> </Stmt><br /> </CXXConstructor></p>
<br/>
<p>And this is the case my matcher is not retrieving the class E. I don't know if clang it's considering that first CxxConstructor as implicit... The only difference I can see is the "used" attribute. I've tried creating a simple matcher to use the isUsed() method of Decl class:</p>
<p>namespace clang{ <br /> namespace ast_matchers{ <br /> AST_MATCHER(Decl, isUsed) <br /> { <br /> return Node.isUsed(); <br /> } <br /> } <br />}</p>
<p>but, this is having no influence.</p>
<p>Maybe, I'm ignoring something.</p>
<p>Thanks,</p>
<p>Pedro.</p>
<br/>
<br/>
<br/>
<div><em>El dia 28 may 2013 18:18, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> escribió:</em></div><div><div><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div dir="ltr"><br /><div class="gmail_extra"><br /><br /></div></div></blockquote><div dir="ltr"><div class="gmail_extra"><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="gmail_quote">On Tue, May 28, 2013 at 2:07 AM, Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgado@uca.es" target="_blank">pedro.delgado@uca.es</a>></span> wrote:<br /><div><div><p>That seems like an approach that works. I don't know that there's a different common property. Why's the default constructor different from the copy constructor here?</p>
</div><p>First of all, sorry but I made a mistake in the example:</p>
<br/>
<br/>
<div>class A{<br />1. A(){...}<br />2. A(int a){...}</div><p>3. <strong>A(const A& a){... ...}</strong><br />};</p>
<br/>
<p>What I mean is that I need to find if there is at least one constructor that explicitly overloads the default constructor so that if I delete the default constructor the compiler won't provide the default constructor. So, my question was totally erroneous as the copy constructor does overload the default constructor if provided, but I don't want to take it into account if it wasn't explicitly provided.</p>
<p>A better question is: which are the kind of constructors that the compiler provides if no constructors are explicitly supplied? Only the default and the copy constructor (in some situations)?</p>
</div><div>Default, copy, and move constructors are provided implicitly (under various conditions - obviously if you have members that aren't default, copy, or move constructible, you might not/cannot get all of those) </div><div><p>If "unless(allOf(... ...))" is the best solution, could someone enumerate the kind of constructors I must to indicate in that matcher?</p>
<div><p>I'd suggest to not use ast-dump-xml any more. It's basically deprecated, and hopefully it'll be removed soon. -ast-dump gives you all the information (and more).</p>
</div><p>Ok, I didn't know it.</p>
<div><p>... you can see that one is the default constructor and the other one is the copy constructor. If you just put "G g;" into the code instead of the second class, you'll also see that a simple use of G already triggers the copy constructor to appear. Others are probably better able to explain exactly when a copy constructor is created.</p>
</div><p>Further information will be well received.</p>
<p>Regards,</p>
<p>Pedro.</p>
<div><em>El dia 27 may 2013 12:24, Manuel Klimek <<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>> escribió:</em></div><div><div><div dir="ltr">Hi Pedro,<div>first, please always send those mails also to cfe-dev. There are people who are much more knowledgable about the AST on that list, and you'll often get better answers faster that way :)</div><div class="gmail_extra">On Mon, May 27, 2013 at 10:00 AM, Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgado@uca.es" target="_blank">pedro.delgado@uca.es</a>></span> wrote:<br /><div class="gmail_quote"><div><p>Sorry Manuel, but I prefer to ask you all the things I don't know before you reply me:</p>
<p>How do I know that a CXXConstructorDecl is a "simple" constructor of a class. I mean, I want to find all the constructors in a class, but not the copy, the move or things like this constructors. I'm not able to find this in the documentation. To clarify this, I'm going to put an example:</p>
<p>class A{<br />1. A(){...}<br />2. A(int a){...}<br />3. A(const &a){... ...}<br />};</p>
<p>I want to look only for 1 and 2 and not for 3 when I ask:<br />recordDecl(hasMethod(constructDecl(...)));</p>
<p>What can I do? Do I have to write "unless(allOf(isCopyConstructor(), isMoveConstructor()...))" for each type of existing constructors?</p>
</div><div>That seems like an approach that works. I don't know that there's a different common property. Why's the default constructor different from the copy constructor here?</div><div> </div><div><p>Thanks,</p>
<p>Pedro.</p>
<br/>
<br/>
<br/>
<p>Hi Manuel,</p>
<p>I would like to ask you something about the AST built by Clang if you don't mind. I've just have a look at your video of introduction to Clang AST (By the way, nice tutorial!) and I think that you may have an answer for my trouble.</p>
<p>Look, I was trying to look for classes that had only the default constructor through ASTMatchers. Well, I tested my matcher with the next classes:</p>
<p>class G{<br />public:<br /> G():a(1){}<br /> int a;<br /> virtual int ma(int arg);<br />};</p>
<p>class L: <strong>public G</strong>{<br /> public:<br /> L(){v = 1;}<br /> int b;<br /> int h;<br /> virtual int ma(int arg);<br /> private:<br /> int v;<br /> int f();<br />};</p>
<p>My matcher only retrieved the class 'L' and not the 'G'. I was wondering what would be the problem when I had a look to the ast-dump-xml option:</p>
</div><div>I'd suggest to not use ast-dump-xml any more. It's basically deprecated, and hopefully it'll be removed soon. -ast-dump gives you all the information (and more).</div><div><p> <CXXRecord ptr="0xd695f30" name="G" typeptr="0xd695f80"><br /> <CXXRecord ptr="0xd695fd0" name="G" typeptr="0xd695f80"/><br /> <AccessSpec ptr="0xd696020" access="public"/><br /> <strong><CXXConstructor</strong> used="1" ptr="0xd696080" name="G" prototype="true"><br /> <FunctionProtoType ptr="0xd696050" canonical="0xd696050"><br /> <BuiltinType ptr="0xd695c40" canonical="0xd695c40"/><br /> <parameters/><br /> </FunctionProtoType><br /> <Stmt><br />CompoundStmt 0xd696450 <tst.cpp:7:10, col:11><br /> </Stmt><br /> </CXXConstructor></p>
<p>....</p>
<p><strong><CXXConstructor</strong> ptr="0xd6aefc0" name="G" prototype="true" inline="true"><br /> <FunctionProtoType ptr="0xd6af050" canonical="0xd6af030" exception_spec="unevaluated"><br /> <BuiltinType ptr="0xd695c40" canonical="0xd695c40"/><br /> <parameters><br /> <LValueReferenceType ptr="0xd696240" canonical="0xd696240"><br /> <QualType const="true"><br /> <RecordType ptr="0xd695f80" canonical="0xd695f80"><br /> <CXXRecord ref="0xd695f30"/><br /> </RecordType><br /> </QualType><br /> </LValueReferenceType><br /> </parameters><br /> </FunctionProtoType><br /> <ParmVar ptr="0xd6af070" name="" initstyle="c"><br /> <LValueReferenceType ptr="0xd696240" canonical="0xd696240"><br /> <QualType const="true"><br /> <RecordType ptr="0xd695f80" canonical="0xd695f80"><br /> <CXXRecord ref="0xd695f30"/><br /> </RecordType><br /> </QualType><br /> </LValueReferenceType><br /> </ParmVar><br /> </CXXConstructor><br /> </CXXRecord></p>
<br/>
<p>Why class 'G' has two constructors? If I change the test program in order that class 'L' doesn't inherits from class 'G', this doesn't happen (class 'G' only has one constructor in the ast-dump-xml) Could you lend me a hand?</p>
</div><div>If you look at -ast-dump:</div><div><div>$ clang -cc1 -ast-dump t4.cc</div><div><snip></div><div>|-CXXRecordDecl 0x37faf80 <t4.cc:1:1, line:6:1> class G</div><div><snip></div><div>| |-CXXConstructorDecl 0x37fb1c0 <line:3:3, col:15> G 'void (void)'</div><div>| | |-CXXCtorInitializer Field 0x37fb290 'a' 'int'</div><div>| | | |-IntegerLiteral 0x382d018 <col:11> 'int' 1</div><div>| | `-CompoundStmt 0x382d0a0 <col:14, col:15></div><div><snip></div><div>| `-CXXConstructorDecl 0x382da70 <col:7> G 'void (const class G &)' inline</div><div>| `-ParmVarDecl 0x382f820 <col:7> 'const class G &'</div><div><snip></div><div>... you can see that one is the default constructor and the other one is the copy constructor. If you just put "G g;" into the code instead of the second class, you'll also see that a simple use of G already triggers the copy constructor to appear. Others are probably better able to explain exactly when a copy constructor is created.</div><div>cheers,</div><div>/Manuel</div></div></div></div></div></div></div></div><br/>
<p>_______________________________________________<br />cfe-dev mailing list<br /><a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a></p>
</div></blockquote></div></div><blockquote style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><p><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></p>
</blockquote></div></div></div><br/>
<p>_______________________________________________<br />cfe-dev mailing list<br /><a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a></p>
</blockquote></div></div><p><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></p>
</blockquote></div></div></div></blockquote></div><br/>
</div></blockquote></div></div></div><br/>
<p>_______________________________________________<br/>
cfe-dev mailing list<br/>
cfe-dev@cs.uiuc.edu</p>
</blockquote></div></div></div><p><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></p>
</blockquote>
</body>
</html>