clang doesn't compile simple code

Hi

Here is a sample code :

typedef int (_cdecl * func1 )( void );
typedef int (_stdcall * func2 )( void );

which clang doesn't compile.
Actually it compiles it on Win with compiler from Windows snapshot builds
<http://llvm.org/builds/&gt;
While on Ubuntu (apt-get ...) or on Windows pacman from MSYS2
<http://sourceforge.net/projects/msys2/&gt; doesn,t compile.

Problem is:
While gcc preprocesor (mingw on win32 or gcc on linux) translates code to

typedef int (__attribute__((__cdecl__)) * func1 )( void );
typedef int (__attribute__((__stdcall__)) * func2 )( void );

and then translates it to object file, clang preprocesor lives code as it is
and then throws error.

Solutuion:
If i explicitly change source code to:

typedef int (__attribute__((__cdecl__)) * func1 )( void );
typedef int (__attribute__((__stdcall__)) * func2 )( void );

and then compile it with clang , it compiles OK.

regards
Franček

Add the -fms-extensions flag to enable support for __cdecl and __stdcall, as well as other things like __declspec(dllexport).

Alternatively, pass a triple flag that doesn’t mention mingw to get this behavior by default, like --target=i686-pc-win32.

Hi

Thanks Reid.
I tried it before and it actually works in this simple case.

The problem is that I have I big project with about 10000 files which
is portable and which compiles fine on many platforms
(win,linux,bsd,osx,android) with many compilers.

