[cfe-dev] Matching method defined outside a class declaration

Manuel Klimek klimek at google.com
Thu Sep 26 23:57:16 PDT 2013


On Tue, Sep 17, 2013 at 3:27 PM, Jesper Eskilson <jesper.eskilson at iar.com>wrote:

> On 09/17/2013 03:20 PM, Manuel Klimek wrote:
>
>> On Tue, Sep 17, 2013 at 3:17 PM, Jesper Eskilson <jesper.eskilson at iar.com<mailto:
>> jesper.eskilson at iar.**com <jesper.eskilson at iar.com>>> wrote:
>>
>>     On 09/17/2013 02:50 PM, Manuel Klimek wrote:
>>
>>         On Tue, Sep 17, 2013 at 2:24 PM, Jesper Eskilson
>>         <jesper.eskilson at iar.com <mailto:jesper.eskilson at iar.**com<jesper.eskilson at iar.com>
>> >
>>         <mailto:jesper.eskilson at iar.**com <jesper.eskilson at iar.com>
>>
>>         <mailto:jesper.eskilson at iar.**com <jesper.eskilson at 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
>>
>
> How do construct the key so that I get unique names for B1-B3, for example
> if they are qualified by namespaces? Typically it will look like this
>
> A a1("banana", new fruits::behavior);
> A a1("tomato", new vegetables::behavior);
>

Sorry for the late answer, I was on vacation.

The solution we're using is to use a combination of the file name and the
fully qualified name as key.


>
>
>>
>>     --     *Jesper Eskilson* /Development Engineer/
>>     IAR Systems AB
>>     Box 23051, Strandbodgatan 1
>>     SE-750 23 Uppsala, SWEDEN
>>     E-mail: jesper.eskilson at iar.com <mailto:jesper.eskilson at iar.**com<jesper.eskilson at iar.com>
>> >
>>     <mailto:jesper.eskilson at iar.**com <jesper.eskilson at iar.com> <mailto:
>> jesper.eskilson at iar.**com <jesper.eskilson at iar.com>>>
>>
>>     Website: www.iar.com <http://www.iar.com>
>>     <http://www.iar.com> Twitter: www.twitter.com/iarsystems
>>     <http://www.twitter.com/**iarsystems<http://www.twitter.com/iarsystems>
>> >
>>     <http://www.twitter.com/**iarsystems<http://www.twitter.com/iarsystems>
>> >
>>
>>
>>
>
> --
> *Jesper Eskilson* /Development Engineer/
> IAR Systems AB
> Box 23051, Strandbodgatan 1
> SE-750 23 Uppsala, SWEDEN
> E-mail: jesper.eskilson at iar.com <mailto:jesper.eskilson at iar.**com<jesper.eskilson at iar.com>>
> Website: www.iar.com
> <http://www.iar.com> Twitter: www.twitter.com/iarsystems <
> http://www.twitter.com/**iarsystems <http://www.twitter.com/iarsystems>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130927/07b8c379/attachment.html>


More information about the cfe-dev mailing list