Skip to content

Commit

Permalink
C++ front-end: parse GCC attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
tautschnig committed Jun 11, 2018
1 parent 1f9deb3 commit fde09ca
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 15 deletions.
11 changes: 3 additions & 8 deletions src/ansi-c/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -938,14 +938,9 @@ __decltype { if(PARSER.cpp98 &&
PARSER.mode==configt::ansi_ct::flavourt::CODEWARRIOR ||
PARSER.mode==configt::ansi_ct::flavourt::ARM)
{
if(PARSER.cpp98)
BEGIN(IGNORE_PARENS);
else
{
BEGIN(GCC_ATTRIBUTE1);
loc();
return TOK_GCC_ATTRIBUTE;
}
BEGIN(GCC_ATTRIBUTE1);
loc();
return TOK_GCC_ATTRIBUTE;
}
else
return make_identifier();
Expand Down
4 changes: 4 additions & 0 deletions src/cpp/cpp_typecheck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ void cpp_typecheckt::typecheck_type(typet &type)
if(type.subtype().get_bool(ID_C_volatile))
type.set(ID_C_volatile, true);
}
else if(type.id()==ID_vector)
{
typecheck_vector_type(to_vector_type(type));
}
else if(type.id()==ID_code)
{
code_typet &code_type=to_code_type(type);
Expand Down
194 changes: 187 additions & 7 deletions src/cpp/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class Parser // NOLINT(readability/identifiers)
bool optStorageSpec(cpp_storage_spect &);
bool optCvQualify(typet &);
bool optAlignas(typet &);
bool rAttribute();
bool rAttribute(typet &);
bool optAttribute(cpp_declarationt &);
bool optIntegralTypeOrClassSpec(typet &);
bool rConstructorDecl(
Expand Down Expand Up @@ -473,8 +473,10 @@ void Parser::merge_types(const typet &src, typet &dest)
{
if(dest.id()!=ID_merged_type)
{
source_locationt location=dest.source_location();
typet tmp(ID_merged_type);
tmp.move_to_subtypes(dest);
tmp.add_source_location()=location;
dest=tmp;
}

Expand Down Expand Up @@ -2044,7 +2046,7 @@ bool Parser::optCvQualify(typet &cv)
break;

case TOK_GCC_ATTRIBUTE:
if(!rAttribute())
if(!rAttribute(cv))
return false;
break;

Expand Down Expand Up @@ -2103,28 +2105,204 @@ bool Parser::optAlignas(typet &cv)
return true;
}

bool Parser::rAttribute()
bool Parser::rAttribute(typet &t)
{
#ifdef DEBUG
indenter _i;
std::cout << std::string(__indent, ' ') << "Parser::rAttribute "
<< lex.LookAhead(0);
#endif
cpp_tokent tk;
lex.get_token(tk);

switch(tk.kind)
{
case '(':
rAttribute();
if(lex.LookAhead(0)!=')')
rAttribute(t);

if(lex.LookAhead(0)!=')')
return false;
lex.get_token(tk);
break;
return true;

case TOK_IDENTIFIER:
case TOK_GCC_ATTRIBUTE_PACKED:
{
typet attr(ID_packed);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_TRANSPARENT_UNION:
{
typet attr(ID_transparent_union);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_VECTOR_SIZE:
{
cpp_tokent tk2, tk3;

if(lex.get_token(tk2)!='(')
return false;

exprt exp;
if(!rCommaExpression(exp))
return false;

if(lex.get_token(tk3)!=')')
return false;

vector_typet attr(nil_typet(), exp);
attr.add_source_location()=exp.source_location();
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_ALIGNED:
{
typet attr(ID_aligned);
set_location(attr, tk);

if(lex.LookAhead(0)=='(')
{
cpp_tokent tk2, tk3;

if(lex.get_token(tk2)!='(')
return false;

exprt exp;
if(!rCommaExpression(exp))
return false;

if(lex.get_token(tk3)!=')')
return false;

attr.add(ID_size, exp);
}

merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_MODE:
{
cpp_tokent tk2, tk3;

if(lex.get_token(tk2)!='(')
return false;

irept name;
if(!rName(name))
return false;

if(lex.get_token(tk3)!=')')
return false;

typet attr(ID_gcc_attribute_mode);
set_location(attr, tk);
attr.set(ID_size, name.get(ID_identifier));
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_GNU_INLINE:
{
typet attr(ID_static);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_WEAK:
{
typet attr(ID_weak);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_ALIAS:
{
cpp_tokent tk2, tk3, tk4;

if(lex.get_token(tk2)!='(')
return false;

if(!rString(tk3))
return false;

if(lex.get_token(tk4)!=')')
return false;

typet attr(ID_alias);
set_location(attr, tk);
attr.move_to_sub(tk3.data);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_SECTION:
{
cpp_tokent tk2, tk3, tk4;

if(lex.get_token(tk2)!='(')
return false;

if(!rString(tk3))
return false;

if(lex.get_token(tk4)!=')')
return false;

typet attr(ID_section);
set_location(attr, tk);
attr.move_to_sub(tk3.data);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_NORETURN:
{
typet attr(ID_noreturn);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_CONSTRUCTOR:
{
typet attr(ID_constructor);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case TOK_GCC_ATTRIBUTE_DESTRUCTOR:
{
typet attr(ID_destructor);
set_location(attr, tk);
merge_types(attr, t);
break;
}

case ',':
if(lex.LookAhead(0)==')')
// the scanner ignored an attribute
return true;
break;

default:
return false;
}

return true;
if(lex.LookAhead(0)==')')
return true;

return rAttribute(t);
}

bool Parser::optAttribute(cpp_declarationt &declaration)
Expand Down Expand Up @@ -2971,6 +3149,8 @@ bool Parser::rDeclarator(
break;
}

optCvQualify(d_outer);

#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rDeclarator2 13\n";
#endif
Expand Down

0 comments on commit fde09ca

Please sign in to comment.