Observation: Clang AST don’t contain any template specialisation if a header file is missing. It is true even when the template got nothing to do with the header file.
For example,
#include "unknown_header.h"
template<class T>
T add(T x, T y) {return x + y;}
void sum(void)
{
add<double>(5.0, 6.0);
}
generate the FunctionTemplateDecl
instance, which doesn’t contain specialisation for type double
.
But if we get rid of “unknown_header.h”, resulting in successful compilation, we can see the specialisation using type double. The specialisation can be seen below after removing the header.
|-FunctionTemplateDecl 0x55ec327d83e8 <tmp.cpp:1:1, line:2:31> col:3 add
| |-TemplateTypeParmDecl 0x55ec327d80f0 <line:1:10, col:16> col:16 referenced class depth 0 index 0 T
| |-FunctionDecl 0x55ec327d8348 <line:2:1, col:31> col:3 add 'T (T, T)'
| | |-ParmVarDecl 0x55ec327d81c0 <col:7, col:9> col:9 referenced x 'T'
| | |-ParmVarDecl 0x55ec327d8238 <col:12, col:14> col:14 referenced y 'T'
| | `-CompoundStmt 0x55ec327d8580 <col:17, col:31>
| | `-ReturnStmt 0x55ec327d8570 <col:18, col:29>
| | `-BinaryOperator 0x55ec327d8550 <col:25, col:29> '<dependent type>' '+'
| | |-DeclRefExpr 0x55ec327d8510 <col:25> 'T' lvalue ParmVar 0x55ec327d81c0 'x' 'T'
| | `-DeclRefExpr 0x55ec327d8530 <col:29> 'T' lvalue ParmVar 0x55ec327d8238 'y' 'T'
| `-FunctionDecl 0x55ec327d8ae8 <col:1, col:31> col:3 used add 'double (double, double)'
| |-TemplateArgument type 'double'
| | `-BuiltinType 0x55ec327923c0 'double'
| |-ParmVarDecl 0x55ec327d8960 <col:7, col:9> col:9 used x 'double':'double'
| |-ParmVarDecl 0x55ec327d89d8 <col:12, col:14> col:14 used y 'double':'double'
| `-CompoundStmt 0x55ec327d8da8 <col:17, col:31>
| `-ReturnStmt 0x55ec327d8d98 <col:18, col:29>
| `-BinaryOperator 0x55ec327d8d78 <col:25, col:29> 'double' '+'
| |-ImplicitCastExpr 0x55ec327d8d48 <col:25> 'double':'double' <LValueToRValue>
| | `-DeclRefExpr 0x55ec327d8d08 <col:25> 'double':'double' lvalue ParmVar 0x55ec327d8960 'x' 'double':'double'
| `-ImplicitCastExpr 0x55ec327d8d60 <col:29> 'double':'double' <LValueToRValue>
| `-DeclRefExpr 0x55ec327d8d28 <col:29> 'double':'double' lvalue ParmVar 0x55ec327d89d8 'y' 'double':'double'
Question: What stops clang from generating the template specialisation if the header is missing?