Skip to content

Commit 87b9431

Browse files
committed
Support Visual Studio's __forceinline
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.
1 parent fa94bc0 commit 87b9431

File tree

5 files changed

+45
-5
lines changed

5 files changed

+45
-5
lines changed

regression/ansi-c/forceinline1/main.i

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#line 1 "test.c"
2+
3+
__inline int foo()
4+
{
5+
return 0;
6+
}
7+
8+
__forceinline int foo()
9+
{
10+
return 1;
11+
}
12+
13+
int main()
14+
{
15+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.i
3+
--i386-win32
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/ansi-c/c_typecheck_base.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,12 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
333333
// gcc allows re-definition if the first
334334
// definition is marked as "extern inline"
335335

336-
if(old_symbol.type.get_bool(ID_C_inlined) &&
337-
(config.ansi_c.mode==configt::ansi_ct::flavourt::GCC ||
338-
config.ansi_c.mode==configt::ansi_ct::flavourt::APPLE ||
339-
config.ansi_c.mode==configt::ansi_ct::flavourt::ARM))
336+
if(
337+
old_symbol.type.get_bool(ID_C_inlined) &&
338+
(config.ansi_c.mode == configt::ansi_ct::flavourt::GCC ||
339+
config.ansi_c.mode == configt::ansi_ct::flavourt::APPLE ||
340+
config.ansi_c.mode == configt::ansi_ct::flavourt::ARM ||
341+
config.ansi_c.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO))
340342
{
341343
// overwrite "extern inline" properties
342344
old_symbol.is_extern=new_symbol.is_extern;

src/ansi-c/parser.y

+15
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ extern char *yyansi_ctext;
165165
%token TOK_MSC_EXCEPT "__except"
166166
%token TOK_MSC_LEAVE "__leave"
167167
%token TOK_MSC_DECLSPEC "__declspec"
168+
%token TOK_MSC_FORCEINLINE "__forceinline"
168169
%token TOK_INTERFACE "__interface"
169170
%token TOK_CDECL "__cdecl"
170171
%token TOK_STDCALL "__stdcall"
@@ -1385,6 +1386,20 @@ storage_class:
13851386
| TOK_THREAD_LOCAL { $$=$1; set($$, ID_thread_local); }
13861387
| TOK_GCC_ASM { $$=$1; set($$, ID_asm); }
13871388
| msc_declspec { $$=$1; }
1389+
| TOK_MSC_FORCEINLINE
1390+
{
1391+
// equivalent to always_inline, and seemingly also has the semantics
1392+
// of extern inline in that multiple definitions can be provided in
1393+
// the same translation unit
1394+
init($$);
1395+
set($$, ID_static);
1396+
set($1, ID_inline);
1397+
$1=merge($1, $$);
1398+
1399+
init($$);
1400+
set($$, ID_always_inline);
1401+
$$=merge($1, $$);
1402+
}
13881403
;
13891404

13901405
basic_type_name:

src/ansi-c/scanner.l

+1-1
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ __decltype { if(PARSER.cpp98 &&
11381138

11391139
"__forceinline" { if(PARSER.mode==configt::ansi_ct::flavourt::VISUAL_STUDIO ||
11401140
PARSER.mode==configt::ansi_ct::flavourt::ARM)
1141-
{ loc(); return TOK_INLINE; }
1141+
{ loc(); return TOK_MSC_FORCEINLINE; }
11421142
else
11431143
return make_identifier();
11441144
}

0 commit comments

Comments
 (0)