[cfe-dev] Finding all references to a function overload or type.

Holtgrewe, Manuel manuel.holtgrewe at fu-berlin.de
Wed Nov 21 01:41:19 PST 2012


Hi Manuel,

Thank you for your answer. I think I figured it out. Here is a quick explanation of my problem to help out others who stumble over this problem.

My problem was how to get from the template function to the instantiation thereof. A look at the output of -dump-ast, however, showed me that the AST contains the whole instantiation.

Below is the AST dump of the small example program and the program itself.

Thanks,
Manuel

typedef __int128 __int128_t;
typedef unsigned __int128 __uint128_t;
template <typename T = int, typename TSpec = Tick> struct Foo {
    struct Foo;
    inline Foo() throw() (CompoundStmt 0x27f6270 <ast_demo.cpp:8:8>)


    inline Foo(const Foo<int, Tick> &) throw();
}
template <typename T, typename TSpec> struct Foo;
struct Tick {
    struct Tick;
    inline Tick() throw();
    inline Tick(const Tick &) throw();
    inline void ~Tick() throw() (CompoundStmt 0x27f56e8 <ast_demo.cpp:4:8>)


};
struct Tock {
    struct Tock;
};
struct Foo {
    struct Foo;
};
template <typename T = int> int bar(const Foo<int, Tick> &x) (CompoundStmt 0x27f72c0 <ast_demo.cpp:13:1, col:13>
  (ReturnStmt 0x27f72a0 <col:3, col:10>
    (IntegerLiteral 0x27f1a70 <col:10> 'int' 1)))

template <typename T> int bar(const Foo<T, Tick> &x) (CompoundStmt 0x27f1ab0 <ast_demo.cpp:13:1, col:13>
  (ReturnStmt 0x27f1a90 <col:3, col:10>
    (IntegerLiteral 0x27f1a70 <col:10> 'int' 1)))

;
struct Foo {
    struct Foo;
};
template <typename T> int bar(const Foo<T, Tock> &x) (CompoundStmt 0x27f45d0 <ast_demo.cpp:21:1, col:13>
  (ReturnStmt 0x27f45b0 <col:3, col:10>
    (IntegerLiteral 0x27f4590 <col:10> 'int' 1)))

;
template <typename TSpec = Tick> int foo(const Tick &tag) (CompoundStmt 0x27f7278 <ast_demo.cpp:25:1, line:28:1>
  (DeclStmt 0x27f62b8 <line:26:3, col:20>
    0x27f5d60 "Foo<int, Tick> x =
      (CXXConstructExpr 0x27f6288 <col:19> 'Foo<int, struct Tick>':'struct Foo<int, struct Tick>''void (void) throw()')")
  (ReturnStmt 0x27f7258 <line:27:3, col:15>
    (CallExpr 0x27f7210 <col:10, col:15> 'int'
      (ImplicitCastExpr 0x27f71f8 <col:10> 'int (*)(const Foo<int, struct Tick> &)' <FunctionToPointerDecay>
        (DeclRefExpr 0x27f7170 <col:10> 'int (const Foo<int, struct Tick> &)' lvalue Function 0x27f7060 'bar' 'int (const Foo<int, struct Tick> &)' (FunctionTemplate 0x27f1a20 'bar')))
      (ImplicitCastExpr 0x27f7240 <col:14> 'const Foo<int, struct Tick>':'const struct Foo<int, struct Tick>' lvalue <NoOp>
        (DeclRefExpr 0x27f6d80 <col:14> 'Foo<int, struct Tick>':'struct Foo<int, struct Tick>' lvalue Var 0x27f5d60 'x' 'Foo<int, struct Tick>':'struct Foo<int, struct Tick>')))))

template <typename TSpec> int foo(const TSpec &tag) (CompoundStmt 0x27f4c48 <ast_demo.cpp:25:1, line:28:1>
  (DeclStmt 0x27f4b58 <line:26:3, col:20>
    0x27f4b00 "Foo<int, TSpec> x")
  (ReturnStmt 0x27f4c28 <line:27:3, col:15>
    (CallExpr 0x27f4bf8 <col:10, col:15> '<dependent type>'
      (UnresolvedLookupExpr 0x27f4b70 <col:10> '<overloaded function type>' lvalue (ADL) = '1' 0x27f4540 0x27f1a20)
      (DeclRefExpr 0x27f4bd0 <col:14> 'Foo<int, TSpec>' lvalue Var 0x27f4b00 'x' 'Foo<int, TSpec>'))))

;
int main() (CompoundStmt 0x27f5b20 <ast_demo.cpp:31:1, col:23>
  (ReturnStmt 0x27f5b00 <col:3, col:20>
    (CallExpr 0x27f5aa0 <col:10, col:20> 'int'
      (ImplicitCastExpr 0x27f5a88 <col:10> 'int (*)(const struct Tick &)' <FunctionToPointerDecay>
        (DeclRefExpr 0x27f5a00 <col:10> 'int (const struct Tick &)' lvalue Function 0x27f58f0 'foo' 'int (const struct Tick &)' (FunctionTemplate 0x27f4880 'foo')))
      (MaterializeTemporaryExpr 0x27f5ae8 <col:14, col:19> 'const struct Tick':'const struct Tick' lvalue
        (ImplicitCastExpr 0x27f5ad0 <col:14, col:19> 'const struct Tick':'const struct Tick' <NoOp>
          (CXXTemporaryObjectExpr 0x27f55c0 <col:14, col:19> 'struct Tick''void (void) throw()' zeroing))))))

template <typename T, typename TSpec>
struct Foo;

struct Tick {};
struct Tock {};

template <typename T>
struct Foo<T, Tick>
{};

template <typename T>
int bar(Foo<T, Tick> const & x)
{ return 1; }

template <typename T>
struct Foo<T, Tock>
{};

template <typename T>
int bar(Foo<T, Tock> const & x)
{ return 1; }

template <typename TSpec>
int foo(TSpec const & tag)
{
  Foo<int, TSpec> x;
  return bar(x);
}

int main()
{ return foo(Tick()); }


________________________________
From: Manuel Klimek [klimek at google.com]
Sent: Wednesday, November 21, 2012 10:20 AM
To: Holtgrewe, Manuel
Cc: cfe-dev at cs.uiuc.edu
Subject: Re: [cfe-dev] Finding all references to a function overload or type.

On Wed, Nov 21, 2012 at 10:18 AM, Holtgrewe, Manuel <manuel.holtgrewe at fu-berlin.de<mailto:manuel.holtgrewe at fu-berlin.de>> wrote:
Hi,

the location of the function declaration/definition appears to be easier to construct and would work fine for me.

Then you'll basically want to drill through the AST from the call to the declaration, and get the location of the declaration via the SourceManager.

Cheers,
/Manuel


Thanks,
Manuel

________________________________
From: Manuel Klimek [klimek at google.com<mailto:klimek at google.com>]
Sent: Wednesday, November 21, 2012 10:10 AM

To: Holtgrewe, Manuel
Cc: cfe-dev at cs.uiuc.edu<mailto:cfe-dev at cs.uiuc.edu>
Subject: Re: [cfe-dev] Finding all references to a function overload or type.

On Wed, Nov 21, 2012 at 10:02 AM, Holtgrewe, Manuel <manuel.holtgrewe at fu-berlin.de<mailto:manuel.holtgrewe at fu-berlin.de>> wrote:
ping

Maybe I should elaborate a bit further.

Given the program [1] (written as a string in the test), I would like to find out from which contextes the function overload bar(Foo<T, Tick> const &) is called.

I tried dumping parts of the AST and from that it appears that it is not directly possible to see the instantiation points. Is it possible to see a "concrete AST" with instantiated class and function templates?

What's your "key" for the overload of bar in this case?
Possible keys:
a) the location of the function declaration / definition
b) the parameter list

