<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On 16 March 2017 at 22:14, Michael <span dir="ltr"><<a href="mailto:redm@gmx.de" target="_blank">redm@gmx.de</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div>template <typename BaseType><br>class BaseTemplate : public BaseType<br>{</div><div> void bar(BaseType arg1);</div><div>}</div><div><br></div><div>template <typename BaseType><br>class RecursiveBase : public BaseTemplate<BaseType></div><div>{</div><div> void foo(BaseType arg2);</div><div>}<br></div></div></div></blockquote><div><br></div><div>I am not sure if I understood you correctly but:</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><div>You also want to know that the specialised parameter of “BaseTemplate" is “Base”</div></div></div></div></blockquote><div><br></div><div>Sure, you can get this information once you _instantiate_ a class from your class template. I.e.</div><div>    class Base {};</div><div>    class Derived : public RecursiveBase<Base> {};</div><div><br></div><div>Traversing the AST and getting to the '<span style="font-size:12.8px">CXCursor_TypeRef</span>'s of 'Derived' will get you this information.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><div>And you also want to know that arg1 and arg2 of the specialised “RecursiveBase” are of type “Base”</div></div></div></div></blockquote><div><br></div><div>If you have the information that 'Derived' is built with 'Base', which you do have, then you should be able to match this information against 'foo()'/'bar()' and corresponding arguments. I.e. if we have the following:</div><div><br></div><div>    void fun() {</div><div>        Derived d;</div><div>        d.foo(Base());</div><div>    }</div><div><br></div><div>Then AST dump for 'd.foo(Base())' line would look something like this:</div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">|-`</span><span style="font-size:12.8px">CXCursor_UnexposedExpr</span><span style="font-size:12.8px">`:</span><span class="gmail-m_2852376609566435044gmail-im" style="font-size:12.8px"> ''</span></div><div><div style="font-size:12.8px"><span style="font-size:12.8px">|</span><span style="font-size:12.8px">   </span><span style="font-size:12.8px"> </span><span style="font-size:12.8px">|-`CXCursor_CallExpr`: 'foo'</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">|    </span><span style="font-size:12.8px">   </span><span style="font-size:12.8px"> </span><span style="font-size:12.8px">|-`CXCursor_MemberRefExpr`: 'foo'</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">|</span><span style="font-size:12.8px">   </span><span style="font-size:12.8px">         </span><span style="font-size:12.8px">|-`CXCursor_UnexposedExpr`: 'd'</span><br></div><div style="font-size:12.8px"><span style="font-size:12.8px">|    </span><span style="font-size:12.8px">  </span><span style="font-size:12.8px">          </span><span style="font-size:12.8px">|-`CXCursor_DeclRefExpr`: 'd'</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">|</span><span style="font-size:12.8px">   </span><span style="font-size:12.8px">     </span><span style="font-size:12.8px">|-`CXCursor_CallExpr`: ''</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">|    </span><span style="font-size:12.8px">   </span><span style="font-size:12.8px">     </span><span style="font-size:12.8px">|-`</span><span style="font-size:12.8px">CXCursor_UnexposedExpr</span><span style="font-size:12.8px">`: ''</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">|    </span><span style="font-size:12.8px">   </span><span style="font-size:12.8px">         </span><span style="font-size:12.8px">|-`</span><span style="font-size:12.8px">CXCursor_CallExpr</span><span style="font-size:12.8px">`: 'Base'</span><br></div></div><div style="font-size:12.8px"><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">If we wanted to find out more information about 'foo' we would do the follow-up on '</span><span style="font-size:12.8px">CXCursor_MemberRefExpr</span><span style="font-size:12.8px">' : 'foo' node </span><span style="font-size:12.8px">by using a 'clang_getCursorReferenced()'</span><span style="font-size:12.8px"> </span><span style="font-size:12.8px">and dumping the information we get from resulting node. You will find out that type spelling of referenced (resulting) node will be set to 'void (Base)', and not to 'void (BaseType)' as it was for a '</span><span style="font-size:small">RecursiveBase</span><span style="font-size:12.8px">' template class. I am not sure but there might be a libclang API from this point on wards to get the number of arguments and their types.</span></div><div style="font-size:12.8px"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><div>The methods are only accessible through the referenced raw template (ClassTemplate?), where you only have the raw template parameters.</div><div>It’s still possible to figure out the types in this case, yes, but it gets more and more cumbersome in the more general cases.</div><div><br></div><div>With a cursor directly at the specialised version of the template everything would already be resolved, readily usable. As you can see when dumping the tree with commandline clang. It seems just that libclang does not expose that information.</div></div></div></div></blockquote><div><br></div><div>Not every use-case is covered and exposed via libclang API. There are situations where you will have to handle your specific use-cases manually with your code (as shown above). If shown that these use-cases might be relevant for general purpose then you might go ahead and issue a patch to libclang API.</div><div><br></div><div>Cheers,</div><div>Adi</div></div></div></div>