2323#include " cpp_member_spec.h"
2424#include " cpp_enum_type.h"
2525
26- #define DEBUG
2726#ifdef DEBUG
2827#include < iostream>
2928
@@ -6363,7 +6362,10 @@ bool Parser::rAllocateInitializer(exprt &init)
63636362 postfix.exp
63646363 : primary.exp
63656364 | postfix.expr '[' comma.expression ']'
6365+ | postfix.expr '[' initializer ']'
63666366 | postfix.expr '(' function.arguments ')'
6367+ | integral.or.class.spec '(' function.arguments ')'
6368+ | integral.or.class.spec initializer
63676369 | postfix.expr '.' var.name
63686370 | postfix.expr ArrowOp var.name
63696371 | postfix.expr IncOp
@@ -6372,8 +6374,6 @@ bool Parser::rAllocateInitializer(exprt &init)
63726374 openc++.postfix.expr
63736375 : postfix.expr '.' userdef.statement
63746376 | postfix.expr ArrowOp userdef.statement
6375-
6376- Note: function-style casts are accepted as function calls.
63776377*/
63786378bool Parser::rPostfixExpr (exprt &exp)
63796379{
@@ -6382,8 +6382,52 @@ bool Parser::rPostfixExpr(exprt &exp)
63826382 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0\n " ;
63836383#endif
63846384
6385- if (!rPrimaryExpr (exp))
6386- return false ;
6385+ typet type;
6386+
6387+ cpp_token_buffert::post pos=lex.Save ();
6388+ // try to see whether this is explicit type conversion, else it has to be
6389+ // a primary-expression
6390+ if (optIntegralTypeOrClassSpec (type) &&
6391+ (type.is_not_nil () || rName (type)) &&
6392+ (lex.LookAhead (0 ) == ' (' || lex.LookAhead (0 ) == ' {' ))
6393+ {
6394+ #ifdef DEBUG
6395+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 0.1\n " ;
6396+ #endif
6397+
6398+ cpp_tokent tk;
6399+ lex.LookAhead (0 , tk);
6400+ exprt exp2;
6401+ if (lex.LookAhead (0 )==' {' )
6402+ {
6403+ if (!rInitializeExpr (exp2))
6404+ return false ;
6405+ }
6406+ else
6407+ {
6408+ // lex.LookAhead(0)=='('
6409+ lex.get_token (tk);
6410+
6411+ exprt exp2;
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+ {
6427+ lex.Restore (pos);
6428+ if (!rPrimaryExpr (exp))
6429+ return false ;
6430+ }
63876431
63886432#ifdef DEBUG
63896433 std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1\n " ;
@@ -6399,7 +6443,14 @@ bool Parser::rPostfixExpr(exprt &exp)
63996443 {
64006444 case ' [' :
64016445 lex.get_token (op);
6402- if (!rCommaExpression (e))
6446+
6447+ if (lex.LookAhead (0 ) == ' {' )
6448+ {
6449+ // C++11 initialisation expression
6450+ if (!rInitializeExpr (e))
6451+ return false ;
6452+ }
6453+ else if (!rCommaExpression (e))
64036454 return false ;
64046455
64056456#ifdef DEBUG
@@ -6447,35 +6498,6 @@ bool Parser::rPostfixExpr(exprt &exp)
64476498 }
64486499 break ;
64496500
6450- case ' {' :
6451- #ifdef DEBUG
6452- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 3a\n " ;
6453- #endif
6454-
6455- // this is a C++11 extension
6456- if (!rInitializeExpr (e))
6457- return false ;
6458-
6459- if (lex.get_token (cp)!=' }' )
6460- return false ;
6461-
6462- #ifdef DEBUG
6463- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 4a\n " ;
6464- #endif
6465-
6466- {
6467- side_effect_expr_function_callt fc (
6468- std::move (exp), {}, typet{}, source_locationt{});
6469- fc.arguments ().reserve (e.operands ().size ());
6470- set_location (fc, op);
6471-
6472- Forall_operands (it, e)
6473- fc.arguments ().push_back (*it);
6474- e.operands ().clear (); // save some
6475- exp.swap (fc);
6476- }
6477- break ;
6478-
64796501 case TOK_INCR:
64806502 lex.get_token (op);
64816503
@@ -6746,8 +6768,6 @@ bool Parser::rTypePredicate(exprt &expr)
67466768 | THIS
67476769 | var.name
67486770 | '(' comma.expression ')'
6749- | integral.or.class.spec '(' function.arguments ')'
6750- | integral.or.class.spec initializer
67516771 | typeid.expr
67526772 | true
67536773 | false
@@ -6865,12 +6885,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
68656885#endif
68666886 return true ;
68676887
6868- case ' {' : // C++11 initialisation expression
6869- #ifdef DEBUG
6870- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 10\n " ;
6871- #endif
6872- return rInitializeExpr (exp);
6873-
68746888 case TOK_TYPEID:
68756889 return rTypeidExpr (exp);
68766890
@@ -6901,60 +6915,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
69016915 std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 14\n " ;
69026916#endif
69036917 {
6904- typet type;
6905-
6906- if (!optIntegralTypeOrClassSpec (type))
6907- return false ;
6908-
6909- #ifdef DEBUG
6910- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 15\n " ;
6911- #endif
6912-
6913- if (type.is_not_nil () && lex.LookAhead (0 )==TOK_SCOPE)
6914- {
6915- lex.get_token (tk);
6916- lex.get_token (tk);
6917-
6918- // TODO
6919- }
6920- else if (type.is_not_nil ())
6921- {
6922- #ifdef DEBUG
6923- std::cout << std::string (__indent, ' ' ) << " Parser::rPrimaryExpr 16\n " ;
6924- #endif
6925- if (lex.LookAhead (0 )==' {' )
6926- {
6927- lex.LookAhead (0 , tk);
6928-
6929- exprt exp2;
6930- if (!rInitializeExpr (exp2))
6931- return false ;
6932-
6933- exp=exprt (" explicit-constructor-call" );
6934- exp.type ().swap (type);
6935- exp.add_to_operands (std::move (exp2));
6936- set_location (exp, tk);
6937- }
6938- else if (lex.LookAhead (0 )==' (' )
6939- {
6940- lex.get_token (tk);
6941-
6942- exprt exp2;
6943- if (!rFunctionArguments (exp2))
6944- return false ;
6945-
6946- if (lex.get_token (tk2)!=' )' )
6947- return false ;
6948-
6949- exp=exprt (" explicit-constructor-call" );
6950- exp.type ().swap (type);
6951- exp.operands ().swap (exp2.operands ());
6952- set_location (exp, tk);
6953- }
6954- else
6955- return false ;
6956- }
6957- else
69586918 {
69596919 if (!rVarName (exp))
69606920 return false ;
0 commit comments