@@ -243,6 +243,7 @@ class Parser // NOLINT(readability/identifiers)
243243 bool rLinkageSpec (cpp_linkage_spect &);
244244 bool rNamespaceSpec (cpp_namespace_spect &);
245245 bool rUsing (cpp_usingt &);
246+ bool rUsingOrTypedef (cpp_itemt &);
246247 bool rStaticAssert (cpp_static_assertt &);
247248 bool rLinkageBody (cpp_linkage_spect::itemst &);
248249 bool rTemplateDecl (cpp_declarationt &);
@@ -581,14 +582,8 @@ bool Parser::rDefinition(cpp_itemt &item)
581582 return rNamespaceSpec (item.make_namespace_spec ());
582583 else if (t==TOK_INLINE && lex.LookAhead (1 )==TOK_NAMESPACE)
583584 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- }
590585 else if (t==TOK_USING)
591- return rUsing (item. make_using () );
586+ return rUsingOrTypedef (item);
592587 else if (t==TOK_STATIC_ASSERT)
593588 return rStaticAssert (item.make_static_assert ());
594589 else
@@ -668,6 +663,9 @@ bool Parser::rTypedefUsing(cpp_declarationt &declaration)
668663 std::cout << std::string (__indent, ' ' ) << " Parser::rTypedefUsing 2\n " ;
669664#endif
670665
666+ if (!optAttribute (declaration.type ()))
667+ return false ;
668+
671669 if (lex.get_token (tk)!=' =' )
672670 return false ;
673671
@@ -901,12 +899,43 @@ bool Parser::rUsing(cpp_usingt &cpp_using)
901899 if (!rName (cpp_using.name ()))
902900 return false ;
903901
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+
904908 if (lex.get_token (tk)!=' ;' )
905909 return false ;
906910
907911 return true ;
908912}
909913
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+
910939/*
911940 static_assert.declaration : STATIC_ASSERT ( expression , expression ) ';'
912941*/
@@ -4739,14 +4768,8 @@ bool Parser::rClassMember(cpp_itemt &member)
47394768 return rTypedef (member.make_declaration ());
47404769 else if (t==TOK_TEMPLATE)
47414770 return rTemplateDecl (member.make_declaration ());
4742- else if (
4743- t == TOK_USING && is_identifier (lex.LookAhead (1 )) &&
4744- lex.LookAhead (2 ) == ' =' )
4745- {
4746- return rTypedefUsing (member.make_declaration ());
4747- }
47484771 else if (t==TOK_USING)
4749- return rUsing (member. make_using () );
4772+ return rUsingOrTypedef (member);
47504773 else if (t==TOK_STATIC_ASSERT)
47514774 return rStaticAssert (member.make_static_assert ());
47524775 else
0 commit comments