Cheers,
/Manuel


Thanks,
Manuel

[1] https://github.com/holtgrewe/func_references/blob/master/src/test.cpp#L114

________________________________
From: cfe-dev-bounces at cs.uiuc.edu<mailto:cfe-dev-bounces at cs.uiuc.edu> [cfe-dev-bounces at cs.uiuc.edu<mailto:cfe-dev-bounces at cs.uiuc.edu>] on behalf of Holtgrewe, Manuel [manuel.holtgrewe at fu-berlin.de<mailto:manuel.holtgrewe at fu-berlin.de>]
Sent: Monday, November 19, 2012 9:11 AM
To: cfe-dev at cs.uiuc.edu<mailto:cfe-dev at cs.uiuc.edu>

Subject: Re: [cfe-dev] Finding all references to a function overload or type.

Thank you for your answer.

I was able to write a small test program with an RecursiveASTVisitor [1] by using some example code I found on github.

However, now I'm stuck. I could not find out how to find out that the function overload bar(Foo<int, Tick> const &) is called from the AST.

Can someone help me with this and point me into the right direction again?

Thanks,
Manuel

[1] https://github.com/holtgrewe/func_references/blob/master/src/test.cpp

________________________________
From: Manuel Klimek [klimek at google.com<mailto:klimek at google.com>]
Sent: Thursday, November 15, 2012 5:12 PM
To: Holtgrewe, Manuel
Cc: cfe-dev at cs.uiuc.edu<mailto:cfe-dev at cs.uiuc.edu>
Subject: Re: [cfe-dev] Finding all references to a function overload or type.

On Thu, Nov 15, 2012 at 12:47 AM, Holtgrewe, Manuel <manuel.holtgrewe at fu-berlin.de<mailto:manuel.holtgrewe at fu-berlin.de>> wrote:
Dear all,

I would like to use the clang infrastructure (libclang, libtooling, ...) to find all references to a function overload or a type in a program. This should also work if the program has templates.

Consider the following example:

void f(int i)
{}

template <typename T>
void f(T x)
{
  X<T> y;
}

template <typename T>
struct X
{};

template <>
struct X<long>
{};

main ()
{
  f(3.0);
  f(1);
  f(1l);

  return 0;
}

For example, I would like to find all occurences of the overload "void f(int i)" (result should be the line with "f(1)" or all occurences of the specialization "X<long>" (in the line with "X<T> y" when f is called with a long value.

Is this possible with clang? If so, can anyone point me in the right direction?

Yes. Start here: http://clang.llvm.org/docs/Tooling.html

Cheers,
/Manuel


Thanks,
Manuel
_______________________________________________
cfe-dev mailing list
cfe-dev at cs.uiuc.edu<mailto:cfe-dev at cs.uiuc.edu>
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
cfe-dev at cs.uiuc.edu<mailto:cfe-dev at cs.uiuc.edu>
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev



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


More information about the cfe-dev mailing list