Skip to content

Commit 0c30349

Browse files
committed
fix(cpp1): emit template for dependent _template-id_
1 parent 4569d75 commit 0c30349

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

regression-tests/pure2-optional-typename.cpp2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ f: <T, V: T::value_type> (x: T::value_type) -> T::value_type = {
1010
_ = :identity<T>::value_type = (); // First identifier.
1111
_ = :std::optional<T>::value_type = (); // Non-first identifier.
1212

13+
// Emitted `template`.
14+
ptr: type == * T; // Needed, pending #502.
15+
type: type == std::pointer_traits<ptr>::rebind<ptr>; // Type-only context.
16+
_ = :std::pointer_traits<ptr>::rebind<ptr> = (); // Non type-only context.
17+
1318
// Aliases.
1419
w: type == T;
1520
_ = :w::value_type = x;

regression-tests/test-results/pure2-optional-typename.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ template<typename T> using identity = T;
1515
template<typename T, typename T::value_type V> [[nodiscard]] auto f(cpp2::in<typename T::value_type> x) -> typename T::value_type;
1616

1717

18-
#line 31 "pure2-optional-typename.cpp2"
18+
#line 36 "pure2-optional-typename.cpp2"
1919
auto main() -> int;
2020

2121

@@ -34,6 +34,11 @@ template<typename T, typename T::value_type V> [[nodiscard]] auto f(cpp2::in<typ
3434
(void) typename identity<T>::value_type{};// First identifier.
3535
(void) typename std::optional<T>::value_type{};// Non-first identifier.
3636

37+
// Emitted `template`.
38+
using ptr = T*; // Needed, pending #502.
39+
using type = typename std::pointer_traits<ptr>::template rebind<ptr>;// Type-only context.
40+
(void) typename std::pointer_traits<ptr>::template rebind<ptr>{};// Non type-only context.
41+
3742
// Aliases.
3843
using w = T;
3944
(void) typename w::value_type{x};

source/cppfront.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,8 @@ class cppfront
16141614
unqualified_id_node const& n,
16151615
bool in_synthesized_multi_return = false,
16161616
bool is_local_name = true,
1617-
bool is_qualified = false
1617+
bool is_qualified = false,
1618+
bool can_emit_template_keyword = false
16181619
)
16191620
-> void
16201621
{
@@ -1663,6 +1664,10 @@ class cppfront
16631664
printer.print_cpp2("CPP2_FORWARD(", {n.position().lineno, n.position().colno - 8});
16641665
}
16651666

1667+
if (can_emit_template_keyword && n.open_angle != source_position{}) {
1668+
printer.print_cpp2("template ", n.position());
1669+
}
1670+
16661671
assert(n.identifier);
16671672
emit(*n.identifier, is_qualified); // inform the identifier if we know this is qualified
16681673

@@ -1755,7 +1760,7 @@ class cppfront
17551760
auto guard = finally([&]{ looking_up.pop_back(); });
17561761

17571762
// If any parent declaration
1758-
return std::any_of(current_declarations.begin() + 1, current_declarations.end(), [&](declaration_node const* decl) {
1763+
return std::any_of(current_declarations.rbegin(), current_declarations.rend() - 1, [&](declaration_node const* decl) {
17591764
// that can have aliases
17601765
if ((decl->is_function()
17611766
|| decl->is_type()
@@ -1765,7 +1770,7 @@ class cppfront
17651770
{
17661771
auto& stmts = decl->initializer->get_if<compound_statement_node>()->statements;
17671772
// among its statements
1768-
return std::any_of(stmts.begin(), stmts.end(), [&](decltype(stmts.front())& stmt) {
1773+
return std::any_of(stmts.rbegin(), stmts.rend(), [&](decltype(stmts.front())& stmt) {
17691774
if (auto decl = stmt->get_if<declaration_node>();
17701775
decl
17711776
&& decl->is_alias()) {
@@ -1886,12 +1891,16 @@ class cppfront
18861891
printer.print_cpp2("typename ", n.position());
18871892
}
18881893

1894+
auto can_emit_template_keyword = false;
18891895
for (auto const& id : n.ids)
18901896
{
18911897
if (id.scope_op) {
18921898
emit(*id.scope_op);
18931899
}
1894-
emit(*id.id, false, true, true); // inform the unqualified-id that it's qualified
1900+
emit(*id.id, false, true, true, can_emit_template_keyword); // inform the unqualified-id that it's qualified
1901+
if (!can_emit_template_keyword && this->is_dependent(*id.id)) {
1902+
can_emit_template_keyword = true;
1903+
}
18951904
}
18961905

18971906
printer.emit_to_string();

0 commit comments

Comments
 (0)