Skip to content

Commit c6c2534

Browse files
committed
Enhance closure type demangling by appending count and refining template parameter handling
Add support for C++20 constraint expressions in closure type demangling
1 parent 7320e8c commit c6c2534

File tree

5 files changed

+65
-22
lines changed

5 files changed

+65
-22
lines changed

src/cplusplus/v3/ast.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ void DemNode_deinit(DemNode *xs) {
156156
if (xs->closure_ty_name.template_params) {
157157
DemNode_dtor(xs->closure_ty_name.template_params);
158158
}
159+
if (xs->closure_ty_name.requires1) {
160+
DemNode_dtor(xs->closure_ty_name.requires1);
161+
}
162+
if (xs->closure_ty_name.requires2) {
163+
DemNode_dtor(xs->closure_ty_name.requires2);
164+
}
159165
if (xs->closure_ty_name.params) {
160166
DemNode_dtor(xs->closure_ty_name.params);
161167
}
@@ -374,6 +380,8 @@ void DemNode_copy(DemNode *dst, const DemNode *src) {
374380
break;
375381
case CP_DEM_TYPE_KIND_CLOSURE_TY_NAME:
376382
dst->closure_ty_name.template_params = src->closure_ty_name.template_params ? DemNode_clone(src->closure_ty_name.template_params) : NULL;
383+
dst->closure_ty_name.requires1 = src->closure_ty_name.requires1 ? DemNode_clone(src->closure_ty_name.requires1) : NULL;
384+
dst->closure_ty_name.requires2 = src->closure_ty_name.requires2 ? DemNode_clone(src->closure_ty_name.requires2) : NULL;
377385
dst->closure_ty_name.params = src->closure_ty_name.params ? DemNode_clone(src->closure_ty_name.params) : NULL;
378386
dst->closure_ty_name.count = src->closure_ty_name.count; // DemStringView, shallow copy
379387
break;

src/cplusplus/v3/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ typedef struct {
237237

238238
typedef struct {
239239
PDemNode template_params;
240+
PDemNode requires1, requires2;
240241
PDemNode params;
241242
DemStringView count;
242243
} ClosureTyName;

src/cplusplus/v3/v3.c

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -906,25 +906,36 @@ void ast_pp(DemNode *node, DemString *out, PPContext *ctx) {
906906
}
907907
break;
908908

909-
case CP_DEM_TYPE_KIND_CLOSURE_TY_NAME:
910-
// Closure types are lambda expressions: 'lambda'(params)#count
909+
case CP_DEM_TYPE_KIND_CLOSURE_TY_NAME: {
910+
// Closure types are lambda expressions: 'lambda[count]'<template_params> [ requires expr ] (params) [ requires expr ]
911+
const ClosureTyName *ctn = &node->closure_ty_name;
911912
dem_string_append(out, "'lambda");
912-
if (node->closure_ty_name.template_params && node->closure_ty_name.template_params->children) {
913+
if (ctn->count.buf && ctn->count.len > 0) {
914+
dem_string_append_sv(out, ctn->count);
915+
}
916+
dem_string_append(out, "'");
917+
918+
if (ctn->template_params && ctn->template_params->children) {
913919
dem_string_append(out, "<");
914920
ast_pp(node->closure_ty_name.template_params, out, ctx);
915921
dem_string_append(out, ">");
916922
}
917-
dem_string_append(out, "'(");
923+
if (ctn->requires1) {
924+
dem_string_append(out, " requires ");
925+
ast_pp(ctn->requires1, out, ctx);
926+
}
927+
928+
print_open(out, ctx);
918929
if (node->closure_ty_name.params) {
919930
ast_pp(node->closure_ty_name.params, out, ctx);
920931
}
921-
dem_string_append(out, ")");
922-
if (node->closure_ty_name.count.buf && node->closure_ty_name.count.len > 0) {
923-
dem_string_append(out, "#");
924-
dem_string_append_n(out, node->closure_ty_name.count.buf, node->closure_ty_name.count.len);
932+
print_close(out, ctx);
933+
if (ctn->requires2) {
934+
dem_string_append(out, " requires ");
935+
ast_pp(ctn->requires2, out, ctx);
925936
}
926937
break;
927-
938+
}
928939
case CP_DEM_TYPE_KIND_TYPE: {
929940
// Check if this is a function pointer (or pointer/reference/qualified wrapping a function pointer)
930941
DemNode *func_node = NULL;
@@ -3187,7 +3198,7 @@ bool rule_template_arg(DemParser *p, DemResult *r) {
31873198
if (!is_template_param_decl(p)) {
31883199
RETURN_SUCCESS_OR_FAIL(CALL_RULE_REPLACE_NODE(rule_type));
31893200
}
3190-
DEM_UNREACHABLE;
3201+
RETURN_SUCCESS_OR_FAIL(CALL_RULE_REPLACE_NODE(rule_template_param_decl));
31913202
}
31923203
default:
31933204
RETURN_SUCCESS_OR_FAIL(CALL_RULE_REPLACE_NODE(rule_type));
@@ -3238,7 +3249,14 @@ bool rule_template_args_ex(DemParser *p, DemResult *r, bool tag_templates) {
32383249
}
32393250
Node_append(many_node, arg);
32403251
if (READ('Q')) {
3241-
DEM_UNREACHABLE;
3252+
// C++20 constraint expression attached to the template argument.
3253+
// Minimal support: parse it as an expression and ignore it.
3254+
// (Pretty-printing a per-argument constraint isn't currently supported.)
3255+
PDemNode constraint_expr = NULL;
3256+
if (!(CALL_RULE_N(constraint_expr, rule_expression) && READ('E'))) {
3257+
TRACE_RETURN_FAILURE();
3258+
}
3259+
DemNode_dtor(constraint_expr);
32423260
}
32433261
}
32443262
many_node->many_ty.sep = ", ";
@@ -3320,21 +3338,35 @@ bool rule_unnamed_type_name(DemParser *p, DemResult *r) {
33203338
TRACE_RETURN_SUCCESS;
33213339
}
33223340
if (READ_STR("Ul")) {
3323-
while (is_template_param_decl(p)) {
3324-
// TODO: Handle template_param_decl
3325-
DEM_UNREACHABLE;
3341+
// Ul <template-param-decl>* [Q <constraint-expr> E] <lambda-sig> [Q <constraint-expr> E] E <number> _
3342+
PDemNode template_params = NULL;
3343+
if (is_template_param_decl(p)) {
3344+
if (!CALL_MANY1_N(template_params, rule_template_param_decl, ", ", '\0')) {
3345+
TRACE_RETURN_FAILURE();
3346+
}
3347+
}
3348+
if (template_params && VecPDemNode_empty(template_params->children)) {
3349+
VecPNodeList_pop(&p->template_params);
33263350
}
3351+
3352+
PDemNode requires1 = NULL;
33273353
if (READ('Q')) {
3328-
// TODO: Handle ConstraintExpr
3329-
DEM_UNREACHABLE;
3354+
// C++20 constraint expression (templated lambda) - minimal support: parse & ignore.
3355+
MUST_MATCH(CALL_RULE_N(requires1, rule_expression) && READ('E'));
3356+
if (!requires1) {
3357+
TRACE_RETURN_FAILURE();
3358+
}
33303359
}
33313360
DemNode *params = NULL;
33323361
if (!READ('v')) {
3333-
CALL_MANY1_N(params, rule_type, ", ", 'E');
3362+
CALL_MANY1_N(params, rule_type, ", ", '\0');
33343363
}
3364+
PDemNode requires2 = NULL;
33353365
if (READ('Q')) {
3336-
// TODO: Handle ConstraintExpr
3337-
DEM_UNREACHABLE;
3366+
MUST_MATCH(CALL_RULE_N(requires2, rule_expression) && READ('E'));
3367+
if (!requires2) {
3368+
TRACE_RETURN_FAILURE();
3369+
}
33383370
}
33393371
if (!READ('E')) {
33403372
TRACE_RETURN_FAILURE();
@@ -3346,7 +3378,10 @@ bool rule_unnamed_type_name(DemParser *p, DemResult *r) {
33463378
TRACE_RETURN_FAILURE();
33473379
}
33483380
node->tag = CP_DEM_TYPE_KIND_CLOSURE_TY_NAME;
3381+
node->closure_ty_name.template_params = template_params;
33493382
node->closure_ty_name.params = params;
3383+
node->closure_ty_name.requires1 = requires1;
3384+
node->closure_ty_name.requires2 = requires2;
33503385
TRACE_RETURN_SUCCESS;
33513386
}
33523387
RULE_FOOT(unnamed_type_name);

test/data/cxx_method.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13387,7 +13387,7 @@ _ZN5clang16CompilerInstance23createDefaultOutputFileEbN4llvm9StringRefES2_,"clan
1338713387
_ZN12FilteredView5matchERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7__ptr,"FilteredView::match(std::string const&, std::string const&)"
1338813388
_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ptr,std::stringbuf::str() const
1338913389
_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcmm_ptr,"std::stringbuf::_M_sync(char*, unsigned long, unsigned long)"
13390-
_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ptr,std::ios::init(std::streambuf*)
13390+
_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ptr,"std::ios::init(std::basic_streambuf<char, std::char_traits<char>>*)"
1339113391
_ZNKSt7__cxx1111basic_regexIcNS_12regex_traitsIcEEE5flagsEv,std::regex::flags() const
1339213392
_ZNSt7__cxx1111basic_regexIcNS_12regex_traitsIcEEE10_M_compileEPKcS5_NSt15regex_constants18syntax_option_typeE,"std::regex::_M_compile(char const*, char const*, std::regex_constants::syntax_option_type)"
1339313393
_ZZN12_GLOBAL__N_115ARMDAGToDAGISel6SelectEPN4llvm6SDNodeEE7Opcodes8,(anonymous namespace)::ARMDAGToDAGISel::Select(llvm::SDNode*)::Opcodes

test/data/cxx_operator.csv

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ _ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE,void test19::g<test19::A>(test19::S<
303303
_ZSteqIcEN9__gnu_cxx11__enable_ifIXsr9__is_charIT_EE7__valueEbE6__typeERKSbIS2_St11char_traitsIS2_ESaIS2_EESA_,"__gnu_cxx::__enable_if<__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)"
304304
_ZN5clang11LangOptionsaSERKS0_,clang::LangOptions::operator=(clang::LangOptions const&)
305305
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc,"std::basic_ostream<char, std::char_traits<char>>& std::operator<<<std::char_traits<char>>(std::basic_ostream<char, std::char_traits<char>>&, char const*)"
306-
_ZNSolsEPSt15basic_streambufIcSt11char_traitsIcEE_ptr,std::ostream::operator<<(std::streambuf*)
307-
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ptr,"std::ostream& std::operator<< <std::char_traits<char>>(std::ostream&, char const*)"
306+
_ZNSolsEPSt15basic_streambufIcSt11char_traitsIcEE_ptr,"std::ostream::operator<<(std::basic_streambuf<char, std::char_traits<char>>*)"
308307
_ZNK3Ncr6Silver7Utility6detail12CallOnThreadIZ53-[DeploymentSetupController handleManualServerEntry:]E3$_5EclIJEEEDTclclL_ZNS2_4getTIS4_EERT_vEEspclsr3stdE7forwardIT_Efp_EEEDpOSA_,decltype(-[DeploymentSetupController handleManualServerEntry:]::$_5& Ncr::Silver::Utility::detail::getT<-[DeploymentSetupController handleManualServerEntry:]::$_5>()()()) Ncr::Silver::Utility::detail::CallOnThread<-[DeploymentSetupController handleManualServerEntry:]::$_5>::operator()<>() const
309308
_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE,void test19::g<test19::A>(test19::S<&test19::A::operator int>)
310309
_ZZN4NIds4NStr14TCStrAggregateINS0_13TCTCStrTraitsINS0_11TCStrTraitsIcNS0_17CDefaultStrParamsEEENS0_14TCStrImp_FixedIS5_Lx256EEEEEE21f_AddFromIteratorUTF8INS0_16CStrIteratorUTF8EEEvRxRKT_ENKSA_ISB_EUlmE0_clEm,"void NIds::NStr::TCStrAggregate<NIds::NStr::TCTCStrTraits<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, NIds::NStr::TCStrImp_Fixed<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, 256ll>>>::f_AddFromIteratorUTF8<NIds::NStr::CStrIteratorUTF8>(long long&, NIds::NStr::CStrIteratorUTF8 const&)::NIds::NStr::TCStrAggregate<NIds::NStr::TCTCStrTraits<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, NIds::NStr::TCStrImp_Fixed<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, 256ll>>>::f_AddFromIteratorUTF8<NIds::NStr::CStrIteratorUTF8>::'lambda0'(unsigned long)::operator()(unsigned long) const"

0 commit comments

Comments
 (0)