[cfe-dev] AST-dump

Manuel Klimek klimek at google.com
Mon May 27 03:24:44 PDT 2013

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>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
|-CXXRecordDecl 0x37faf80 <t4.cc:1:1, line:6:1> class G
| |-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>
| `-CXXConstructorDecl 0x382da70 <col:7> G 'void (const class G &)' inline
|   `-ParmVarDecl 0x382f820 <col:7> 'const class G &'

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130527/e6fb0528/attachment.html>

More information about the cfe-dev mailing list