@@ -6363,7 +6363,10 @@ bool Parser::rAllocateInitializer(exprt &init)
63636363 postfix.exp
63646364 : primary.exp
63656365 | postfix.expr '[' comma.expression ']'
6366+ | postfix.expr '[' initializer ']'
63666367 | postfix.expr '(' function.arguments ')'
6368+ | integral.or.class.spec '(' function.arguments ')'
6369+ | integral.or.class.spec initializer
63676370 | postfix.expr '.' var.name
63686371 | postfix.expr ArrowOp var.name
63696372 | postfix.expr IncOp
@@ -6372,8 +6375,6 @@ bool Parser::rAllocateInitializer(exprt &init)
63726375 openc++.postfix.expr
63736376 : postfix.expr '.' userdef.statement
63746377 | postfix.expr ArrowOp userdef.statement
6375-
6376- Note: function-style casts are accepted as function calls.
63776378*/
63786379bool Parser::rPostfixExpr (exprt &exp)
63796380{
@@ -6382,8 +6383,89 @@ bool Parser::rPostfixExpr(exprt &exp)
63826383 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0\n " ;
63836384#endif
63846385
6385- if (!rPrimaryExpr (exp))
6386- return false ;
6386+ typet type;
6387+
6388+ cpp_token_buffert::post pos=lex.Save ();
6389+ // try to see whether this is explicit type conversion, else it has to be
6390+ // a primary-expression
6391+ if (optIntegralTypeOrClassSpec (type) &&
6392+ type.is_not_nil () &&
6393+ (lex.LookAhead (0 ) == ' (' || lex.LookAhead (0 ) == ' {' ))
6394+ {
6395+ #ifdef DEBUG
6396+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0.1\n " ;
6397+ #endif
6398+
6399+ cpp_tokent tk;
6400+ lex.LookAhead (0 , tk);
6401+ exprt exp2;
6402+ if (lex.LookAhead (0 )==' {' )
6403+ {
6404+ if (!rInitializeExpr (exp2))
6405+ return false ;
6406+ }
6407+ else
6408+ {
6409+ // lex.LookAhead(0)=='('
6410+ lex.get_token (tk);
6411+
6412+ if (!rFunctionArguments (exp2))
6413+ return false ;
6414+
6415+ cpp_tokent tk2;
6416+ if (lex.get_token (tk2)!=' )' )
6417+ return false ;
6418+ }
6419+
6420+ exp=exprt (" explicit-constructor-call" );
6421+ exp.type ().swap (type);
6422+ exp.operands ().swap (exp2.operands ());
6423+ set_location (exp, tk);
6424+ }
6425+ else
6426+ lex.Restore (pos);
6427+
6428+ exprt type_or_function_name;
6429+ if (rName (type_or_function_name) &&
6430+ (lex.LookAhead (0 ) == ' (' || lex.LookAhead (0 ) == ' {' ))
6431+ {
6432+ #ifdef DEBUG
6433+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0.2\n " ;
6434+ #endif
6435+
6436+ cpp_tokent tk;
6437+ lex.LookAhead (0 , tk);
6438+ exprt exp2;
6439+ if (lex.LookAhead (0 )==' {' )
6440+ {
6441+ if (!rInitializeExpr (exp2))
6442+ return false ;
6443+ }
6444+ else
6445+ {
6446+ // lex.LookAhead(0)=='('
6447+ lex.get_token (tk);
6448+
6449+ if (!rFunctionArguments (exp2))
6450+ return false ;
6451+
6452+ cpp_tokent tk2;
6453+ if (lex.get_token (tk2)!=' )' )
6454+ return false ;
6455+ }
6456+
6457+ side_effect_expr_function_callt fc (
6458+ std::move (type_or_function_name), exp2.operands (), typet{}, source_locationt{});
6459+ set_location (fc, tk);
6460+
6461+ exp.swap (fc);
6462+ }
6463+ else
6464+ {
6465+ lex.Restore (pos);
6466+ if (!rPrimaryExpr (exp))
6467+ return false ;
6468+ }
63876469
63886470#ifdef DEBUG
63896471 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1\n " ;
@@ -6399,7 +6481,14 @@ bool Parser::rPostfixExpr(exprt &exp)
63996481 {
64006482 case ' [' :
64016483 lex.get_token (op);
6402- if (!rCommaExpression (e))
6484+
6485+ if (lex.LookAhead (0 ) == ' {' )
6486+ {
6487+ // C++11 initialisation expression
6488+ if (!rInitializeExpr (e))
6489+ return false ;
6490+ }
6491+ else if (!rCommaExpression (e))
64036492 return false ;
64046493
64056494#ifdef DEBUG
@@ -6424,7 +6513,6 @@ bool Parser::rPostfixExpr(exprt &exp)
64246513 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 3\n " ;
64256514#endif
64266515
6427- lex.get_token (op);
64286516 if (!rFunctionArguments (e))
64296517 return false ;
64306518
@@ -6718,8 +6806,6 @@ bool Parser::rTypePredicate(exprt &expr)
67186806 | THIS
67196807 | var.name
67206808 | '(' comma.expression ')'
6721- | integral.or.class.spec '(' function.arguments ')'
6722- | integral.or.class.spec initializer
67236809 | typeid.expr
67246810 | true
67256811 | false
@@ -6837,12 +6923,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
68376923#endif
68386924 return true ;
68396925
6840- case ' {' : // C++11 initialisation expression
6841- #ifdef DEBUG
6842- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 10\n " ;
6843- #endif
6844- return rInitializeExpr (exp);
6845-
68466926 case TOK_TYPEID:
68476927 return rTypeidExpr (exp);
68486928
@@ -6873,60 +6953,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
68736953 std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 14\n " ;
68746954#endif
68756955 {
6876- typet type;
6877-
6878- if (!optIntegralTypeOrClassSpec (type))
6879- return false ;
6880-
6881- #ifdef DEBUG
6882- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 15\n " ;
6883- #endif
6884-
6885- if (type.is_not_nil () && lex.LookAhead (0 )==TOK_SCOPE)
6886- {
6887- lex.get_token (tk);
6888- lex.get_token (tk);
6889-
6890- // TODO
6891- }
6892- else if (type.is_not_nil ())
6893- {
6894- #ifdef DEBUG
6895- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 16\n " ;
6896- #endif
6897- if (lex.LookAhead (0 )==' {' )
6898- {
6899- lex.LookAhead (0 , tk);
6900-
6901- exprt exp2;
6902- if (!rInitializeExpr (exp2))
6903- return false ;
6904-
6905- exp=exprt (" explicit-constructor-call" );
6906- exp.type ().swap (type);
6907- exp.add_to_operands (std::move (exp2));
6908- set_location (exp, tk);
6909- }
6910- else if (lex.LookAhead (0 )==' (' )
6911- {
6912- lex.get_token (tk);
6913-
6914- exprt exp2;
6915- if (!rFunctionArguments (exp2))
6916- return false ;
6917-
6918- if (lex.get_token (tk2)!=' )' )
6919- return false ;
6920-
6921- exp=exprt (" explicit-constructor-call" );
6922- exp.type ().swap (type);
6923- exp.operands ().swap (exp2.operands ());
6924- set_location (exp, tk);
6925- }
6926- else
6927- return false ;
6928- }
6929- else
69306956 {
69316957 if (!rVarName (exp))
69326958 return false ;
0 commit comments