@@ -89,39 +89,103 @@ using Func = void(T, const U&);
8989TEST (Rewriter, Var) {
9090 auto source = R"(
9191template <int i>
92- const int c = i + 321;
92+ const int c = i + 321 + i ;
9393
94- constexpr int x = 123;
94+ constexpr int x = 123 * 2;
95+
96+ constexpr auto y = c<123 * 2>;
9597
9698)" _cxx;
9799
100+ auto interp = ASTInterpreter{&source.unit };
101+
98102 auto control = source.control ();
99103
100104 auto c = source.getAs <VariableSymbol>(" c" );
101105 ASSERT_TRUE (c != nullptr );
102106 auto templateDeclaration = c->templateDeclaration ();
103107 ASSERT_TRUE (templateDeclaration != nullptr );
104108
109+ // extract the expression 123 * 2 from the AST
105110 auto x = source.getAs <VariableSymbol>(" x" );
106111 ASSERT_TRUE (x != nullptr );
107- auto xinit = x->initializer ();
112+ auto xinit = ast_cast<EqualInitializerAST>( x->initializer ())-> expression ;
108113 ASSERT_TRUE (xinit != nullptr );
109114
115+ // synthesize const auto i = 123 * 2;
116+
117+ // ### need to set scope and location
118+ auto templArg = control->newVariableSymbol (nullptr , {});
119+ templArg->setInitializer (xinit);
120+ templArg->setType (control->add_const (x->type ()));
121+ templArg->setConstValue (interp.evaluate (xinit));
122+ ASSERT_TRUE (templArg->constValue ().has_value ());
123+
110124 auto instance = subst (
111125 source, getTemplateBodyAs<SimpleDeclarationAST>(templateDeclaration),
112- {xinit });
126+ {templArg });
113127
114128 auto decl = instance->initDeclaratorList ->value ;
115129 ASSERT_TRUE (decl != nullptr );
116130
117131 auto init = ast_cast<EqualInitializerAST>(decl->initializer );
118132 ASSERT_TRUE (init);
119133
120- ASTInterpreter interp{&source.unit };
121-
122134 auto value = interp.evaluate (init->expression );
123135
124136 ASSERT_TRUE (value.has_value ());
125137
126- ASSERT_EQ (std::visit (ArithmeticCast<int >{}, *value), 123 + 321 );
138+ ASSERT_EQ (std::visit (ArithmeticCast<int >{}, *value), 123 * 2 + 321 + 123 * 2 );
139+
140+ #if false
141+ auto y = source.getAs <VariableSymbol>(" y" );
142+ ASSERT_TRUE (y != nullptr );
143+ auto yinit = ast_cast<EqualInitializerAST>(y->initializer ())->expression ;
144+ ASSERT_TRUE (yinit != nullptr );
145+
146+ auto idExpr = ast_cast<IdExpressionAST>(yinit);
147+ ASSERT_TRUE (idExpr != nullptr );
148+
149+ ASSERT_TRUE (idExpr->symbol );
150+
151+ auto templateId = ast_cast<SimpleTemplateIdAST>(idExpr->unqualifiedId );
152+ ASSERT_TRUE (templateId != nullptr );
153+
154+ // get the primary template declaration
155+ ASSERT_EQ (templateId->primaryTemplateSymbol , c);
156+ auto xx = symbol_cast<VariableSymbol>(templateId->primaryTemplateSymbol );
157+ ASSERT_TRUE (xx != nullptr );
158+ auto xxTemplDecl =
159+ getTemplateBodyAs<SimpleDeclarationAST>(xx->templateDeclaration ());
160+ ASSERT_TRUE (xxTemplDecl != nullptr );
161+
162+ ASSERT_EQ (getTemplateBodyAs<SimpleDeclarationAST>(templateDeclaration),
163+ xxTemplDecl);
164+
165+ std::vector<TemplateArgument> templateArguments;
166+ for (auto arg : ListView{templateId->templateArgumentList }) {
167+ if (auto expr = ast_cast<ExpressionAST>(arg)) {
168+ // ### need to set scope and location
169+ auto templArg = control->newVariableSymbol (nullptr , {});
170+ templArg->setInitializer (xinit);
171+ templArg->setType (control->add_const (expr->type ));
172+ templArg->setConstValue (interp.evaluate (expr));
173+ ASSERT_TRUE (templArg->constValue ().has_value ());
174+ templateArguments.push_back (templArg);
175+ }
176+ }
177+
178+ auto instance2 = subst (source, xxTemplDecl, templateArguments);
179+
180+ ASSERT_TRUE (instance2 != nullptr );
181+
182+ auto decl2 = instance2->initDeclaratorList ->value ;
183+ ASSERT_TRUE (decl2 != nullptr );
184+ auto init2 = ast_cast<EqualInitializerAST>(decl2->initializer );
185+ ASSERT_TRUE (init2 != nullptr );
186+ auto value2 = interp.evaluate (init2->expression );
187+ ASSERT_TRUE (value2.has_value ());
188+ ASSERT_EQ (std::visit (ArithmeticCast<int >{}, *value2),
189+ 123 * 2 + 321 + 123 * 2 );
190+ #endif
127191}
0 commit comments