[cfe-dev] Getting template arguments from a clang::Type object

Massa, Gert via cfe-dev cfe-dev at lists.llvm.org
Tue Dec 22 07:16:50 PST 2020


Hi Yitzhak

 

Thank you for pointing me in the right direction. The trick was to call getAsCXXRecordDecl on the type object first and then cast it to ClassTemplateSpecializationDecl .

 

clang::CXXRecordDecl * record = type->getAsCXXRecordDecl(); 

if (const auto * templateDecl = llvm::dyn_cast<ClassTemplateSpecializationDecl>(record))

{

    const TemplateArgumentList & argList = templateDecl->getTemplateArgs();

    for (uint i = 0; i < argList.size(); i++)

    {

        res.AddTemplateArg(ToSimpleAst(argList.get(i).getAsType()));

    }

}

 

From: Yitzhak Mandelbaum <yitzhakm at google.com> 
Sent: Monday, December 21, 2020 16:41
To: Massa, Gert (DI SW STS R&D SIM ARCH) <gert.massa at siemens.com>
Cc: cfe-dev at lists.llvm.org
Subject: Re: [cfe-dev] Getting template arguments from a clang::Type object

 

You probably want to look at `ClassTemplatesSpecializationDecl`.  If you're doing this in the context of AST matchers, then something like the following is probably what you want:

 

```

AST_MATCHER_P(clang::TypeLoc, templateSpecializationTypeLoc,
              clang::ast_matchers::TypeLocMatcher, InnerMatcher) {
  auto L = Node.getAs<clang::TemplateSpecializationTypeLoc>();
  if (L.isNull()) return false;
  return InnerMatcher.matches(L, Finder, Builder);
}

AST_MATCHER_P(
    clang::TypeLoc, hasAnyTemplateArgumentLoc,
    clang::ast_matchers::internal::Matcher<clang::TemplateArgumentLoc>,
    InnerMatcher) {
  auto L = Node.getAs<clang::TemplateSpecializationTypeLoc>();
  if (L.isNull()) return false;
  for (unsigned Index = 0, N = L.getNumArgs(); Index < N; ++Index) {
    clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(L.getArgLoc(Index), Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

 

AST_MATCHER_P(clang::TemplateArgumentLoc, refersToTypeLoc,
              clang::ast_matchers::internal::Matcher<clang::TypeLoc>,
              InnerMatcher) {
  return Node.getArgument().getKind() == clang::TemplateArgument::Type &&
         InnerMatcher.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder,
                              Builder);
}

```

 

These could be used in a matcher, for example, to identify a type which is a template instantiation with any argument that refers to some type of interest (here, identified by `inner_matcher`).

```

auto template_instantiation =
            templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
                templateArgumentLoc(refersToTypeLoc(inner_matcher))));

```

 

As for AST guides, I don't know of any good ones, unfortunately. My first place to look is clang-query (especially in godbolt.org <http://godbolt.org> ) -- I enter a code snippet and see what the resulting AST looks like.  To see the AST for types, try using something like this in godbolt.org <http://godbolt.org> :  <https://godbolt.org/z/bTaoTE> https://godbolt.org/z/bTaoTE. (Kudos to Richard Smith for this one...).

 

On Mon, Dec 21, 2020 at 9:04 AM Massa, Gert via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> > wrote:

Hi All,

 

Can anyone tell me how to get the template arguments from a clang::Type object? For example, if I have clang::Type for “std::vector<int>”, how do I get to this “int” type? 

 

When looking at the API reference I’m getting a bit lost with all the terminology I’m not yet familiar with, any good resources to that explains the terminology? Especially how templates are represented is still unclear to me.

 

Thanks in advanced for your help and a huge thanks to all the LLVM and clang contributes!

 

With Kind Regards,

Gert Massa

 

_______________________________________________
cfe-dev mailing list
cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> 
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20201222/f8922e72/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 12148 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20201222/f8922e72/attachment-0001.bin>


More information about the cfe-dev mailing list