AST-dump

Hi,

Well, I’m going to rewind and try to give as much information of the problem as possible to clarify it to everyone.

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 constructor belongs to, doesn’t have any other constructors (with at least another constructor, the compiler doesn’t provide the default constructor).

So, I created the next matcher:

DeclarationMatcher DefaultConstructorMatcher =
recordDecl(
unless(hasMethod(constructorDecl(
allOf(hasAnyParameter(anything()), unless(isImplicit()))))),
hasMethod(constructorDecl(isDefinition(), parameterCountIs(0),
anyOf(hasAnyConstructorInitializer(isWritten()), has(compoundStmt(has(stmt()))))).bind(“default_constructor”))
).bind(“class_default_constructor”);

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.

(Note: I put “unless(isImplicit())” to avoid other implicit constructors provides by the compiler)

Then, I can do:

if (Result.Nodes.getNodeAsclang::CXXRecordDecl(“class_default_constructor”))
const CXXConstructorDecl *FS = Result.Nodes.getNodeAsclang::CXXConstructorDecl(“default_constructor”);

The problem now is:

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

Constructor E() is retrieved.

  • Case 2:
    class E{
    public:
    E();
    int e;
    };

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

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:

CompoundStmt 0xc7de378 <./ABC.h:8:7, line:10:1> `-DeclStmt 0xc7de368 `-VarDecl 0xc7de320 a 'int' `-IntegerLiteral 0xc7de350 'int' 3

With all this information everyone could test that this is true. Now, responding your message:

Did you mean “clang::Redeclarable< decl_type >” class?

Yes.

I’ve been looking for a solution with this, but I definitively have no idea what can I do with it.

I think your suggestion might be useful to me, so that the second declaration is not taken into account

Yes, that is the idea.

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.

the matcher you are suggesting is previous to this or is included in the same matcher I’m trying to build?

I don’t understand what you mean.

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.

Thanks for your concern,

Pedro.

El dia 10 jun 2013 00:50, Gábor Kozár kozargabor@gmail.com escribió:

Hi,

Well, I'm going to rewind and try to give as much information of the
problem as possible to clarify it to everyone.

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

Why do you care whether the default constructor is trivial? Wouldn't you
also want to delete trivial constructors here?

constructor belongs to, doesn't have any other constructors (with at least
another constructor, the compiler doesn't provide the default constructor).

So, I created the next matcher:

DeclarationMatcher DefaultConstructorMatcher =
recordDecl(
           unless(hasMethod(constructorDecl(
                allOf(hasAnyParameter(anything()),
unless(isImplicit()))))),
           hasMethod(constructorDecl(isDefinition(), parameterCountIs(0),
                 anyOf(hasAnyConstructorInitializer(isWritten()),
has(compoundStmt(has(stmt())))

What doesn't match here is hasMethod(constructorDecl(isDefinition())).
hasMethod will *not* loop over all declarations, but just the ones made in
the recordDecl.

To your specific problem (and tying into my above question): why not just
constructorDecl(parameterCountIs(0), unless(isImplicit()))?