Before -fms-extensions I had a few errors in only one file
(which i can solve with a few #ifdef tricks).

After I put globaly - CFLAGS +=-fms-extensions in my make file , I get
houndreds of errors in connection with intrinsics.
Like :
../intrin-impl.h:960:10: error: definition of builtin function
'_InterlockedExchangeAdd'
__LONG32 _InterlockedExchangeAdd(__LONG32 volatile *Addend, __LONG32 Value)
{

...

Of course I can make bigger changes in my build system or in my header
files.
But I think that main idea is that we will have on windows two clang
compilers.
One msvc compatible (name ,abi, parameters ...) which will be replacement
for msvc compiler and
other mingw (gcc) compatible.

There are thousands of prejects which compile fine with gcc (mingw).
It would be a nice if they compile out of a box with clang (with maybe some
additional attribute).

regards
Franček

We already define __declspec for mingw compatibility, so adding the ccs seems reasonable.

I’m curious if you can fix most of your errors with -fms-extensions by dropping your intrin-impl.h header and including clang’s intrin.h instead. You’ll have to hack out the _MSC_VER ifdef there. If that works, it might be worth making clang’s intrin.h header available when targeting mingw.

Hi

Here is sample output from compiling libpng which is part of our platform.

clang -I. -I../../../../../../include -Wmissing-braces -Wreturn-type
-Wformat -Wimplicit-int
-Wimplicit-function-declaration -O3 -DUNICODE
-IG:/HRB_SVN/SRC-GIT/src/3rd/zlib -DPNG_NO_STDIO
-IC:/msys32/mingw32/lib/clang/3.5.0/include -fms-extensions -opng.o -c
../../../png.c

In file included from ../../../png.c:14:
In file included from ../../../pngpriv.h:462:
In file included from
C:/msys32/mingw32/bin/../i686-w64-mingw32/include\windows.h:69:
In file included from
C:/msys32/mingw32/bin/../i686-w64-mingw32/include\windef.h:8:
In file included from
C:/msys32/mingw32/bin/../i686-w64-mingw32/include\minwindef.h:146:
In file included from
C:/msys32/mingw32/bin/../i686-w64-mingw32/include\winnt.h:26:
C:/msys32/mingw32/bin/../i686-w64-mingw32/include\psdk_inc/intrin-impl.h:960:10:
error: definition of builtin function
'_InterlockedExchangeAdd'
__LONG32 _InterlockedExchangeAdd(__LONG32 volatile *Addend, __LONG32 Value)
{

As you see intrin-impl.h is included from winnt.h

#define __INTRINSIC_GROUP_WINNT /* only define the intrinsics in this file
*/
#include <psdk_inc/intrin-impl.h>

I also did a little hack changing psdk/intrin-impl to intrin.h in winnt.h
and here is result:

clang -I. -I../../../../../../include -Wmissing-braces -Wreturn-type
-Wformat -Wimplicit-int -Wimplicit-function-declaration -O3 -DUNICODE
-IG:/HRB_SVN/SRC-GIT/src/3rd/zlib -DPNG_NO_STDIO
-IC:/msys32/mingw32/lib/clang/3.5.0/include -fms-extensions -opng.o -c
../../../png.c
In file included from ../../../png.c:14:
In file included from ../../../pngpriv.h:462:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\windows.h:69:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\windef.h:8:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\minwindef.h:146:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\winnt.h:27:
C:/msys32/mingw32/lib/clang/3.5.0/include/intrin.h:294:13: error:
conflicting types for '_setjmp'
int __cdecl _setjmp(jmp_buf);
            ^
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\setjmp.h:164:63: note:
previous declaration is here
  int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
_setjmp(jmp_buf _Buf, void *_Ctx);

            ^
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\setjmp.h:164:63: note:
previous declaration is here
  int __cdecl __attribute__ ((__nothrow__,__returns_twice__))
_setjmp(jmp_buf _Buf, void *_Ctx);
                                                              ^
In file included from ../../../png.c:14:
In file included from ../../../pngpriv.h:462:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\windows.h:70:
In file included from
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\winbase.h:45:
C:\msys32\mingw32\bin/../i686-w64-mingw32/include\psdk_inc/intrin-impl.h:849:13:
error: redefinition of '__stosb'
__buildstos(__stosb, unsigned char, "b")
....

IMHO the simplest solution would be if clang/gcc preprocessor translates
_cdecl,_stdcall,... to
__attribute__((...)) .

regards
Franček

Hi

I just noticed (if i am not wrong) that in the SVN revision 206791
in Targets.cpp something is happening:

static void addMinGWDefines
....

Hi

I solved the problem.
IMHO the simplest dirty way.
I just added

CFLAGS+=-D_cdecl=__attribute__((__cdecl__))
-D_stdcall=__attribute__((__stdcall__))

to my make file and everything compiles fine.

When I inspect clang macro definitions with clang -dD -E ...,
I see that there is allready :

#define __declspec(a) __attribute__((a))

Why not others? :

#define _cdecl __attribute__((__cdecl__))
#define __cdecl __attribute__((__cdecl__))
#define _stdcall __attribute__((__stdcall__))
.....

regards
Franček

Yep, that’s what r206791 does. If you update and rebuild you should see it.

Hi

Thanks.

After this commit I can compile all my files and create static libs.
There is still a problem creating shared libs (with *clang -shared*).
Any solution?

regards
Franček

No idea. This isn't enough information, and I'm not a mingw expert.

Hi

Here is simple example and the description of the problem.

--- main.c ----

#include <stdio.h>
#include "dll.h"

int main(void)
{
    hello("World");
    return 0;
}

---- dll.h -------------

#ifndef DLL_H
#define DLL_H

#ifdef BUILDING_DLL
#define MY_DLL __declspec(dllexport)
#else
#define MY_DLL __declspec(dllimport)
#endif

void MY_DLL hello(const char *s);
#endif

---- dll.c -------------

#include <stdio.h>
#include "dll.h"

void hello(const char *s)
{
   printf("Hello %s\n", s);
}

---- build.bat -----

clang -c -DBUILDING_DLL dll.c
clang -shared -o dll.dll dll.o -Wl,--out-implib,libdll.a

clang -c main.c
clang -o main.exe main.o -L. -ldll

Hi

By the way I am working with:

clang version 3.5.0 (207372)
Target: i686-pc-windows-gnu
Thread model: posix

Hi

Here is a problem:
64bit clang with 64 bit mingw is OK, while 32bit clang is producing wrong
COFF.

Here is two liner:

--- test.c ---------------

#include <stdio.h>

void __declspec(dllexport) hello(const char *s);

void hello(const char *s)
{
   printf("Hello %s\n", s);
}

---- build.bat -----

clang -c test.c
gcc -shared -o test.dll test.o -Wl,--out-implib,test.a

Error from 32bit clang (64bit no error):

Cannot export _hello: symbol not found
collect2.exe: error: ld returned 1 exit status

I intentionaly use gcc -shared to show that the problem is in clang
compiler (32bit) producing a wrong test.o,
while 64bti version is ok ( wheter I use gcc -shared or clang -shared and
later link test.dll to main.c)

regards
Franček