On Tue, Sep 17, 2013 at 2:24 PM, Jesper Eskilson
<jesper.eskilson@iar.com <mailto:jesper.eskilson@iar.**com<jesper.eskilson@iar.com>
>
<mailto:jesper.eskilson@iar.**com <jesper.eskilson@iar.com>
<mailto:jesper.eskilson@iar.**com <jesper.eskilson@iar.com>>>>
wrote:
Hello,
I'm trying to write an AST matcher rule which is able to match
method definitions. Given the following C++ source code:
class B
{
void foo();
void bar() {
int a_local_variable_in_bar;
}
};
void B::foo()
{
int a_local_variable_in_foo;
}
B b
int main()
{
}
I would like a matcher which can tell me where instances
of B are
created and also give me the definitions of its methods
(in this
case "foo" and "bar").
StatementMatcher m = constructExpr(
hasType(
recordDecl(**isSameOrDerivedFrom("B"),
hasMethod(methodDecl(**isDefinition()).bind("method")**
))));
But it will only give me the definition of "bar", and not the
defintion of "foo" which is declared outside the class.
This is because hasMethod will not give you anything outside
of the class definition. The reason is that you often don't
see out-of-class method definitions of when you have a class
definition.
If you already know the name of the class (as you specify it
in your matcher), why do you want to write this matcher in the
first place? You'll not be able to match all constructor calls
and method definitions in general, as classes may be
instantiated in a translation unit where not all method
definitions are visible.
If you have more details on what you're actually trying to do
(on a higher level) we might be able to help more...
If I cannot do this with matchers, is there a way to get
to the
definition of "foo" given the declaration of the class B?
No, as you might see the class definition in a header where
foo is not visible. Usually you'll want to go the other way -
find all method definitions of class "B".
I have a bunch of class instantiations in a large codebase which
look like this
A a1("banana", new B1);
A a2("apple", new B2);
A a3("ananas", new B2);
B1, B2, B3, all inherit from B which defines a method "foo"
(outside the declaration of B). This definition may or may not be
overridden in B1/B2/B3.
I want to be able to generate output on the form:
banana:
void foo() { /* this is the foo implementation in class B1 */ }
apple:
void foo() { /* this is the foo implementation in class B2 */ }
ananas:
void foo() { /* this is the foo implementation in class B3 */ }
I was thinking about first matching out all the different
definitions of foo, and then in a separate matcher match the
construction expressions of a1-a3, but I'm not sure of the best
way to "share" information between matchers.
Create intermediate output:
- output all paremeter combinations ("banana", "B1"), ("apple, "B2")
- output all method definitions ("B1", "void foo() { ... }"), ...
store the intermediate results. After running over all translation units,
do a "reduce" step where you combine the information by using the class as
the key