The corresponding AST Matcher for the parent class declaration

Given the class hierarchy:

class A {};
class B {};
class C : public A {};
class D : public C {};

      

I am trying to refactor class C to inherit from class B and not class A. I can easily get a definition statement with recordDecl

:

recordDecl(hasName("C"), isDefinition()).bind("MyClass")

      

With the associated MatchCallback, I can the dump()

class check that it matches the right node. However, I haven't found a way to bind to instead, public A

or better yet, simply A

.

What would be a suitable AST Matcher for Capture public A

or A

Class C?

EDIT:

The result clang -ast-dump

filtered for class C in this situation will display something similar to the following:

CXXRecordDecl [address] <line numbers> <loc> class C definition
|- public 'class A'
|- CXXRecordDecl [address 2] <columns> <loc> implicit referenced class C

      

As if there is no AST Node type to represent parent class declarations in ast-dump.

+3


source to share


1 answer


I found this link providing some context for how to expand. Notably, one tutorial suggested using RecordDecl

in a match handler for the returned node versus this link using CXXRecordDecl

. So if we output each base to a match handler:

if (const CXXRecord *entityBase = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("entityBase")) {
    for (auto &p : entityBase->bases()) {
        p.dump();
    }
}

      

We find that the class reference is A RecordType

referenced by a CXXRecord

. However, using clang-query

, I have not found a way to bind match recordType(...)

with anything capable of pulling only public A

or A

. Instead, the solution became something like this:



std::string qual = "public ";
std::string parentName = "A";
std::string parentType = "class " + parentName;
if (0 == parentType.compare(p.getType().getAsString())) {
    Replacement Rep(*(Result.SourceManager),
        p.getLocStart().getLocWithOffset(qual.length()),
        parentName.length(),
        "B");
    Replace->insert(Rep);
}

      

I won't mark this as an answer, but just in case someone has a way to use recordType to bind the base class reference directly, rather than iterate and check the type names of the base class as shown above.

+1


source







All Articles