Skip to content

Commit 9132abc

Browse files
committed
Add support for pointer deduce type
1 parent be63722 commit 9132abc

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

source/cppfront.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,32 @@ class cppfront
15551555
}
15561556

15571557

1558+
//-----------------------------------------------------------------------
1559+
//
1560+
auto is_it_pointer_declaration(declaration_sym const* decl, int deref_cnt = 0, int addr_cnt = 0) -> bool {
1561+
if (!decl || !decl->declaration)
1562+
return false;
1563+
if (addr_cnt>deref_cnt)
1564+
return true;
1565+
1566+
if (decl->declaration->dereference) {
1567+
auto deref = sema.get_declaration_of(*decl->declaration->dereference);
1568+
return is_it_pointer_declaration(deref, deref_cnt+decl->declaration->dereference_cnt, addr_cnt);
1569+
} else if (decl->declaration->address_of) {
1570+
auto addr = sema.get_declaration_of(*decl->declaration->address_of);
1571+
return is_it_pointer_declaration(addr, deref_cnt, addr_cnt+1);
1572+
}
1573+
1574+
int pointer_declarators_cnt = 0;
1575+
if (auto* obj_id_expr = std::get_if<declaration_node::object>(&decl->declaration->type)) {
1576+
if (auto* unqual = std::get_if<id_expression_node::unqualified>(&(*obj_id_expr)->id)){
1577+
pointer_declarators_cnt = std::ssize((*unqual)->pointer_declarators);
1578+
}
1579+
}
1580+
1581+
return (pointer_declarators_cnt + addr_cnt - deref_cnt) > 0;
1582+
};
1583+
15581584
//-----------------------------------------------------------------------
15591585
//
15601586
auto emit(postfix_expression_node& n, bool for_lambda_capture = false) -> void
@@ -1588,7 +1614,7 @@ class cppfront
15881614

15891615
// TODO: Generalize this -- for now we detect only multi-level cases of the form "p: ***int = ...;"
15901616
// We don't recognize pointer types that are deduced or from Cpp1
1591-
if (!unqual->pointer_declarators.empty() || is_pointer) {
1617+
if (is_it_pointer_declaration(decl) || !unqual->pointer_declarators.empty() || is_pointer) {
15921618
if (n.ops.empty()) {
15931619
last_postfix_expr_was_pointer = true;
15941620
}

source/parse.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,10 @@ struct declaration_node
847847
source_position pos;
848848
std::unique_ptr<unqualified_id_node> identifier;
849849

850+
token const* dereference = nullptr;
851+
int dereference_cnt = 0;
852+
token const* address_of = nullptr;
853+
850854
enum active { function, object };
851855
std::variant<
852856
std::unique_ptr<function_type_node>,
@@ -2872,6 +2876,18 @@ class parser
28722876
}
28732877
}
28742878

2879+
if (deduced_type) {
2880+
if (peek(1)->type() == lexeme::Ampersand) {
2881+
n->address_of = &curr();
2882+
} else if (peek(1)->type() == lexeme::Multiply) {
2883+
n->dereference = &curr();
2884+
n->dereference_cnt = 1;
2885+
while(peek(n->dereference_cnt+1)->type() == lexeme::Multiply) {
2886+
n->dereference_cnt += 1;
2887+
}
2888+
}
2889+
}
2890+
28752891
if (!(n->initializer = statement(semicolon_required, n->equal_sign))) {
28762892
error("ill-formed initializer");
28772893
next();

0 commit comments

Comments
 (0)