@@ -778,7 +778,7 @@ bool Parser::isTypeSpecifier()
778778 t == TOK_CPROVER_BOOL || t == TOK_CLASS || t == TOK_STRUCT ||
779779 t == TOK_UNION || t == TOK_ENUM || t == TOK_INTERFACE ||
780780 t == TOK_TYPENAME || t == TOK_TYPEOF || t == TOK_DECLTYPE ||
781- t == TOK_UNDERLYING_TYPE;
781+ t == TOK_UNDERLYING_TYPE || t == TOK_ATOMIC_TYPE_SPECIFIER ;
782782}
783783
784784/*
@@ -1336,31 +1336,61 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration)
13361336 if (!rTemplateDecl2 (template_type, kind))
13371337 return false ;
13381338
1339- // TODO
1340-
1341- cpp_tokent tk1, tk2;
1339+ cpp_tokent tk1;
13421340
13431341 if (lex.get_token (tk1) != TOK_CLASS)
13441342 return false ;
13451343
1346- if (lex.LookAhead (0 ) == ' ,' )
1344+ declaration=cpp_declarationt ();
1345+ set_location (declaration, tk1);
1346+
1347+ declaration.set (ID_is_type, true );
1348+ declaration.type ()=template_type;
1349+
1350+ declaration.declarators ().resize (1 );
1351+ cpp_declaratort &declarator=declaration.declarators ().front ();
1352+
1353+ declarator=cpp_declaratort ();
1354+ declarator.name ().make_nil ();
1355+ declarator.type ().make_nil ();
1356+ set_location (declarator, tk1);
1357+
1358+ if (lex.LookAhead (0 ) == ' ,' || lex.LookAhead (0 ) == ' >' )
13471359 return true ;
13481360
1349- if (!is_identifier (lex.get_token (tk2)))
1361+ if (lex.LookAhead (0 )==TOK_ELLIPSIS)
1362+ {
1363+ cpp_tokent tk2;
1364+ lex.get_token (tk2);
1365+ declarator.set_has_ellipsis ();
1366+ }
1367+
1368+ if (is_identifier (lex.LookAhead (0 )))
1369+ {
1370+ cpp_tokent tk2;
1371+ lex.get_token (tk2);
1372+
1373+ declarator.name () = cpp_namet (tk2.data .get (ID_C_base_name));
1374+ set_location (declarator.name (), tk2);
1375+
1376+ add_id (declarator.name (), new_scopet::kindt::TYPE_TEMPLATE_PARAMETER);
1377+ }
1378+ else
13501379 return false ;
1351- // Ptree cspec=new PtreeClassSpec(new LeafReserved(tk1),
1352- // Ptree::Cons(new Leaf(tk2),nil),
1353- // nil);
1354- // decl=Ptree::Snoc(decl, cspec);
1380+
13551381 if (lex.LookAhead (0 )==' =' )
13561382 {
1383+ if (declarator.get_has_ellipsis ())
1384+ return false ;
1385+
13571386 typet default_type;
1387+
13581388 lex.get_token (tk1);
13591389 if (!rTypeName (default_type))
1360- return false ;
1390+ return false ;
13611391
1362- // decl=Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
1363- // default_type) );
1392+ declarator. value ()= exprt (ID_type);
1393+ declarator. value (). type (). swap (default_type );
13641394 }
13651395 }
13661396 else
@@ -2502,6 +2532,17 @@ bool Parser::optAttribute(typet &t)
25022532 break ;
25032533 }
25042534
2535+ case TOK_GCC_IDENTIFIER:
2536+ if (tk.text == " clang" && lex.LookAhead (0 ) == TOK_SCOPE)
2537+ {
2538+ exprt discarded;
2539+ if (!rExpression (discarded, false ))
2540+ return false ;
2541+ }
2542+ else
2543+ return false ;
2544+ break ;
2545+
25052546 default :
25062547 // TODO: way may wish to change this: GCC, Clang, Visual Studio merely
25072548 // warn when they see an attribute that they don't recognize
@@ -2737,8 +2778,34 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
27372778
27382779 return true ;
27392780 }
2781+ else if (t == TOK_ATOMIC_TYPE_SPECIFIER)
2782+ {
2783+ #ifdef DEBUG
2784+ std::cout << std::string (__indent, ' ' )
2785+ << " Parser::optIntegralTypeOrClassSpec 9\n " ;
2786+ #endif // DEBUG
2787+ cpp_tokent atomic_tk;
2788+ lex.get_token (atomic_tk);
2789+
2790+ cpp_tokent tk;
2791+ if (lex.get_token (tk)!=' (' )
2792+ return false ;
2793+
2794+ // the argument is always a type
2795+ if (!rTypeSpecifier (p, false ))
2796+ return false ;
2797+
2798+ if (lex.get_token (tk)!=' )' )
2799+ return false ;
2800+
2801+ return true ;
2802+ }
27402803 else
27412804 {
2805+ #ifdef DEBUG
2806+ std::cout << std::string (__indent, ' ' )
2807+ << " Parser::optIntegralTypeOrClassSpec 10\n " ;
2808+ #endif // DEBUG
27422809 p.make_nil ();
27432810 return true ;
27442811 }
@@ -3774,7 +3841,7 @@ bool Parser::rName(irept &name)
37743841 components.back ().add (ID_expr_arg).swap (expr);
37753842
37763843 if (lex.LookAhead (0 ) != TOK_SCOPE)
3777- return false ;
3844+ return true ;
37783845 }
37793846 break ;
37803847
@@ -4549,6 +4616,9 @@ bool Parser::rEnumSpec(typet &spec)
45494616 spec.set (ID_C_class, true );
45504617 }
45514618
4619+ if (!optAttribute (spec))
4620+ return false ;
4621+
45524622 if (lex.LookAhead (0 )!=' {' &&
45534623 lex.LookAhead (0 )!=' :' )
45544624 {
@@ -6721,7 +6791,10 @@ bool Parser::rPostfixExpr(exprt &exp)
67216791 }
67226792
67236793#ifdef DEBUG
6724- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1\n " ;
6794+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1 "
6795+ << lex.LookAhead (0 )
6796+ << ' ' << lex.peek ().text
6797+ << ' \n ' ;
67256798#endif
67266799
67276800 exprt e;
@@ -7903,7 +7976,9 @@ std::optional<codet> Parser::rStatement()
79037976 if (!rUsing (cpp_using))
79047977 return {};
79057978
7906- UNIMPLEMENTED;
7979+ codet statement (ID_cpp_using);
7980+ // UNIMPLEMENTED;
7981+ return std::move (statement);
79077982 }
79087983
79097984 case TOK_STATIC_ASSERT:
@@ -7920,6 +7995,14 @@ std::optional<codet> Parser::rStatement()
79207995 return std::move (statement);
79217996 }
79227997
7998+ case ' [' :
7999+ {
8000+ typet discard;
8001+ if (!optAttribute (discard))
8002+ return {};
8003+ return code_blockt{};
8004+ }
8005+
79238006 default :
79248007 return rExprStatement ();
79258008 }
0 commit comments