[cfe-dev] AST-dump

Pedro Delgado Perez pedro.delgado at uca.es
Thu May 30 01:41:29 PDT 2013


 
Hi,

> 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) 
> 
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.

recordDecl(
   unless(hasMethod(constructorDecl(
            allOf(hasAnyParameter(anything()), unless(isImplicit()))

I know I shouldn't use the -ast-dump-xml option, but look at this. If I have a class like this:

class E{
   public:
      E(){int a = 3;}; 
      int e;
};

This is the dump of the constructor:

<CXXConstructor used="1" ptr="0xd7d8070" name="E" prototype="true">
  <FunctionProtoType ptr="0xd7d8040" canonical="0xd7d8040">
   <BuiltinType ptr="0xd7d7c30" canonical="0xd7d7c30"/>
   <parameters/>
  </FunctionProtoType>
  <Stmt>
CompoundStmt 0xd7d81a8 <./ABC.h:4:6, col:17>
`-DeclStmt 0xd7d8198 <col:7, col:16>
 `-VarDecl 0xd7d8150 <col:7, col:15> a 'int'
   `-IntegerLiteral 0xd7d8180 <col:15> 'int' 3

  </Stmt>
 </CXXConstructor>

And this case is working fine. But when the class is this other way:

class E{
   public:
      E(); 
      int e;
};

E::E(){
  int a = 3;
}

The dump creates two CXXConstructors, I suppose one for the declaration and the other for the definition:

<CXXConstructor ptr="0xc7de070" name="E" prototype="true">
  <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040">
   <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/>
   <parameters/>
  </FunctionProtoType>
 </CXXConstructor>

....

<CXXConstructor used="1" ptr="0xc7de270" name="E" previous="0xc7de070" prototype="true">
 <FunctionProtoType ptr="0xc7de040" canonical="0xc7de040">
  <BuiltinType ptr="0xc7ddc30" canonical="0xc7ddc30"/>
  <parameters/>
 </FunctionProtoType>
 <Stmt>
CompoundStmt 0xc7de378 <./ABC.h:8:7, line:10:1>
`-DeclStmt 0xc7de368 <line:9:2, col:11>
 `-VarDecl 0xc7de320 <col:2, col:10> a 'int'
   `-IntegerLiteral 0xc7de350 <col:10> 'int' 3

 </Stmt>
 </CXXConstructor>


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:

namespace clang{ 
   namespace ast_matchers{ 
      AST_MATCHER(Decl, isUsed) 
      { 
         return Node.isUsed(); 
      } 
   } 
}

but, this is having no influence.

Maybe, I'm ignoring something.

Thanks,

Pedro.




El dia 28 may 2013 18:18, David Blaikie <dblaikie at gmail.com> escribió:
> 
> 
> 
> 
> 


> On Tue, May 28, 2013 at 2:07 AM, Pedro Delgado Perez <pedro.delgado at uca.es [ mailto:pedro.delgado at uca.es ]> wrote:
> 
> 
> 
> 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?
> 
> First of all, sorry but I made a mistake in the example:
> 
> 
> 
> class A{
> 1.   A(){...}
> 2.   A(int a){...}
> 3.   A(const A& a){... ...}
> };
> 
> 
> 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.
> 
> 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)?
> 
> 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) 
> 
> If "unless(allOf(... ...))" is the best solution, could someone enumerate the kind of constructors I must to indicate in that matcher?
> 
> 
> 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).
> 
> Ok, I didn't know it.
> 
> 
> ... 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.
> 
> Further information will be well received.
> 
> Regards,
> 
> Pedro.
> 
> El dia 27 may 2013 12:24, Manuel Klimek <klimek at google.com [ mailto:klimek at google.com ]> escribió:
> 
> 
> Hi Pedro,
> 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 :)
> On Mon, May 27, 2013 at 10:00 AM, Pedro Delgado Perez <pedro.delgado at uca.es [ mailto:pedro.delgado at uca.es ]> wrote:
> 
> 
> 
> Sorry Manuel, but I prefer to ask you all the things I don't know before you reply me:
> 
> 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:
> 
> class A{
> 1.   A(){...}
> 2.   A(int a){...}
> 3.   A(const &a){... ...}
> };
> 
> I want to look only for 1 and 2 and not for 3 when I ask:
> recordDecl(hasMethod(constructDecl(...)));
> 
> What can I do? Do I have to write "unless(allOf(isCopyConstructor(), isMoveConstructor()...))" for each type of existing constructors?
> 
> 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?
>  
> 
> Thanks,
> 
> Pedro.
> 
> 
> 
> 
> Hi Manuel,
> 
> 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.
> 
> 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:
> 
> class G{
> public:
>     G():a(1){}
>     int a;
>     virtual int ma(int arg);
> };
> 
> class L: public G{
>     public:
>         L(){v = 1;}
>         int b;
>         int h;
>         virtual int ma(int arg);
>     private:
>         int v;
>         int f();
> };
> 
> 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:
> 
> 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).
> 
>  <CXXRecord ptr="0xd695f30" name="G" typeptr="0xd695f80">
>  <CXXRecord ptr="0xd695fd0" name="G" typeptr="0xd695f80"/>
>  <AccessSpec ptr="0xd696020" access="public"/>
>  <CXXConstructor used="1" ptr="0xd696080" name="G" prototype="true">
>   <FunctionProtoType ptr="0xd696050" canonical="0xd696050">
>   <BuiltinType ptr="0xd695c40" canonical="0xd695c40"/>
>   <parameters/>
>   </FunctionProtoType>
>   <Stmt>
> CompoundStmt 0xd696450 <tst.cpp:7:10, col:11>
>   </Stmt>
>  </CXXConstructor>
> 
> ....
> 
> <CXXConstructor ptr="0xd6aefc0" name="G" prototype="true" inline="true">
>   <FunctionProtoType ptr="0xd6af050" canonical="0xd6af030" exception_spec="unevaluated">
>   <BuiltinType ptr="0xd695c40" canonical="0xd695c40"/>
>   <parameters>
>    <LValueReferenceType ptr="0xd696240" canonical="0xd696240">
>    <QualType const="true">
>     <RecordType ptr="0xd695f80" canonical="0xd695f80">
>     <CXXRecord ref="0xd695f30"/>
>     </RecordType>
>    </QualType>
>    </LValueReferenceType>
>   </parameters>
>   </FunctionProtoType>
>   <ParmVar ptr="0xd6af070" name="" initstyle="c">
>   <LValueReferenceType ptr="0xd696240" canonical="0xd696240">
>    <QualType const="true">
>    <RecordType ptr="0xd695f80" canonical="0xd695f80">
>     <CXXRecord ref="0xd695f30"/>
>    </RecordType>
>    </QualType>
>   </LValueReferenceType>
>   </ParmVar>
>  </CXXConstructor>
>  </CXXRecord>
> 
> 
> 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?
> 
> If you look at -ast-dump:
> 
> $ clang -cc1 -ast-dump t4.cc
> <snip>
> |-CXXRecordDecl 0x37faf80 <t4.cc:1:1, line:6:1> class G
> <snip>
> | |-CXXConstructorDecl 0x37fb1c0 <line:3:3, col:15> G 'void (void)'
> | | |-CXXCtorInitializer Field 0x37fb290 'a' 'int'
> | | | |-IntegerLiteral 0x382d018 <col:11> 'int' 1
> | | `-CompoundStmt 0x382d0a0 <col:14, col:15>
> <snip>
> | `-CXXConstructorDecl 0x382da70 <col:7> G 'void (const class G &)' inline
> |  `-ParmVarDecl 0x382f820 <col:7> 'const class G &'
> <snip>
> ... 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.
> cheers,
> /Manuel
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> 
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev [ http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev ]
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130530/fee232ad/attachment.html>


More information about the cfe-dev mailing list