Skip to content

Commit

Permalink
Support __attribute__((constructor))
Browse files Browse the repository at this point in the history
  • Loading branch information
tautschnig committed May 18, 2016
1 parent e35f6b7 commit 3f01cce
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 5 deletions.
31 changes: 31 additions & 0 deletions src/ansi-c/ansi_c_convert_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ void ansi_c_convert_typet::read_rec(const typet &type)
}
else if(type.id()==ID_noreturn)
c_qualifiers.is_noreturn=true;
else if(type.id()==ID_constructor)
constructor=true;
else if(type.id()==ID_destructor)
destructor=true;
else
other.push_back(type);
}
Expand Down Expand Up @@ -274,6 +278,33 @@ void ansi_c_convert_typet::write(typet &type)
}

type.swap(other.front());

if(constructor || destructor)
{
if(constructor && destructor)
{
err_location(source_location);
str << "combining constructor and destructor not supported";
error_msg();
throw 0;
}
else if(type.id()!=ID_empty)
{
err_location(source_location);
str << "constructor and destructor required to be type void";
error_msg();
throw 0;
}

type.id(constructor ? ID_constructor : ID_destructor);
}
}
else if(constructor || destructor)
{
err_location(source_location);
str << "constructor and destructor required to be type void";
error_msg();
throw 0;
}
else if(gcc_float128_cnt)
{
Expand Down
3 changes: 2 additions & 1 deletion src/ansi-c/ansi_c_convert_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ansi_c_convert_typet:public message_streamt
bool packed, aligned;
exprt vector_size, alignment, bv_width, fraction_width;
exprt msc_based; // this is Visual Studio
bool constructor, destructor;

// storage spec
c_storage_spect c_storage_spec;
Expand Down Expand Up @@ -67,7 +68,7 @@ class ansi_c_convert_typet:public message_streamt
msc_based.make_nil();
gcc_attribute_mode.make_nil();

packed=aligned=false;
packed=aligned=constructor=destructor=false;

other.clear();
c_storage_spec.clear();
Expand Down
5 changes: 5 additions & 0 deletions src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,11 @@ std::string expr2ct::convert_rec(
{
return q+"__builtin_va_list"+d;
}
else if(src.id()==ID_constructor ||
src.id()==ID_destructor)
{
return q+"__attribute__(("+id2string(src.id())+")) void"+d;
}

{
lispexprt lisp;
Expand Down
6 changes: 6 additions & 0 deletions src/ansi-c/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ extern char *yyansi_ctext;
%token TOK_GCC_ATTRIBUTE_GNU_INLINE "__gnu_inline__"
%token TOK_GCC_ATTRIBUTE_WEAK "weak"
%token TOK_GCC_ATTRIBUTE_NORETURN "noreturn"
%token TOK_GCC_ATTRIBUTE_CONSTRUCTOR "constructor"
%token TOK_GCC_ATTRIBUTE_DESTRUCTOR "destructor"
%token TOK_GCC_ATTRIBUTE_END ")"
%token TOK_GCC_LABEL "__label__"
%token TOK_MSC_ASM "__asm"
Expand Down Expand Up @@ -1566,6 +1568,10 @@ gcc_type_attribute:
{ $$=$1; set($$, ID_noreturn); }
| TOK_GCC_ATTRIBUTE_NORETURN TOK_GCC_ATTRIBUTE_END
{ $$=$1; set($$, ID_noreturn); }
| TOK_GCC_ATTRIBUTE_CONSTRUCTOR TOK_GCC_ATTRIBUTE_END
{ $$=$1; set($$, ID_constructor); }
| TOK_GCC_ATTRIBUTE_DESTRUCTOR TOK_GCC_ATTRIBUTE_END
{ $$=$1; set($$, ID_destructor); }
| gcc_attribute_specifier
;

Expand Down
6 changes: 6 additions & 0 deletions src/ansi-c/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,12 @@ __decltype { if(PARSER.cpp98 && PARSER.mode==ansi_c_parsert::GCC)
"noreturn" |
"__noreturn__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_NORETURN; }

"constructor" |
"__constructor__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_CONSTRUCTOR; }

"destructor" |
"__destructor__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_DESTRUCTOR; }

{ws} { /* ignore */ }
{newline} { /* ignore */ }
{identifier} { BEGIN(GCC_ATTRIBUTE4); }
Expand Down
3 changes: 1 addition & 2 deletions src/cpp/cpp_typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,7 @@ void cpp_typecheckt::static_and_dynamic_initialization()
init_symbol.mode=ID_cpp;
init_symbol.module=module;
init_symbol.type=code_typet();
init_symbol.type.add(ID_return_type)=typet(ID_empty);
init_symbol.type.set("initialization", true);
init_symbol.type.add(ID_return_type)=typet(ID_constructor);
init_symbol.is_type=false;
init_symbol.is_macro=false;

Expand Down
9 changes: 9 additions & 0 deletions src/linking/remove_internal_symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ void remove_internal_symbols(
symbol.value.is_not_nil() &&
!symbol.value.get_bool(ID_C_zero_initializer);

// __attribute__((constructor)), __attribute__((destructor))
if(symbol.mode==ID_C && is_function && is_file_local)
{
const code_typet &code_type=to_code_type(symbol.type);
if(code_type.return_type().id()==ID_constructor ||
code_type.return_type().id()==ID_destructor)
is_file_local=false;
}

if(is_type)
{
// never EXPORTED by itself
Expand Down
4 changes: 2 additions & 2 deletions src/linking/static_lifetime_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ bool static_lifetime_init(
{
const symbolt &symbol=ns.lookup(id);

if(symbol.type.get_bool("initialization") &&
symbol.type.id()==ID_code)
if(symbol.type.id()==ID_code &&
to_code_type(symbol.type).return_type().id()==ID_constructor)
{
code_function_callt function_call;
function_call.function()=symbol.symbol_expr();
Expand Down

0 comments on commit 3f01cce

Please sign in to comment.