262
262
if (token_provider->current () &&
263
263
token_provider->current ()->type () == TOK_LESS) {
266
266
while ((current = token_provider->current ())) {
267
267
token = current->type ();
269
269
if (token == TOK_SEMI_COLON || token == TOK_CLOSE_ROUND ||
270
token == TOK_CLOSE_SQUARE || token == TOK_CLOSE_CURLY)
270
token == TOK_CLOSE_SQUARE || token == TOK_CLOSE_CURLY) {
272
else if (token == TOK_OPEN_ROUND) {
272
} else if (token == TOK_OPEN_ROUND) {
273
273
skip_round_block ();
275
275
} else if (token == TOK_OPEN_CURLY) {
343
343
return last_result;
346
// find out if a qualified name is a template declarator id
347
// rather than a declaration specifier, this is used to
348
// decide when to instantiate a template id
349
bool CCSyntax::is_tpl_declarator_id () {
350
// doesn't matter in parameter declaration
351
if (semantic().in_param_decl_clause() ||
352
semantic().in_template_param_list()) {
356
// only consider names
357
if (! token_provider->current () ||
358
token_provider->current ()->type() != TOK_ID) {
362
State s = token_provider->get_state ();
363
bool result = false, is_tpl_id = false;
365
while (token_provider->current ()) {
366
int token = token_provider->current ()->type ();
369
if (token != TOK_ID) {
370
// operator name is a declarator id
371
result = (token == TOK_OPERATOR);
378
if (token_provider->current () &&
379
token_provider->current ()->type () == TOK_LESS) {
381
skip_block (TOK_LESS, TOK_GREATER);
384
// nested name, go on to next name part
385
if (token_provider->current () &&
386
token_provider->current ()->type () == TOK_COLON_COLON) {
391
// not a nested name, now check for declarator id
392
token = token_provider->current () ? token_provider->current ()->type () : 0;
393
if (token == TOK_OPEN_ROUND) {
394
if (is_ptr_to_fct ()) {
395
// pointer to function or reference to function
400
token = token_provider->current () ? token_provider->current ()->type () : 0;
401
// not a function or array pointer decl?
402
result = (token != TOK_OPEN_ROUND && token != TOK_OPEN_SQUARE);
404
result = (token == TOK_ASSIGN || token == TOK_SEMI_COLON || token == TOK_OPEN_SQUARE);
409
token_provider->set_state (s);
410
return is_tpl_id && result;
413
bool CCSyntax::is_ptr_to_fct () {
414
State s = token_provider->get_state ();
417
// skip all open parentheses
418
while (token_provider->current () && token_provider->current ()->type () == TOK_OPEN_ROUND) {
422
if (token_provider->current ()) {
424
result = token_provider->current ()->type () == TOK_MUL ||
425
token_provider->current ()->type () == TOK_AND;
428
token_provider->set_state (s);
346
432
/*****************************************************************************/
348
434
/* C + + G r a m m a r */
487
return (literal () ||
573
return (literal () ||
490
(parse (TOK_OPEN_ROUND) &&
491
parse (&CCSyntax::expr) &&
492
parse (TOK_CLOSE_ROUND))) ?
493
builder ().prim_expr () : (CTree*)0;
576
(parse (TOK_OPEN_ROUND) &&
577
parse (&CCSyntax::expr) &&
578
parse (TOK_CLOSE_ROUND))) ?
579
builder ().prim_expr () : (CTree*)0;
496
582
bool CCSyntax::prim_expr () {
657
743
if (! parse (&CCSyntax::postfix_expr2))
658
744
return (CTree*)0;
746
bool have_postfix = false;
660
747
CTree *result = builder ().postfix_expr ();
661
748
semantic ().enter_postfix_expr ();
662
749
semantic ().postfix_expr (result);
663
750
while (postfix_expr1 ()) {
664
752
result = builder ().postfix_expr (result);
665
753
semantic ().postfix_expr (result);
667
755
semantic ().leave_postfix_expr ();
756
return have_postfix ? result : semantic ().valid_id_expr (result);
671
759
CTree *CCSyntax::postfix_expr2 () {
672
760
// 1 : cmpd_literal
762
// 1 : construct_expr
763
// 4 : TYPEID ( expr )
764
// 4 : TYPEID ( type_id )
765
// 7 : CONST_CAST < type_id > ( expr )
766
// 7 : REINT_CAST < type_id > ( expr )
767
// 7 : STATIC_CAST < type_id > ( expr )
768
// 7 : DYNAMIC_CAST < type_id > ( expr )
769
static int any_new_cast[] = { TOK_DYN_CAST, TOK_REINT_CAST,
770
TOK_STAT_CAST, TOK_CONST_CAST, 0 };
772
if (parse (any_new_cast)) {
773
return (parse (TOK_LESS) && parse (&CCSyntax::type_id) &&
774
parse (TOK_GREATER) &&
775
parse (TOK_OPEN_ROUND) && parse (&CCSyntax::expr) &&
776
parse (TOK_CLOSE_ROUND)) ?
777
semantic ().postfix_expr2 () : (CTree*)0;
779
// construct expression, compound literal, member access expression
780
else if (parse (&CCSyntax::construct_expr) ||
781
cmpd_literal () || prim_expr ()) {
782
return semantic ().postfix_expr2 ();
785
else if (parse (TOK_TYPEID)) {
786
return (parse (TOK_OPEN_ROUND) &&
787
(parse (&CCSyntax::expr) || parse (&CCSyntax::type_id)) &&
788
parse (TOK_CLOSE_ROUND)) ?
789
semantic ().postfix_expr2 () : (CTree*)0;
794
CTree *CCSyntax::construct_expr () {
674
795
// 3 : simple_type_spec ( )
675
796
// 4 : simple_type_spec ( expr_list )
676
// 4 : TYPEID ( expr )
677
// 4 : TYPEID ( type_id )
678
797
// 5 : TYPENAME nested_name_spec identifier ( )
679
798
// 5 : TYPENAME nested_name_spec template_id ( )
680
799
// 6 : TYPENAME nested_name_spec identifier ( expr_list )
682
801
// 6 : TYPENAME nested_name_spec template_key template_id ( )
683
802
// 6 : TYPENAME :: nested_name_spec identifier ( )
684
803
// 6 : TYPENAME :: nested_name_spec template_id ( )
685
// 7 : CONST_CAST < type_id > ( expr )
686
// 7 : REINT_CAST < type_id > ( expr )
687
// 7 : STATIC_CAST < type_id > ( expr )
688
// 7 : DYNAMIC_CAST < type_id > ( expr )
689
804
// 7 : TYPENAME nested_name_spec template_key template_id ( expr_list )
690
805
// 7 : TYPENAME :: nested_name_spec identifier ( expr_list )
691
806
// 7 : TYPENAME :: nested_name_spec template_id ( expr_list )
692
807
// 7 : TYPENAME :: nested_name_spec template_key template_id ( )
693
808
// 8 : TYPENAME :: nested_name_spec template_key template_id ( expr_list )
694
static int any_new_cast[] = { TOK_DYN_CAST, TOK_REINT_CAST,
695
TOK_STAT_CAST, TOK_CONST_CAST, 0 };
696
// lookahead: check if this is a simple_type_spec (...)
697
State s = save_state ();
698
bool simple_ts = (simple_type_spec () && parse (TOK_OPEN_ROUND));
701
if (parse (any_new_cast)) {
702
return (parse (TOK_LESS) && parse (&CCSyntax::type_id) &&
703
parse (TOK_GREATER) &&
704
parse (TOK_OPEN_ROUND) && parse (&CCSyntax::expr) &&
705
parse (TOK_CLOSE_ROUND)) ?
706
semantic ().postfix_expr2 () : (CTree*)0;
707
// construct expression
708
} else if (parse (TOK_TYPENAME)) {
809
if (parse (TOK_TYPENAME)) {
709
810
return (parse (TOK_COLON_COLON), nested_name_spec () &&
710
811
(template_key () ? template_id () :
711
812
template_id () || identifier ()) &&
712
813
semantic ().reset_search_scope () &&
713
parse (TOK_OPEN_ROUND) &&
814
parse (TOK_OPEN_ROUND) &&
714
815
(parse (&CCSyntax::expr_list), parse (TOK_CLOSE_ROUND))) ?
715
semantic ().postfix_expr2 () : (CTree*)0;
716
// construct expression
717
} else if (simple_ts) {
718
return ((simple_type_spec (), parse (TOK_OPEN_ROUND),
719
parse (&CCSyntax::expr_list), parse (TOK_CLOSE_ROUND))) ?
720
semantic ().postfix_expr2 () : (CTree*)0;
721
// member access expressions
722
} else if (cmpd_literal () || prim_expr ()) {
723
return semantic ().postfix_expr2 ();
726
else if (parse (TOK_TYPEID)) {
727
return (parse (TOK_OPEN_ROUND) &&
728
(parse (&CCSyntax::expr) || parse (&CCSyntax::type_id)) &&
729
parse (TOK_CLOSE_ROUND)) ?
730
semantic ().postfix_expr2 () : (CTree*)0;
816
builder ().construct_expr () : (CTree*)0;
818
return (simple_type_spec () && parse (TOK_OPEN_ROUND) &&
819
(parse (&CCSyntax::expr_list), parse (TOK_CLOSE_ROUND))) ?
820
builder ().construct_expr () : (CTree*)0;
735
823
void CCSyntax::init_postfix_expr1 () {
796
884
// 1: delete_expr
797
885
// 1: postfix_expr
798
888
// 2: any_unary_op cast_expr
799
889
// 2: SIZEOF unary_expr
890
// 2: ALIGNOF unary_expr
800
891
// 4: SIZEOF unary_expr1
892
// 4: ALIGNOF unary_expr1
801
893
static int any_unary_op[] = { TOK_AND, TOK_MUL, TOK_PLUS, TOK_MINUS,
802
894
TOK_TILDE, TOK_NOT, TOK_DECR, TOK_INCR, 0 };
803
895
return (parse (any_unary_op) ?
804
parse (&CCSyntax::cast_expr) :
806
(parse (&CCSyntax::unary_expr1) || parse
807
(&CCSyntax::unary_expr)) :
896
parse (&CCSyntax::cast_expr) :
897
(parse (TOK_SIZEOF) || parse (TOK_ALIGNOF)) ?
898
(parse (&CCSyntax::unary_expr1) || parse (&CCSyntax::unary_expr)) :
808
899
(parse (&CCSyntax::new_expr) ||
809
900
parse (&CCSyntax::delete_expr) ||
901
parse (&CSyntax::offsetof_expr) ||
902
parse (&CCSyntax::type_trait_expr) ||
810
903
parse (&CCSyntax::postfix_expr))) ?
811
904
builder ().unary_expr () : (CTree*)0;
814
CTree *CCSyntax::new_expr () {
907
CTree *CCSyntax::type_trait_expr () {
908
// 4: any_unary_type_trait_op ( type_id )
909
// 6: any_binary_type_trait_op ( type_id , type_id )
910
static int any_unary_type_trait_op[] = {
911
TOK_HAS_NOTHROW_ASSIGN, TOK_HAS_NOTHROW_COPY, TOK_HAS_NOTHROW_CTOR,
912
TOK_HAS_TRIVIAL_ASSIGN, TOK_HAS_TRIVIAL_COPY, TOK_HAS_TRIVIAL_CTOR,
913
TOK_HAS_TRIVIAL_DTOR, TOK_HAS_VIRTUAL_DTOR, TOK_IS_ABSTRACT,
914
TOK_IS_CLASS, TOK_IS_EMPTY, TOK_IS_ENUM, TOK_IS_POD,
915
TOK_IS_POLYMORPHIC, TOK_IS_UNION, 0 };
916
static int any_binary_type_trait_op[] = {
918
return (parse (any_unary_type_trait_op) ?
919
parse (TOK_OPEN_ROUND) &&
920
parse (&CCSyntax::type_id) &&
921
parse (TOK_CLOSE_ROUND) :
922
parse (any_binary_type_trait_op) &&
923
parse (TOK_OPEN_ROUND) &&
924
parse (&CCSyntax::type_id) &&
926
parse (&CCSyntax::type_id) &&
927
parse (TOK_CLOSE_ROUND)) ?
928
builder ().type_trait_expr () : (CTree*)0;
931
CTree *CCSyntax::new_expr () {
815
932
// 2: NEW new_type_id
816
933
// 3: NEW new_type_id new_init
817
934
// 3: NEW new_placement new_type_id
1230
1347
parse (&CCSyntax::rule_elaborated_type_spec);
1350
CTree *CCSyntax::decl_spec_seq1 () {
1352
// if the current template id is part of a declarator id, then it is no
1353
// declaration specifier; declarator ids are not instantiated whereas
1354
// declaration specifiers are instantiated
1355
return is_tpl_declarator_id () ? (CTree*)0 : accept (CSyntax::decl_spec_seq1 ());
1233
1358
CTree *CCSyntax::enumerator_list () {
1234
1359
// 1 : enumerator_def
1235
1360
// 3+: enumerator_def , enumerator_def ..
1861
1988
// 3: access_spec nested_name_spec class_name
1862
1989
// 3: VIRTUAL access_spec class_name
1863
1990
// 3: access_spec VIRTUAL class_name
1991
// 4: :: nested_name_spec template_key class_name
1992
// 4: VIRTUAL nested_name_spec template_key class_name
1993
// 4: access_spec nested_name_spec template_key class_name
1864
1994
// 4: VIRTUAL :: nested_name_spec class_name
1865
1995
// 4: access_spec :: nested_name_spec class_name
1866
1996
// 4: VIRTUAL access_spec nested_name_spec class_name
1867
1997
// 4: access_spec VIRTUAL nested_name_spec class_name
1868
1998
// 4: VIRTUAL access_spec :: class_name
1869
1999
// 4: access_spec VIRTUAL :: class_name
2000
// 5: VIRTUAL :: nested_name_spec template_key class_name
2001
// 5: access_spec :: nested_name_spec template_key class_name
2002
// 5: VIRTUAL access_spec nested_name_spec template_key class_name
2003
// 5: access_spec VIRTUAL nested_name_spec template_key class_name
1870
2004
// 5: VIRTUAL access_spec :: nested_name_spec class_name
1871
2005
// 5: access_spec VIRTUAL :: nested_name_spec class_name
2006
// 6: VIRTUAL access_spec :: nested_name_spec template_key class_name
2007
// 6: access_spec VIRTUAL :: nested_name_spec template_key class_name
1872
2008
bool ok = false;
1873
2009
if (parse (TOK_VIRTUAL) ? opt (access_spec ()) :
1874
2010
(access_spec () ? opt (parse (TOK_VIRTUAL)) : true)) {
1875
2011
colon_colon ();
1876
2012
nested_name_spec ();
1877
2014
semantic ().enter_base_spec ();
1878
2015
ok = class_name ();
1879
2016
semantic ().leave_base_spec ();
2096
2233
// 6: TEMPLATE < template_param_list > CLASS identifier
2097
2234
// 7: TEMPLATE < template_param_list > CLASS = id_expr
2098
2235
// 8: TEMPLATE < template_param_list > CLASS identifier = id_expr
2099
return ((parse (TOK_CLASS) || parse (TOK_TYPENAME)) ?
2100
(identifier () || parse (&CCSyntax::private_name),
2101
parse (TOK_ASSIGN) ? parse (&CCSyntax::type_id) : true) :
2102
parse (TOK_TEMPLATE) &&
2103
parse (TOK_LESS) && parse (&CCSyntax::template_param_list) &&
2104
parse (TOK_GREATER) && parse (TOK_CLASS) &&
2106
parse (TOK_ASSIGN) ?
2107
(semantic ().enter_expr (),
2108
(id_expr () ? semantic ().leave_expr () :
2109
(semantic ().leave_expr (), false))) : true)) ?
2236
return (((parse (TOK_CLASS) || parse (TOK_TYPENAME)) ?
2237
(identifier () || parse (&CCSyntax::private_name),
2238
parse (TOK_ASSIGN) ? parse (&CCSyntax::type_id) : true) :
2239
parse (TOK_TEMPLATE) &&
2240
parse (TOK_LESS) && parse (&CCSyntax::template_param_list) &&
2241
parse (TOK_GREATER) && parse (TOK_CLASS) &&
2242
(identifier () || parse (&CCSyntax::private_name),
2243
parse (TOK_ASSIGN) ?
2244
(semantic ().enter_expr (),
2245
(id_expr () ? semantic ().leave_expr () :
2246
(semantic ().leave_expr (), false))) : true)) &&
2247
(look_ahead (TOK_COMMA) || look_ahead (TOK_GREATER))) ?
2110
2248
semantic ().introduce_type_param () : (CTree*)0;