2323#include " cpp_member_spec.h"
2424#include " cpp_enum_type.h"
2525
26- #define DEBUG
2726#ifdef DEBUG
2827#include < iostream>
2928
@@ -6321,7 +6320,10 @@ bool Parser::rAllocateInitializer(exprt &init)
63216320 postfix.exp
63226321 : primary.exp
63236322 | postfix.expr '[' comma.expression ']'
6323+ | postfix.expr '[' initializer ']'
63246324 | postfix.expr '(' function.arguments ')'
6325+ | integral.or.class.spec '(' function.arguments ')'
6326+ | integral.or.class.spec initializer
63256327 | postfix.expr '.' var.name
63266328 | postfix.expr ArrowOp var.name
63276329 | postfix.expr IncOp
@@ -6330,8 +6332,6 @@ bool Parser::rAllocateInitializer(exprt &init)
63306332 openc++.postfix.expr
63316333 : postfix.expr '.' userdef.statement
63326334 | postfix.expr ArrowOp userdef.statement
6333-
6334- Note: function-style casts are accepted as function calls.
63356335*/
63366336bool Parser::rPostfixExpr (exprt &exp)
63376337{
@@ -6340,8 +6340,52 @@ bool Parser::rPostfixExpr(exprt &exp)
63406340 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0\n " ;
63416341#endif
63426342
6343- if (!rPrimaryExpr (exp))
6344- return false ;
6343+ typet type;
6344+
6345+ cpp_token_buffert::post pos=lex.Save ();
6346+ // try to see whether this is explicit type conversion, else it has to be
6347+ // a primary-expression
6348+ if (optIntegralTypeOrClassSpec (type) &&
6349+ (type.is_not_nil () || rName (type)) &&
6350+ (lex.LookAhead (0 ) == ' (' || lex.LookAhead (0 ) == ' {' ))
6351+ {
6352+ #ifdef DEBUG
6353+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0.1\n " ;
6354+ #endif
6355+
6356+ cpp_tokent tk;
6357+ lex.LookAhead (0 , tk);
6358+ exprt exp2;
6359+ if (lex.LookAhead (0 )==' {' )
6360+ {
6361+ if (!rInitializeExpr (exp2))
6362+ return false ;
6363+ }
6364+ else
6365+ {
6366+ // lex.LookAhead(0)=='('
6367+ lex.get_token (tk);
6368+
6369+ exprt exp2;
6370+ if (!rFunctionArguments (exp2))
6371+ return false ;
6372+
6373+ cpp_tokent tk2;
6374+ if (lex.get_token (tk2)!=' )' )
6375+ return false ;
6376+ }
6377+
6378+ exp=exprt (" explicit-constructor-call" );
6379+ exp.type ().swap (type);
6380+ exp.operands ().swap (exp2.operands ());
6381+ set_location (exp, tk);
6382+ }
6383+ else
6384+ {
6385+ lex.Restore (pos);
6386+ if (!rPrimaryExpr (exp))
6387+ return false ;
6388+ }
63456389
63466390#ifdef DEBUG
63476391 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1\n " ;
@@ -6357,7 +6401,14 @@ bool Parser::rPostfixExpr(exprt &exp)
63576401 {
63586402 case ' [' :
63596403 lex.get_token (op);
6360- if (!rCommaExpression (e))
6404+
6405+ if (lex.LookAhead (0 ) == ' {' )
6406+ {
6407+ // C++11 initialisation expression
6408+ if (!rInitializeExpr (e))
6409+ return false ;
6410+ }
6411+ else if (!rCommaExpression (e))
63616412 return false ;
63626413
63636414#ifdef DEBUG
@@ -6405,35 +6456,6 @@ bool Parser::rPostfixExpr(exprt &exp)
64056456 }
64066457 break ;
64076458
6408- case ' {' :
6409- #ifdef DEBUG
6410- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 3a\n " ;
6411- #endif
6412-
6413- // this is a C++11 extension
6414- if (!rInitializeExpr (e))
6415- return false ;
6416-
6417- if (lex.get_token (cp)!=' }' )
6418- return false ;
6419-
6420- #ifdef DEBUG
6421- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 4a\n " ;
6422- #endif
6423-
6424- {
6425- side_effect_expr_function_callt fc (
6426- std::move (exp), {}, typet{}, source_locationt{});
6427- fc.arguments ().reserve (e.operands ().size ());
6428- set_location (fc, op);
6429-
6430- Forall_operands (it, e)
6431- fc.arguments ().push_back (*it);
6432- e.operands ().clear (); // save some
6433- exp.swap (fc);
6434- }
6435- break ;
6436-
64376459 case TOK_INCR:
64386460 lex.get_token (op);
64396461
@@ -6704,8 +6726,6 @@ bool Parser::rTypePredicate(exprt &expr)
67046726 | THIS
67056727 | var.name
67066728 | '(' comma.expression ')'
6707- | integral.or.class.spec '(' function.arguments ')'
6708- | integral.or.class.spec initializer
67096729 | typeid.expr
67106730 | true
67116731 | false
@@ -6823,12 +6843,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
68236843#endif
68246844 return true ;
68256845
6826- case ' {' : // C++11 initialisation expression
6827- #ifdef DEBUG
6828- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 10\n " ;
6829- #endif
6830- return rInitializeExpr (exp);
6831-
68326846 case TOK_TYPEID:
68336847 return rTypeidExpr (exp);
68346848
@@ -6859,60 +6873,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
68596873 std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 14\n " ;
68606874#endif
68616875 {
6862- typet type;
6863-
6864- if (!optIntegralTypeOrClassSpec (type))
6865- return false ;
6866-
6867- #ifdef DEBUG
6868- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 15\n " ;
6869- #endif
6870-
6871- if (type.is_not_nil () && lex.LookAhead (0 )==TOK_SCOPE)
6872- {
6873- lex.get_token (tk);
6874- lex.get_token (tk);
6875-
6876- // TODO
6877- }
6878- else if (type.is_not_nil ())
6879- {
6880- #ifdef DEBUG
6881- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 16\n " ;
6882- #endif
6883- if (lex.LookAhead (0 )==' {' )
6884- {
6885- lex.LookAhead (0 , tk);
6886-
6887- exprt exp2;
6888- if (!rInitializeExpr (exp2))
6889- return false ;
6890-
6891- exp=exprt (" explicit-constructor-call" );
6892- exp.type ().swap (type);
6893- exp.add_to_operands (std::move (exp2));
6894- set_location (exp, tk);
6895- }
6896- else if (lex.LookAhead (0 )==' (' )
6897- {
6898- lex.get_token (tk);
6899-
6900- exprt exp2;
6901- if (!rFunctionArguments (exp2))
6902- return false ;
6903-
6904- if (lex.get_token (tk2)!=' )' )
6905- return false ;
6906-
6907- exp=exprt (" explicit-constructor-call" );
6908- exp.type ().swap (type);
6909- exp.operands ().swap (exp2.operands ());
6910- set_location (exp, tk);
6911- }
6912- else
6913- return false ;
6914- }
6915- else
69166876 {
69176877 if (!rVarName (exp))
69186878 return false ;
0 commit comments