Skip to content

Commit

Permalink
Support Visual Studio's __forceinline
Browse files Browse the repository at this point in the history
It was previously treated the same as inline/__inline, but Windows header files
come with multiple implementations of functions defined in the same file, with
an expected behaviour similar to "extern inline" in GCC.
  • Loading branch information
tautschnig committed Jul 7, 2018
1 parent fa94bc0 commit 87b9431
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
15 changes: 15 additions & 0 deletions regression/ansi-c/forceinline1/main.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#line 1 "test.c"

__inline int foo()
{
return 0;
}

__forceinline int foo()
{
return 1;
}

int main()
{
}
8 changes: 8 additions & 0 deletions regression/ansi-c/forceinline1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.i
--i386-win32
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
^CONVERSION ERROR$
10 changes: 6 additions & 4 deletions src/ansi-c/c_typecheck_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,12 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
// gcc allows re-definition if the first
// definition is marked as "extern inline"

if(old_symbol.type.get_bool(ID_C_inlined) &&
(config.ansi_c.mode==configt::ansi_ct::flavourt::GCC ||
config.ansi_c.mode==configt::ansi_ct::flavourt::APPLE ||
config.ansi_c.mode==configt::ansi_ct::flavourt::ARM))
if(
old_symbol.type.get_bool(ID_C_inlined) &&
(config.ansi_c.mode == configt::ansi_ct::flavourt::GCC ||
config.ansi_c.mode == configt::ansi_ct::flavourt::APPLE ||
config.ansi_c.mode == configt::ansi_ct::flavourt::ARM ||
config.ansi_c.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO))
{
// overwrite "extern inline" properties
old_symbol.is_extern=new_symbol.is_extern;
Expand Down
15 changes: 15 additions & 0 deletions src/ansi-c/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ extern char *yyansi_ctext;
%token TOK_MSC_EXCEPT "__except"
%token TOK_MSC_LEAVE "__leave"
%token TOK_MSC_DECLSPEC "__declspec"
%token TOK_MSC_FORCEINLINE "__forceinline"
%token TOK_INTERFACE "__interface"
%token TOK_CDECL "__cdecl"
%token TOK_STDCALL "__stdcall"
Expand Down Expand Up @@ -1385,6 +1386,20 @@ storage_class:
| TOK_THREAD_LOCAL { $$=$1; set($$, ID_thread_local); }
| TOK_GCC_ASM { $$=$1; set($$, ID_asm); }
| msc_declspec { $$=$1; }
| TOK_MSC_FORCEINLINE
{
// equivalent to always_inline, and seemingly also has the semantics
// of extern inline in that multiple definitions can be provided in
// the same translation unit
init($$);
set($$, ID_static);
set($1, ID_inline);
$1=merge($1, $$);

init($$);
set($$, ID_always_inline);
$$=merge($1, $$);
}
;

basic_type_name:
Expand Down
2 changes: 1 addition & 1 deletion src/ansi-c/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ __decltype { if(PARSER.cpp98 &&

"__forceinline" { if(PARSER.mode==configt::ansi_ct::flavourt::VISUAL_STUDIO ||
PARSER.mode==configt::ansi_ct::flavourt::ARM)
{ loc(); return TOK_INLINE; }
{ loc(); return TOK_MSC_FORCEINLINE; }
else
return make_identifier();
}
Expand Down

0 comments on commit 87b9431

Please sign in to comment.