I’m looking to get value of default parameter for templated functions/methods – clang for some reason doesn’t export this information in expected way (VarDecl::getInitExpr() in specialization declaration)
For example, look at AST for following code (-ast-dump below):
template void default_int(int a = 0) {}
template void default_T(T a = T(0)) {}
void test() {
default_int();
default_T();
}
None of the template specializations have any information about default argument.
- For default_int it’s not a big deal – we can read that information from FunctionTemplateDecl and apply it to all specializations
- For default_T problem is harder – parameter in FunctionTemplateDecl will have CXXUnresolvedConstructExpr as init expression which is not so useful. I imagine clang already resolves that ConstructExpr, but it’s not put to ParmVarDecl.
Question:
Is there general way of accessing default parameter value for both cases (1) and (2)? Is there any reason why it’s not initExpr of ParmVarDecl?
clang -c default.cpp -Xclang -ast-dump
TranslationUnitDecl 0x103030cc0 <>
-TypedefDecl 0x103031200 <> implicit __int128_t ‘__int128’
-TypedefDecl 0x103031260 <> implicit __uint128_t ‘unsigned __int128’
-TypedefDecl 0x103031660 <> implicit __builtin_va_list ‘__va_list_tag [1]’
-FunctionTemplateDecl 0x103031900 <default.cpp:1:1, col:48> col:24 default_int-TemplateTypeParmDecl 0x1030316b0 <col:10, col:16> col:16 class T
-FunctionDecl 0x103031850 <col:19, col:48> col:24 default_int ‘void (int)’-ParmVarDecl 0x103031770 <col:36, col:44> col:40 a ‘int’ cinit
-IntegerLiteral 0x1030317d0 <col:44> 'int' 0
-CompoundStmt 0x103031958 <col:47, col:48>
-FunctionDecl 0x103072c00 <col:19, col:48> col:24 used default_int 'void (int)' -TemplateArgument type 'int' -ParmVarDecl 0x103072b70 <col:36, col:44> col:40 a 'int'
-CompoundStmt 0x103031958 <col:47, col:48>
-FunctionTemplateDecl 0x103072810 <line:2:1, col:47> col:24 default_T
-TemplateTypeParmDecl 0x103031970 <col:10, col:16> col:16 referenced class T
-FunctionDecl 0x103072760 <col:19, col:47> col:24 default_T ‘void (T)’
-ParmVarDecl 0x103072600 <col:34, col:43> col:36 a ‘T’ cinit
-CXXUnresolvedConstructExpr 0x103072690 <col:40, col:43> 'T'
-IntegerLiteral 0x103072670 col:42 ‘int’ 0
-CompoundStmt 0x103072868 <col:46, col:47>
-FunctionDecl 0x103073140 <col:19, col:47> col:24 used default_T ‘void (int)’
-TemplateArgument type ‘int’
-ParmVarDecl 0x103073080 <col:34, col:43> col:36 a ‘int’:‘int’
-CompoundStmt 0x103072868 <col:46, col:47>
-FunctionDecl 0x1030728d0 <line:3:1, line:6:1> line:3:6 test ‘void (void)’
-CompoundStmt 0x1030733a8 <col:13, line:6:1> -CallExpr 0x103072dd0 <line:4:3, col:20> 'void' -ImplicitCastExpr 0x103072db8 <col:3, col:18> 'void (*)(int)' <FunctionToPointerDecay>
-DeclRefExpr 0x103072d10 <col:3, col:18> ‘void (int)’ lvalue Function 0x103072c00 ‘default_int’ ‘void (int)’ (FunctionTemplate 0x103031900 ‘default_int’)
-CXXDefaultArgExpr 0x103072e08 <<invalid sloc>> 'int'
-CallExpr 0x103073310 <line:5:3, col:18> ‘void’
-ImplicitCastExpr 0x1030732f8 <col:3, col:16> ‘void (*)(int)’
-DeclRefExpr 0x103073250 <col:3, col:16> 'void (int)' lvalue Function 0x103073140 'default_T' 'void (int)' (FunctionTemplate 0x103072810 'default_T')
-CXXDefaultArgExpr 0x103073380 <> ‘int’:‘int’