@@ -243,6 +243,7 @@ class Parser // NOLINT(readability/identifiers)
243
243
bool rLinkageSpec (cpp_linkage_spect &);
244
244
bool rNamespaceSpec (cpp_namespace_spect &);
245
245
bool rUsing (cpp_usingt &);
246
+ bool rUsingOrTypedef (cpp_itemt &);
246
247
bool rStaticAssert (cpp_static_assertt &);
247
248
bool rLinkageBody (cpp_linkage_spect::itemst &);
248
249
bool rTemplateDecl (cpp_declarationt &);
@@ -581,14 +582,8 @@ bool Parser::rDefinition(cpp_itemt &item)
581
582
return rNamespaceSpec (item.make_namespace_spec ());
582
583
else if (t==TOK_INLINE && lex.LookAhead (1 )==TOK_NAMESPACE)
583
584
return rNamespaceSpec (item.make_namespace_spec ());
584
- else if (
585
- t == TOK_USING && is_identifier (lex.LookAhead (1 )) &&
586
- lex.LookAhead (2 ) == ' =' )
587
- {
588
- return rTypedefUsing (item.make_declaration ());
589
- }
590
585
else if (t==TOK_USING)
591
- return rUsing (item. make_using () );
586
+ return rUsingOrTypedef (item);
592
587
else if (t==TOK_STATIC_ASSERT)
593
588
return rStaticAssert (item.make_static_assert ());
594
589
else
@@ -668,6 +663,9 @@ bool Parser::rTypedefUsing(cpp_declarationt &declaration)
668
663
std::cout << std::string (__indent, ' ' ) << " Parser::rTypedefUsing 2\n " ;
669
664
#endif
670
665
666
+ if (!optAttribute (declaration.type ()))
667
+ return false ;
668
+
671
669
if (lex.get_token (tk)!=' =' )
672
670
return false ;
673
671
@@ -901,12 +899,43 @@ bool Parser::rUsing(cpp_usingt &cpp_using)
901
899
if (!rName (cpp_using.name ()))
902
900
return false ;
903
901
902
+ // We will eventually need to record this attribute as Clang's
903
+ // __using_if_exists__ affects type checking.
904
+ typet discard;
905
+ if (!optAttribute (discard))
906
+ return false ;
907
+
904
908
if (lex.get_token (tk)!=' ;' )
905
909
return false ;
906
910
907
911
return true ;
908
912
}
909
913
914
+ /*
915
+ USING Identifier '=' type.specifier ';'
916
+ | using.declaration
917
+ */
918
+ bool Parser::rUsingOrTypedef (cpp_itemt &item)
919
+ {
920
+ cpp_token_buffert::post pos = lex.Save ();
921
+
922
+ cpp_tokent tk;
923
+ if (lex.get_token (tk) != TOK_USING)
924
+ return false ;
925
+
926
+ typet discard;
927
+ if (
928
+ is_identifier (lex.get_token (tk)) && optAttribute (discard) &&
929
+ lex.LookAhead (0 ) == ' =' )
930
+ {
931
+ lex.Restore (pos);
932
+ return rTypedefUsing (item.make_declaration ());
933
+ }
934
+
935
+ lex.Restore (pos);
936
+ return rUsing (item.make_using ());
937
+ }
938
+
910
939
/*
911
940
static_assert.declaration : STATIC_ASSERT ( expression , expression ) ';'
912
941
*/
@@ -4731,14 +4760,8 @@ bool Parser::rClassMember(cpp_itemt &member)
4731
4760
return rTypedef (member.make_declaration ());
4732
4761
else if (t==TOK_TEMPLATE)
4733
4762
return rTemplateDecl (member.make_declaration ());
4734
- else if (
4735
- t == TOK_USING && is_identifier (lex.LookAhead (1 )) &&
4736
- lex.LookAhead (2 ) == ' =' )
4737
- {
4738
- return rTypedefUsing (member.make_declaration ());
4739
- }
4740
4763
else if (t==TOK_USING)
4741
- return rUsing (member. make_using () );
4764
+ return rUsingOrTypedef (member);
4742
4765
else if (t==TOK_STATIC_ASSERT)
4743
4766
return rStaticAssert (member.make_static_assert ());
4744
4767
else
0 commit comments