Skip to content

Commit 1ca5700

Browse files
committed
C++ front-end: permit GCC attributes in using declarations
LLVM's standard library uses these in type_traits.
1 parent 401abcc commit 1ca5700

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

regression/cpp/using1/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifdef __GNUC__
2+
using type __attribute__((__nodebug__)) = int;
3+
4+
typedef int my_int_t;
5+
namespace N {
6+
using ::my_int_t __attribute__((__using_if_exists__));
7+
}
8+
#endif
9+
10+
int main(int argc, char* argv[])
11+
{
12+
}

regression/cpp/using1/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.cpp
3+
-std=c++11
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/cpp/parse.cpp

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)