[cfe-dev] AST for DeclRefExpr of NonTypeTemplateParm

Mikhail Ramalho via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 27 10:09:37 PDT 2016

Hi all,

I'm trying to parse a C++ program that uses templates but I'm having some
trouble with the generated AST.

The program:

template <const char *N>
struct A { static const char *p; };

template <const char *N>
const char *A<N>::p = N;

int main()
  A<B::c> a;
  return 0;

The generated AST is:

|-ClassTemplateDecl 0x450f720
line:6:34> col:8 A
| |-NonTypeTemplateParmDecl 0x450f620 <line:5:11, col:23> col:23 'const
char *' N
| |-CXXRecordDecl 0x450f690 <line:6:1, col:34> col:8 struct A definition
| | |-CXXRecordDecl 0x450f9b8 <col:1, col:8> col:8 implicit struct A
| | `-VarDecl 0x450fa58 <col:12, col:31> col:31 p 'const char *' static
| `-ClassTemplateSpecializationDecl 0x4516a30 <line:5:1, line:6:34> col:8
struct A definition
|   |-TemplateArgument decl
|   | `-Var 0x4516818 'c' 'const char [1]'
|   |-CXXRecordDecl 0x4516c98 prev 0x4516a30 <col:1, col:8> col:8 implicit
struct A
|   |-VarDecl 0x4516d28 <col:12, col:31> col:31 p 'const char *' static
|   |-CXXConstructorDecl 0x4516db8 <col:8> col:8 implicit used A 'void
(void) throw()' inline
|   | `-CompoundStmt 0x4517100 <col:8>
|   `-CXXConstructorDecl 0x4516f18 <col:8> col:8 implicit A 'void (const
struct A<&B::c> &)' inline noexcept-unevaluated 0x4516f18
|     `-ParmVarDecl 0x4517060 <col:8> col:8 'const struct A<&B::c> &'
*|-VarDecl 0x450fdc0 parent 0x450f690 prev 0x450fa58 <line:10:1,
line:11:23> col:19 p 'const char *' cinit*
*| `-DeclRefExpr 0x450fe60 <col:23> 'const char *' NonTypeTemplateParm
0x450fb38 'N' 'const char *'*
|-CXXRecordDecl 0x450fe88 <line:27:1, line:30:1> line:27:8 struct B
| |-CXXRecordDecl 0x450ffa0 <col:1, col:8> col:8 implicit struct B
| `-VarDecl 0x4516818 <line:29:3, col:24> col:21 used c 'const char [1]'
`-FunctionDecl 0x45168d0 <line:33:1, line:44:1> line:33:5 main 'int (void)'
  `-CompoundStmt 0x4517160 <line:34:1, line:44:1>
    `-DeclStmt 0x4517148 <line:35:3, col:12>
      `-VarDecl 0x4516bd8 <col:3, col:11> col:11 a 'A<struct B::c>':'struct
A<&B::c>' callinit
        `-CXXConstructExpr 0x4517118 <col:11> 'A<struct B::c>':'struct
A<&B::c>' 'void (void) throw()'

Which is quite simple, but I'm having trouble getting the instantiated
varDecl. Does anyone knows:

1. How can I ignore any non instantiated varDecl?

I tried to check getTemplateSpecializationKind() but it always returns
TSK_Undeclared. I also tried to check all redecls() but it only shows:

VarDecl 0x3182ce0 parent 0x31825b0 prev 0x3182978
line:11:23> col:19 p 'const char *' cinit
`-DeclRefExpr 0x3182d80 <col:23> 'const char *' NonTypeTemplateParm
0x3182a58 'N' 'const char *'

VarDecl 0x3182978
col:31> col:31 p 'const char *' static

I tried to cast the VarDecl to TemplateDecl, but also without succes.

2. How can I get the instantiated VarDecl? (Actually, the opposite of the
first question).

I mean, somewhere there must be a VarDecl with
a SubstNonTypeTemplateParmExpr, right?

3. Is it possible to generate the AST without any template? I'm only
interested in the instantiated templates. It seems a long shot, but who

Thank you,


Mikhail Ramalho.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160427/d6b9f789/attachment.html>

More information about the cfe-dev mailing list