@@ -778,7 +778,7 @@ bool Parser::isTypeSpecifier()
778
778
t == TOK_CPROVER_BOOL || t == TOK_CLASS || t == TOK_STRUCT ||
779
779
t == TOK_UNION || t == TOK_ENUM || t == TOK_INTERFACE ||
780
780
t == TOK_TYPENAME || t == TOK_TYPEOF || t == TOK_DECLTYPE ||
781
- t == TOK_UNDERLYING_TYPE;
781
+ t == TOK_UNDERLYING_TYPE || t == TOK_ATOMIC_TYPE_SPECIFIER ;
782
782
}
783
783
784
784
/*
@@ -1336,31 +1336,61 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration)
1336
1336
if (!rTemplateDecl2 (template_type, kind))
1337
1337
return false ;
1338
1338
1339
- // TODO
1340
-
1341
- cpp_tokent tk1, tk2;
1339
+ cpp_tokent tk1;
1342
1340
1343
1341
if (lex.get_token (tk1) != TOK_CLASS)
1344
1342
return false ;
1345
1343
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 ) == ' >' )
1347
1359
return true ;
1348
1360
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
1350
1379
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
+
1355
1381
if (lex.LookAhead (0 )==' =' )
1356
1382
{
1383
+ if (declarator.get_has_ellipsis ())
1384
+ return false ;
1385
+
1357
1386
typet default_type;
1387
+
1358
1388
lex.get_token (tk1);
1359
1389
if (!rTypeName (default_type))
1360
- return false ;
1390
+ return false ;
1361
1391
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 );
1364
1394
}
1365
1395
}
1366
1396
else
@@ -2502,6 +2532,17 @@ bool Parser::optAttribute(typet &t)
2502
2532
break ;
2503
2533
}
2504
2534
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
+
2505
2546
default :
2506
2547
// TODO: way may wish to change this: GCC, Clang, Visual Studio merely
2507
2548
// warn when they see an attribute that they don't recognize
@@ -2737,8 +2778,34 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
2737
2778
2738
2779
return true ;
2739
2780
}
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
+ }
2740
2803
else
2741
2804
{
2805
+ #ifdef DEBUG
2806
+ std::cout << std::string (__indent, ' ' )
2807
+ << " Parser::optIntegralTypeOrClassSpec 10\n " ;
2808
+ #endif // DEBUG
2742
2809
p.make_nil ();
2743
2810
return true ;
2744
2811
}
@@ -3774,7 +3841,7 @@ bool Parser::rName(irept &name)
3774
3841
components.back ().add (ID_expr_arg).swap (expr);
3775
3842
3776
3843
if (lex.LookAhead (0 ) != TOK_SCOPE)
3777
- return false ;
3844
+ return true ;
3778
3845
}
3779
3846
break ;
3780
3847
@@ -4549,6 +4616,9 @@ bool Parser::rEnumSpec(typet &spec)
4549
4616
spec.set (ID_C_class, true );
4550
4617
}
4551
4618
4619
+ if (!optAttribute (spec))
4620
+ return false ;
4621
+
4552
4622
if (lex.LookAhead (0 )!=' {' &&
4553
4623
lex.LookAhead (0 )!=' :' )
4554
4624
{
@@ -6721,7 +6791,10 @@ bool Parser::rPostfixExpr(exprt &exp)
6721
6791
}
6722
6792
6723
6793
#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 ' ;
6725
6798
#endif
6726
6799
6727
6800
exprt e;
@@ -7903,7 +7976,9 @@ std::optional<codet> Parser::rStatement()
7903
7976
if (!rUsing (cpp_using))
7904
7977
return {};
7905
7978
7906
- UNIMPLEMENTED;
7979
+ codet statement (ID_cpp_using);
7980
+ // UNIMPLEMENTED;
7981
+ return std::move (statement);
7907
7982
}
7908
7983
7909
7984
case TOK_STATIC_ASSERT:
@@ -7920,6 +7995,14 @@ std::optional<codet> Parser::rStatement()
7920
7995
return std::move (statement);
7921
7996
}
7922
7997
7998
+ case ' [' :
7999
+ {
8000
+ typet discard;
8001
+ if (!optAttribute (discard))
8002
+ return {};
8003
+ return code_blockt{};
8004
+ }
8005
+
7923
8006
default :
7924
8007
return rExprStatement ();
7925
8008
}
0 commit comments