Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get fully qualified template template argument name using libtooling

I am trying to use libtooling to print a CXXRecordDecl of the substantiation of a template class with a template template parameter. Unfortunately, the string representation of the template template parameter is not fully qualified (e.g. it's missing namespaces).

I am printing the CXXRecordDecl with this code:

clang::PrintingPolicy policy = compiler_instance->getLangOpts();
std::string name = decl->getTypeForDecl()->getCanonicalTypeInternal().getAsString(policy);

Here is an example where I would expect the output to be ns::A<ns::B>, but I get ns::A<B>:

namespace ns {

template <template <class> class T>
class A {
  T<int> x;
};

template <class T>
class B {
  T y;
};

} // namespace ns

int main(int argc, char **argv)
{
  using namespace ns;
  A<B> z;
}

How do I print the fully-qualified name of a class with a template template parameter?

On a related note, is there a way to do this without calling getCanonicalTypeInternal, which sounds like an internal function?

[Edit #1] I've also tried decl->getQualifiedNameAsString(), which completely omits the template arguments and outputs ns::A.

[Edit #2] Cling trades one set of problems for another. It does correctly produce fully-qualified types for template template parameters. However, it produces unqualified names for the argument and return types of functions (and function pointers). For example, the below code produces the output ns::A<void (B)> instead of ns::A<void (ns::B)>:

namespace ns {

class B { };

template <class T>
class A { };

} // namespace

int main(int argc, char **argv)
{
  using namespace ns;

  A<void (B)> x;
}

[Edit #3] I posted an issue on the Cling issue tracker for the above issue. Note that viewing the page requires that you sign in with a CERN lightweight account. See this page for instructions to create an account.

like image 717
Michael Koval Avatar asked Oct 18 '22 22:10

Michael Koval


1 Answers

Try this: decl->getQualifiedNameAsString();

Looks like at current moment clang/libclang has suitable parts, but no the suitable and simple solution that just print full name,

see this http://lists.llvm.org/pipermail/cfe-dev/2015-October/045473.html

but there is cling project based on clang that implement such functionality, see look here:

https://root.cern.ch/gitweb?p=root.git;a=blob;f=interpreter/cling/include/cling/Utils/AST.h;h=91cea2ef82f6a6b2ed4671d43253b1c0ebd86fd4;hb=HEAD

std::string GetFullyQualifiedName(clang::QualType QT,
                                        const clang::ASTContext &Ctx);

is exactly what you looking for, after applying for your example it return ns::A<ns::B>

looks like they integrate this functionality into next or after next clang/libclang release, so hope the best.

like image 117
fghj Avatar answered Oct 31 '22 12:10

fghj