Skip to content

Commit

Permalink
Improve deduction for dependent/pointer in parameters, see #369 com…
Browse files Browse the repository at this point in the history
…ment thread

1. For a constructor parameter when `T` is a template parameter on the class, pass `T const&` for CTAD deduction. We do that already for all functions when `T` is a template parameter on the function, for general deduction.

2. For a parameter `* <anything>`, pass `<anything> *` by value (not `in<>`). We know it's a pointer, and should be passed by value.
  • Loading branch information
hsutter committed May 21, 2023
1 parent e0125d7 commit c84bf47
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ auto try_pointer_stuff() -> void;


#line 21 "mixed-lifetime-safety-and-null-contracts.cpp2"
auto call_my_framework(cpp2::in<char const*> msg) -> void;
auto call_my_framework(char const* msg) -> void;


//=== Cpp2 function definitions =================================================
Expand All @@ -46,7 +46,7 @@ auto try_pointer_stuff() -> void{
// to show -n
}

auto call_my_framework(cpp2::in<char const*> msg) -> void{
auto call_my_framework(char const* msg) -> void{
std::cout
<< "sending error to my framework... ["
<< msg << "]\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class X {
class Y {
private: X* px;

public: explicit Y(cpp2::in<X*> x);
public: explicit Y(X* x);
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
public: auto operator=(cpp2::in<X*> x) -> Y& ;
public: auto operator=(X* x) -> Y& ;

public: auto why(cpp2::in<int> count) const -> void;

Expand Down Expand Up @@ -160,12 +160,12 @@ namespace N {
}

#line 49 "pure2-types-order-independence-and-nesting.cpp2"
Y::Y(cpp2::in<X*> x)
Y::Y(X* x)
: px{ x }
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
{ }
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
auto Y::operator=(cpp2::in<X*> x) -> Y& {
auto Y::operator=(X* x) -> Y& {
px = x;
return *this;
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
Expand Down
2 changes: 1 addition & 1 deletion regression-tests/test-results/version
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

cppfront compiler v0.2.1 Build 8521:0840
cppfront compiler v0.2.1 Build 8521:1217
Copyright(c) Herb Sutter All rights reserved

SPDX-License-Identifier: CC-BY-NC-ND-4.0
Expand Down
2 changes: 1 addition & 1 deletion source/build.info
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"8521:0840"
"8521:1217"
73 changes: 48 additions & 25 deletions source/cppfront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3852,36 +3852,50 @@ class cppfront

auto param_type = print_to_string(type_id);

// If there are template parameters, see if this parameter's name is an
// unqualified-id with a template parameter name, or mentions a template
// parameter as a template argument
auto is_dependent_parameter_type = false;
if (
current_declarations.back()
&& current_declarations.back()->template_parameters
// If there are template parameters on this function or its enclosing
// type, see if this parameter's name is an unqualified-id with a
// template parameter name, or mentions a template parameter as a
// template argument
auto has_template_parameter_type_named = [](
declaration_node const& decl,
std::string_view name
)
-> bool
{
for (auto& tparam : current_declarations.back()->template_parameters->parameters)
{
assert(
tparam
&& tparam->name()
);
// For now just do a quick string match
auto tparam_name = tparam->name()->to_string(true);
if (
tparam->declaration->is_type()
&& (
param_type == tparam_name
|| std::string_view{param_type}.find("<"+tparam_name) != std::string_view::npos
|| std::string_view{param_type}.find(","+tparam_name) != std::string_view::npos
)
)
if (decl.template_parameters) {
for (auto& tparam : decl.template_parameters->parameters)
{
is_dependent_parameter_type = true;
assert(
tparam
&& tparam->name()
);
// For now just do a quick string match
auto tparam_name = tparam->name()->to_string(true);
if (
tparam->declaration->is_type()
&& (
name == tparam_name
|| name.find("<"+tparam_name) != std::string_view::npos
|| name.find(","+tparam_name) != std::string_view::npos
)
)
{
return true;
}
}
}
}
return false;
};

assert( current_declarations.back() );
auto is_dependent_parameter_type =
has_template_parameter_type_named( *current_declarations.back(), param_type )
|| (
current_declarations.back()->parent_is_type()
&& current_declarations.back()->has_name("operator=")
&& has_template_parameter_type_named( *current_declarations.back()->get_parent(), param_type)
)
;

assert( n.declaration->identifier );
auto identifier = print_to_string( *n.declaration->identifier );
Expand All @@ -3891,6 +3905,7 @@ class cppfront
!is_returns
&& !type_id.is_wildcard()
&& !is_dependent_parameter_type
&& !type_id.is_pointer_qualified()
)
{
switch (n.pass) {
Expand All @@ -3903,6 +3918,13 @@ class cppfront
printer.preempt_position_push( n.position() );

if (
type_id.is_pointer_qualified()
&& n.pass == passing_style::in
)
{
printer.print_cpp2( print_to_string(type_id), n.position() );
}
else if (
type_id.is_wildcard()
|| is_dependent_parameter_type
)
Expand Down Expand Up @@ -3960,6 +3982,7 @@ class cppfront
!is_returns
&& !type_id.is_wildcard()
&& !is_dependent_parameter_type
&& !type_id.is_pointer_qualified()
)
{
switch (n.pass) {
Expand Down
6 changes: 6 additions & 0 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -2001,6 +2001,12 @@ struct declaration_node

// API
//
auto get_parent() const
-> declaration_node*
{
return parent_declaration;
}

auto is_public() const
-> bool
{
Expand Down
Loading

0 comments on commit c84bf47

Please sign in to comment.