2323#include " cpp_member_spec.h"
2424#include " cpp_enum_type.h"
2525
26- // #define DEBUG
26+ #define DEBUG
2727#ifdef DEBUG
2828#include < iostream>
2929
@@ -346,7 +346,6 @@ class Parser // NOLINT(readability/identifiers)
346346 bool rPostfixExpr (exprt &);
347347 bool rPrimaryExpr (exprt &);
348348 bool rVarName (exprt &);
349- bool rVarNameCore (exprt &);
350349 bool maybeTemplateArgs ();
351350
352351 bool rFunctionBody (cpp_declaratort &);
@@ -778,7 +777,7 @@ bool Parser::isTypeSpecifier()
778777 t == TOK_CPROVER_BOOL || t == TOK_CLASS || t == TOK_STRUCT ||
779778 t == TOK_UNION || t == TOK_ENUM || t == TOK_INTERFACE ||
780779 t == TOK_TYPENAME || t == TOK_TYPEOF || t == TOK_DECLTYPE ||
781- t == TOK_UNDERLYING_TYPE;
780+ t == TOK_UNDERLYING_TYPE || t == TOK_ATOMIC_TYPE_SPECIFIER ;
782781}
783782
784783/*
@@ -1336,31 +1335,61 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration)
13361335 if (!rTemplateDecl2 (template_type, kind))
13371336 return false ;
13381337
1339- // TODO
1340-
1341- cpp_tokent tk1, tk2;
1338+ cpp_tokent tk1;
13421339
13431340 if (lex.get_token (tk1) != TOK_CLASS)
13441341 return false ;
13451342
1346- if (lex.LookAhead (0 ) == ' ,' )
1343+ declaration=cpp_declarationt ();
1344+ set_location (declaration, tk1);
1345+
1346+ declaration.set (ID_is_type, true );
1347+ declaration.type ()=template_type;
1348+
1349+ declaration.declarators ().resize (1 );
1350+ cpp_declaratort &declarator=declaration.declarators ().front ();
1351+
1352+ declarator=cpp_declaratort ();
1353+ declarator.name ().make_nil ();
1354+ declarator.type ().make_nil ();
1355+ set_location (declarator, tk1);
1356+
1357+ if (lex.LookAhead (0 ) == ' ,' || lex.LookAhead (0 ) == ' >' )
13471358 return true ;
13481359
1349- if (!is_identifier (lex.get_token (tk2)))
1360+ if (lex.LookAhead (0 )==TOK_ELLIPSIS)
1361+ {
1362+ cpp_tokent tk2;
1363+ lex.get_token (tk2);
1364+ declarator.set_has_ellipsis ();
1365+ }
1366+
1367+ if (is_identifier (lex.LookAhead (0 )))
1368+ {
1369+ cpp_tokent tk2;
1370+ lex.get_token (tk2);
1371+
1372+ declarator.name () = cpp_namet (tk2.data .get (ID_C_base_name));
1373+ set_location (declarator.name (), tk2);
1374+
1375+ add_id (declarator.name (), new_scopet::kindt::TYPE_TEMPLATE_PARAMETER);
1376+ }
1377+ else
13501378 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);
1379+
13551380 if (lex.LookAhead (0 )==' =' )
13561381 {
1382+ if (declarator.get_has_ellipsis ())
1383+ return false ;
1384+
13571385 typet default_type;
1386+
13581387 lex.get_token (tk1);
13591388 if (!rTypeName (default_type))
1360- return false ;
1389+ return false ;
13611390
1362- // decl=Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
1363- // default_type) );
1391+ declarator. value ()= exprt (ID_type);
1392+ declarator. value (). type (). swap (default_type );
13641393 }
13651394 }
13661395 else
@@ -1487,6 +1516,10 @@ bool Parser::rDeclaration(cpp_declarationt &declaration)
14871516 cpp_member_spect member_spec;
14881517 if (!optMemberSpec (member_spec))
14891518 return false ;
1519+ if (!optAttribute (declaration.type ()))
1520+ return false ;
1521+ if (!optMemberSpec (member_spec))
1522+ return false ;
14901523
14911524#ifdef DEBUG
14921525 std::cout << std::string (__indent, ' ' ) << " Parser::rDeclaration 0.2\n " ;
@@ -2051,8 +2084,6 @@ bool Parser::isPtrToMember(int i)
20512084*/
20522085bool Parser::optMemberSpec (cpp_member_spect &member_spec)
20532086{
2054- member_spec.clear ();
2055-
20562087 int t=lex.LookAhead (0 );
20572088
20582089 while (
@@ -2502,6 +2533,17 @@ bool Parser::optAttribute(typet &t)
25022533 break ;
25032534 }
25042535
2536+ case TOK_GCC_IDENTIFIER:
2537+ if (tk.text == " clang" && lex.LookAhead (0 ) == TOK_SCOPE)
2538+ {
2539+ exprt discarded;
2540+ if (!rExpression (discarded, false ))
2541+ return false ;
2542+ }
2543+ else
2544+ return false ;
2545+ break ;
2546+
25052547 default :
25062548 // TODO: way may wish to change this: GCC, Clang, Visual Studio merely
25072549 // warn when they see an attribute that they don't recognize
@@ -2737,8 +2779,34 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
27372779
27382780 return true ;
27392781 }
2782+ else if (t == TOK_ATOMIC_TYPE_SPECIFIER)
2783+ {
2784+ #ifdef DEBUG
2785+ std::cout << std::string (__indent, ' ' )
2786+ << " Parser::optIntegralTypeOrClassSpec 9\n " ;
2787+ #endif // DEBUG
2788+ cpp_tokent atomic_tk;
2789+ lex.get_token (atomic_tk);
2790+
2791+ cpp_tokent tk;
2792+ if (lex.get_token (tk)!=' (' )
2793+ return false ;
2794+
2795+ // the argument is always a type
2796+ if (!rTypeSpecifier (p, false ))
2797+ return false ;
2798+
2799+ if (lex.get_token (tk)!=' )' )
2800+ return false ;
2801+
2802+ return true ;
2803+ }
27402804 else
27412805 {
2806+ #ifdef DEBUG
2807+ std::cout << std::string (__indent, ' ' )
2808+ << " Parser::optIntegralTypeOrClassSpec 10\n " ;
2809+ #endif // DEBUG
27422810 p.make_nil ();
27432811 return true ;
27442812 }
@@ -3774,7 +3842,7 @@ bool Parser::rName(irept &name)
37743842 components.back ().add (ID_expr_arg).swap (expr);
37753843
37763844 if (lex.LookAhead (0 ) != TOK_SCOPE)
3777- return false ;
3845+ return true ;
37783846 }
37793847 break ;
37803848
@@ -4549,6 +4617,9 @@ bool Parser::rEnumSpec(typet &spec)
45494617 spec.set (ID_C_class, true );
45504618 }
45514619
4620+ if (!optAttribute (spec))
4621+ return false ;
4622+
45524623 if (lex.LookAhead (0 )!=' {' &&
45534624 lex.LookAhead (0 )!=' :' )
45544625 {
@@ -4715,7 +4786,7 @@ bool Parser::rClassSpec(typet &spec)
47154786 if (!optAttribute (spec))
47164787 return false ;
47174788
4718- if (lex.LookAhead (0 )==' {' )
4789+ if (lex.LookAhead (0 )==' {' || lex. LookAhead ( 0 ) == ' : ' )
47194790 {
47204791 // no tag
47214792#ifdef DEBUG
@@ -4734,21 +4805,21 @@ bool Parser::rClassSpec(typet &spec)
47344805#ifdef DEBUG
47354806 std::cout << std::string (__indent, ' ' ) << " Parser::rClassSpec 5\n " ;
47364807#endif
4808+ }
47374809
4738- t=lex.LookAhead (0 );
4810+ t=lex.LookAhead (0 );
47394811
4740- if (t==' :' )
4741- {
4742- if (!rBaseSpecifiers (spec.add (ID_bases)))
4743- return false ;
4744- }
4745- else if (t==' {' )
4746- {
4747- }
4748- else
4749- {
4750- return true ;
4751- }
4812+ if (t==' :' )
4813+ {
4814+ if (!rBaseSpecifiers (spec.add (ID_bases)))
4815+ return false ;
4816+ }
4817+ else if (t==' {' )
4818+ {
4819+ }
4820+ else
4821+ {
4822+ return true ;
47524823 }
47534824
47544825#ifdef DEBUG
@@ -6721,7 +6792,10 @@ bool Parser::rPostfixExpr(exprt &exp)
67216792 }
67226793
67236794#ifdef DEBUG
6724- std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1\n " ;
6795+ std::cout << std::string (__indent, ' ' ) << " Parser::rPostfixExpr 1 "
6796+ << lex.LookAhead (0 )
6797+ << ' ' << lex.peek ().text
6798+ << ' \n ' ;
67256799#endif
67266800
67276801 exprt e;
@@ -7276,16 +7350,7 @@ bool Parser::rVarName(exprt &name)
72767350 << ' \n ' ;
72777351#endif
72787352
7279- if (rVarNameCore (name))
7280- return true ;
7281- else
7282- return false ;
7283- }
7284-
7285- bool Parser::rVarNameCore (exprt &name)
7286- {
72877353#ifdef DEBUG
7288- indenter _i;
72897354 std::cout << std::string (__indent, ' ' ) << " Parser::rVarNameCore 0\n " ;
72907355#endif
72917356
@@ -7458,7 +7523,7 @@ bool Parser::moreVarName()
74587523/*
74597524 template.args : '<' any* '>'
74607525
7461- template.args must be followed by '(' or '::'
7526+ template.args must be followed by '(', '::', or '; '
74627527*/
74637528bool Parser::maybeTemplateArgs ()
74647529{
@@ -7480,7 +7545,8 @@ bool Parser::maybeTemplateArgs()
74807545 return false ;
74817546 else if ((u==' >' || u==TOK_SHIFTRIGHT) &&
74827547 (lex.LookAhead (i)==TOK_SCOPE || lex.LookAhead (i)==' (' ||
7483- lex.LookAhead (i)==' )' ))
7548+ lex.LookAhead (i)==' )' || lex.LookAhead (i) == ' }' ||
7549+ lex.LookAhead (i) == ' ,' || lex.LookAhead (i) == ' ;' ))
74847550 return true ;
74857551 }
74867552#else
@@ -7903,7 +7969,9 @@ std::optional<codet> Parser::rStatement()
79037969 if (!rUsing (cpp_using))
79047970 return {};
79057971
7906- UNIMPLEMENTED;
7972+ codet statement (ID_cpp_using);
7973+ // UNIMPLEMENTED;
7974+ return std::move (statement);
79077975 }
79087976
79097977 case TOK_STATIC_ASSERT:
@@ -7920,6 +7988,14 @@ std::optional<codet> Parser::rStatement()
79207988 return std::move (statement);
79217989 }
79227990
7991+ case ' [' :
7992+ {
7993+ typet discard;
7994+ if (!optAttribute (discard))
7995+ return {};
7996+ return code_blockt{};
7997+ }
7998+
79237999 default :
79248000 return rExprStatement ();
79258001 }
0 commit comments