From 04bcc9125e0b227aa91b7bd8819d49aafddfd228 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 6 May 2024 22:32:46 +0200 Subject: [PATCH] C++ front-end: parse template parameter packs Attach the "ellipsis" information to the declarator and not to the type. --- .../cpp/type_traits_essentials1/test.desc | 2 +- src/cpp/cpp_declarator.h | 10 ++++ src/cpp/parse.cpp | 51 ++++++------------- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/regression/cpp/type_traits_essentials1/test.desc b/regression/cpp/type_traits_essentials1/test.desc index 0daa9695017..3862862ffd3 100644 --- a/regression/cpp/type_traits_essentials1/test.desc +++ b/regression/cpp/type_traits_essentials1/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE main.cpp -std=c++11 ^EXIT=0$ diff --git a/src/cpp/cpp_declarator.h b/src/cpp/cpp_declarator.h index 2f62817383a..a459e73eb3f 100644 --- a/src/cpp/cpp_declarator.h +++ b/src/cpp/cpp_declarator.h @@ -55,6 +55,16 @@ class cpp_declaratort:public exprt set(ID_is_parameter, is_parameter); } + bool get_has_ellipsis() const + { + return get_bool(ID_ellipsis); + } + + void set_has_ellipsis() + { + set(ID_ellipsis, true); + } + // initializers for function arguments exprt &init_args() { diff --git a/src/cpp/parse.cpp b/src/cpp/parse.cpp index 641aa0ab3ab..e8cd3927613 100644 --- a/src/cpp/parse.cpp +++ b/src/cpp/parse.cpp @@ -1206,14 +1206,11 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) declarator.type().make_nil(); set_location(declarator, tk1); - bool has_ellipsis=false; - if(lex.LookAhead(0)==TOK_ELLIPSIS) { cpp_tokent tk2; lex.get_token(tk2); - - has_ellipsis=true; + declarator.set_has_ellipsis(); } if(is_identifier(lex.LookAhead(0))) @@ -1225,16 +1222,11 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) set_location(declarator.name(), tk2); add_id(declarator.name(), new_scopet::kindt::TYPE_TEMPLATE_PARAMETER); - - if(has_ellipsis) - { - // TODO - } } if(lex.LookAhead(0)=='=') { - if(has_ellipsis) + if(declarator.get_has_ellipsis()) return false; typet default_type; @@ -1307,19 +1299,16 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) << "Parser::rTempArgDeclaration 3\n"; #endif - bool has_ellipsis=false; + declaration.declarators().resize(1); + cpp_declaratort &declarator = declaration.declarators().front(); if(lex.LookAhead(0)==TOK_ELLIPSIS) { cpp_tokent tk2; lex.get_token(tk2); - - has_ellipsis=true; + declarator.set_has_ellipsis(); } - declaration.declarators().resize(1); - cpp_declaratort &declarator=declaration.declarators().front(); - if(!rDeclarator(declarator, kArgDeclarator, true, false)) return false; @@ -1330,16 +1319,11 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) add_id(declarator.name(), new_scopet::kindt::NON_TYPE_TEMPLATE_PARAMETER); - if(has_ellipsis) - { - // TODO - } - exprt &value=declarator.value(); if(lex.LookAhead(0)=='=') { - if(has_ellipsis) + if(declarator.get_has_ellipsis()) return false; cpp_tokent tk; @@ -3998,8 +3982,7 @@ bool Parser::rTemplateArgs(irept &template_args) if(lex.LookAhead(0)==TOK_ELLIPSIS) { lex.get_token(tk1); - - // TODO + exp.set(ID_ellipsis, true); } #ifdef DEBUG std::cout << std::string(__indent, ' ') << "Parser::rTemplateArgs 4.2\n"; @@ -4017,13 +4000,6 @@ bool Parser::rTemplateArgs(irept &template_args) if(!rConditionalExpr(exp, true)) return false; - - if(lex.LookAhead(0)==TOK_ELLIPSIS) - { - lex.get_token(tk1); - - // TODO - } } #ifdef DEBUG @@ -5676,18 +5652,21 @@ bool Parser::rTypeNameOrFunctionType(typet &tname) type.parameters().push_back(parameter); t=lex.LookAhead(0); - if(t==',') + if(t == TOK_ELLIPSIS) { cpp_tokent tk; lex.get_token(tk); + to_cpp_declaration(type.parameters().back()) + .declarators() + .back() + .set_has_ellipsis(); + t = lex.LookAhead(0); } - else if(t==TOK_ELLIPSIS) + + if(t == ',') { - // TODO -- this is actually ambiguous as it could refer to a - // template parameter pack or declare a variadic function cpp_tokent tk; lex.get_token(tk); - type.make_ellipsis(); } else if(t==')') break;