@@ -201,6 +201,68 @@ auto ASTRewriter::instantiateTypeAliasTemplate(
201
201
return instance->symbol ;
202
202
}
203
203
204
+ auto ASTRewriter::instantiateVariableTemplate (
205
+ TranslationUnit* unit, List<TemplateArgumentAST*>* templateArgumentList,
206
+ VariableSymbol* variableSymbol) -> VariableSymbol* {
207
+ auto templateDecl = variableSymbol->templateDeclaration ();
208
+
209
+ if (!templateDecl) {
210
+ unit->error (variableSymbol->location (), " not a template" );
211
+ return nullptr ;
212
+ }
213
+
214
+ auto variableDeclaration =
215
+ ast_cast<SimpleDeclarationAST>(templateDecl->declaration );
216
+
217
+ if (!variableDeclaration) return nullptr ;
218
+
219
+ auto templateArguments =
220
+ make_substitution (unit, templateDecl, templateArgumentList);
221
+
222
+ auto is_primary_template = [&]() -> bool {
223
+ int expected = 0 ;
224
+ for (const auto & arg : templateArguments) {
225
+ if (!std::holds_alternative<Symbol*>(arg)) return false ;
226
+
227
+ auto ty = type_cast<TypeParameterType>(std::get<Symbol*>(arg)->type ());
228
+ if (!ty) return false ;
229
+
230
+ if (ty->index () != expected) return false ;
231
+ ++expected;
232
+ }
233
+ return true ;
234
+ };
235
+
236
+ if (is_primary_template ()) {
237
+ // if this is a primary template, we can just return the class symbol
238
+ return variableSymbol;
239
+ }
240
+
241
+ auto subst = variableSymbol->findSpecialization (templateArguments);
242
+ if (subst) {
243
+ return subst;
244
+ }
245
+
246
+ auto parentScope = variableSymbol->parent ();
247
+ while (parentScope->isTemplateParameters ()) {
248
+ parentScope = parentScope->parent ();
249
+ }
250
+
251
+ auto rewriter = ASTRewriter{unit, parentScope, templateArguments};
252
+
253
+ rewriter.binder ().setInstantiatingSymbol (variableSymbol);
254
+
255
+ auto instance =
256
+ ast_cast<SimpleDeclarationAST>(rewriter.declaration (variableDeclaration));
257
+
258
+ if (!instance) return nullptr ;
259
+
260
+ auto instantiatedSymbol = instance->initDeclaratorList ->value ->symbol ;
261
+ auto instantiatedVariable = symbol_cast<VariableSymbol>(instantiatedSymbol);
262
+
263
+ return instantiatedVariable;
264
+ }
265
+
204
266
auto ASTRewriter::make_substitution (
205
267
TranslationUnit* unit, TemplateDeclarationAST* templateDecl,
206
268
List<TemplateArgumentAST*>* templateArgumentList)
0 commit comments