23
23
#include " cpp_member_spec.h"
24
24
#include " cpp_enum_type.h"
25
25
26
- // #define DEBUG
26
+ #define DEBUG
27
27
#ifdef DEBUG
28
28
#include < iostream>
29
29
@@ -346,7 +346,6 @@ class Parser // NOLINT(readability/identifiers)
346
346
bool rPostfixExpr (exprt &);
347
347
bool rPrimaryExpr (exprt &);
348
348
bool rVarName (exprt &);
349
- bool rVarNameCore (exprt &);
350
349
bool maybeTemplateArgs ();
351
350
352
351
bool rFunctionBody (cpp_declaratort &);
@@ -778,7 +777,7 @@ bool Parser::isTypeSpecifier()
778
777
t == TOK_CPROVER_BOOL || t == TOK_CLASS || t == TOK_STRUCT ||
779
778
t == TOK_UNION || t == TOK_ENUM || t == TOK_INTERFACE ||
780
779
t == TOK_TYPENAME || t == TOK_TYPEOF || t == TOK_DECLTYPE ||
781
- t == TOK_UNDERLYING_TYPE;
780
+ t == TOK_UNDERLYING_TYPE || t == TOK_ATOMIC_TYPE_SPECIFIER ;
782
781
}
783
782
784
783
/*
@@ -1336,31 +1335,61 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration)
1336
1335
if (!rTemplateDecl2 (template_type, kind))
1337
1336
return false ;
1338
1337
1339
- // TODO
1340
-
1341
- cpp_tokent tk1, tk2;
1338
+ cpp_tokent tk1;
1342
1339
1343
1340
if (lex.get_token (tk1) != TOK_CLASS)
1344
1341
return false ;
1345
1342
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 ) == ' >' )
1347
1358
return true ;
1348
1359
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
1350
1378
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
+
1355
1380
if (lex.LookAhead (0 )==' =' )
1356
1381
{
1382
+ if (declarator.get_has_ellipsis ())
1383
+ return false ;
1384
+
1357
1385
typet default_type;
1386
+
1358
1387
lex.get_token (tk1);
1359
1388
if (!rTypeName (default_type))
1360
- return false ;
1389
+ return false ;
1361
1390
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 );
1364
1393
}
1365
1394
}
1366
1395
else
@@ -1487,6 +1516,10 @@ bool Parser::rDeclaration(cpp_declarationt &declaration)
1487
1516
cpp_member_spect member_spec;
1488
1517
if (!optMemberSpec (member_spec))
1489
1518
return false ;
1519
+ if (!optAttribute (declaration.type ()))
1520
+ return false ;
1521
+ if (!optMemberSpec (member_spec))
1522
+ return false ;
1490
1523
1491
1524
#ifdef DEBUG
1492
1525
std::cout << std::string (__indent, ' ' ) << " Parser::rDeclaration 0.2\n " ;
@@ -2051,8 +2084,6 @@ bool Parser::isPtrToMember(int i)
2051
2084
*/
2052
2085
bool Parser::optMemberSpec (cpp_member_spect &member_spec)
2053
2086
{
2054
- member_spec.clear ();
2055
-
2056
2087
int t=lex.LookAhead (0 );
2057
2088
2058
2089
while (
@@ -2502,6 +2533,17 @@ bool Parser::optAttribute(typet &t)
2502
2533
break ;
2503
2534
}
2504
2535
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
+
2505
2547
default :
2506
2548
// TODO: way may wish to change this: GCC, Clang, Visual Studio merely
2507
2549
// warn when they see an attribute that they don't recognize
@@ -2737,8 +2779,34 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
2737
2779
2738
2780
return true ;
2739
2781
}
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
+ }
2740
2804
else
2741
2805
{
2806
+ #ifdef DEBUG
2807
+ std::cout << std::string (__indent, ' ' )
2808
+ << " Parser::optIntegralTypeOrClassSpec 10\n " ;
2809
+ #endif // DEBUG
2742
2810
p.make_nil ();
2743
2811
return true ;
2744
2812
}
@@ -3774,7 +3842,7 @@ bool Parser::rName(irept &name)
3774
3842
components.back ().add (ID_expr_arg).swap (expr);
3775
3843
3776
3844
if (lex.LookAhead (0 ) != TOK_SCOPE)
3777
- return false ;
3845
+ return true ;
3778
3846
}
3779
3847
break ;
3780
3848
@@ -4549,6 +4617,9 @@ bool Parser::rEnumSpec(typet &spec)
4549
4617
spec.set (ID_C_class, true );
4550
4618
}
4551
4619
4620
+ if (!optAttribute (spec))
4621
+ return false ;
4622
+
4552
4623
if (lex.LookAhead (0 )!=' {' &&
4553
4624
lex.LookAhead (0 )!=' :' )
4554
4625
{
@@ -4715,7 +4786,7 @@ bool Parser::rClassSpec(typet &spec)
4715
4786
if (!optAttribute (spec))
4716
4787
return false ;
4717
4788
4718
- if (lex.LookAhead (0 )==' {' )
4789
+ if (lex.LookAhead (0 )==' {' || lex. LookAhead ( 0 ) == ' : ' )
4719
4790
{
4720
4791
// no tag
4721
4792
#ifdef DEBUG
@@ -4734,21 +4805,21 @@ bool Parser::rClassSpec(typet &spec)
4734
4805
#ifdef DEBUG
4735
4806
std::cout << std::string (__indent, ' ' ) << " Parser::rClassSpec 5\n " ;
4736
4807
#endif
4808
+ }
4737
4809
4738
- t=lex.LookAhead (0 );
4810
+ t=lex.LookAhead (0 );
4739
4811
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 ;
4752
4823
}
4753
4824
4754
4825
#ifdef DEBUG
@@ -6721,7 +6792,10 @@ bool Parser::rPostfixExpr(exprt &exp)
6721
6792
}
6722
6793
6723
6794
#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 ' ;
6725
6799
#endif
6726
6800
6727
6801
exprt e;
@@ -7276,16 +7350,7 @@ bool Parser::rVarName(exprt &name)
7276
7350
<< ' \n ' ;
7277
7351
#endif
7278
7352
7279
- if (rVarNameCore (name))
7280
- return true ;
7281
- else
7282
- return false ;
7283
- }
7284
-
7285
- bool Parser::rVarNameCore (exprt &name)
7286
- {
7287
7353
#ifdef DEBUG
7288
- indenter _i;
7289
7354
std::cout << std::string (__indent, ' ' ) << " Parser::rVarNameCore 0\n " ;
7290
7355
#endif
7291
7356
@@ -7458,7 +7523,7 @@ bool Parser::moreVarName()
7458
7523
/*
7459
7524
template.args : '<' any* '>'
7460
7525
7461
- template.args must be followed by '(' or '::'
7526
+ template.args must be followed by '(', '::', or '; '
7462
7527
*/
7463
7528
bool Parser::maybeTemplateArgs ()
7464
7529
{
@@ -7480,7 +7545,8 @@ bool Parser::maybeTemplateArgs()
7480
7545
return false ;
7481
7546
else if ((u==' >' || u==TOK_SHIFTRIGHT) &&
7482
7547
(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) == ' ;' ))
7484
7550
return true ;
7485
7551
}
7486
7552
#else
@@ -7903,7 +7969,9 @@ std::optional<codet> Parser::rStatement()
7903
7969
if (!rUsing (cpp_using))
7904
7970
return {};
7905
7971
7906
- UNIMPLEMENTED;
7972
+ codet statement (ID_cpp_using);
7973
+ // UNIMPLEMENTED;
7974
+ return std::move (statement);
7907
7975
}
7908
7976
7909
7977
case TOK_STATIC_ASSERT:
@@ -7920,6 +7988,14 @@ std::optional<codet> Parser::rStatement()
7920
7988
return std::move (statement);
7921
7989
}
7922
7990
7991
+ case ' [' :
7992
+ {
7993
+ typet discard;
7994
+ if (!optAttribute (discard))
7995
+ return {};
7996
+ return code_blockt{};
7997
+ }
7998
+
7923
7999
default :
7924
8000
return rExprStatement ();
7925
8001
}
0 commit comments