Implementation of stdbool.h

Per title, this is an implementation of stdbool.h, to start off the
project of clang getting its own headers. I picked stdbool.h because
it is one of the simplest standard headers, being that it only has
four straightforward macros. It would be embarrassing if I screwed it
up somehow :slight_smile:

I'm not completely sure if I got the license part right... is some
sort of special exception needed in the headers so programs compiled
with clang aren't under the clang license?

sabre indicated on IRC that he might get the build system and driver
and whatnot setup for clang to have its own headers sometime in the
near future, so I prepared this to allow for testing.

-Eli

temp8.txt (700 Bytes)

This is a bit irrelevant in more than one way at the moment, but for
future G++ compatibility there should be a check for __cplusplus. (Does
the GCC compatibility of clang extend beyond the command-line parameters
of the ccc wrapper script?)

timo

Eli Friedman wrote:-

Per title, this is an implementation of stdbool.h, to start off the
project of clang getting its own headers. I picked stdbool.h because
it is one of the simplest standard headers, being that it only has
four straightforward macros. It would be embarrassing if I screwed it
up somehow :slight_smile:

Oops, how embarrassing :slight_smile:

Neil Booth wrote:-

Eli Friedman wrote:-

> Per title, this is an implementation of stdbool.h, to start off the
> project of clang getting its own headers. I picked stdbool.h because
> it is one of the simplest standard headers, being that it only has
> four straightforward macros. It would be embarrassing if I screwed it
> up somehow :slight_smile:

Oops, how embarrassing :slight_smile:

> +#define bool _Bool

Now it's my turn to be embarrassed. <slinks away>

This is a bit irrelevant in more than one way at the moment, but for
future G++ compatibility there should be a check for __cplusplus.

Hmm, that's a good point... I hadn't really thought about C++. I
won't mess with it for now, and we can audit the headers for C++
support once a significant fraction are implemented (the C++ standard
has its own extensive section about standard headers which I haven't
read in detail).

(Does
the GCC compatibility of clang extend beyond the command-line parameters
of the ccc wrapper script?)

clang intends to be gcc-compatible as far as is necessary for existing
code to continue working, which means supporting essentially every
interesting gcc extension. Of course, some stuff still isn't
complete.

-Eli

Per title, this is an implementation of stdbool.h, to start off the
project of clang getting its own headers.

Nice!

I picked stdbool.h because
it is one of the simplest standard headers, being that it only has
four straightforward macros. It would be embarrassing if I screwed it
up somehow :slight_smile:

Hehe. :slight_smile: It would be really nice to support C++, since clang does support bool in C++ already. I think this just amounts to wrapping the #defines with "#ifndef __cplusplus".

I'm not completely sure if I got the license part right... is some
sort of special exception needed in the headers so programs compiled
with clang aren't under the clang license?

Please use the MIT license instead of the LLVM license for the header. There was some discussion of this a couple months ago, here are some links:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-December/000619.html
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-December/000640.html

sabre indicated on IRC that he might get the build system and driver
and whatnot setup for clang to have its own headers sometime in the
near future, so I prepared this to allow for testing.

I'll see what I can do. Does anyone know a good way to find a path relative to the executable? Ideally I'd like to have "make install" install a file system like:

<prefix>/bin/clang
<prefix>/include/clang/stdbool.h
etc.

and have the build tree look like (note the similarity :slight_smile: :

llvm/Debug/bin/clang
llvm/Debug/include/clang/stdbool.h

The best way I know that avoids having to hard code the prefix into the executable is by making clang search the "../include/clang" path from its executable. Is there a good way to do this?

-Chris

It's ugly on Unix: Perform a PATH search using argv[0]. There may be better platform-specific way to do it, but this is portable.

Maybe this should be a lib/System facility.

— Gordon

The best way I know that avoids having to hard code the prefix into
the executable is by making clang search the "../include/clang" path
from its executable. Is there a good way to do this?

On Mac OS X CFBundle knows how to find the absolute path of the
executable. On Linux one can read the symbolic link /proc/self/exe.
On Windows if you open an app from the GUI, the CWD is the one
containing the executable, but if you run it on the command-line
that's presumably not the case... and on other OSes, I don't know of
any way other than Gordon's suggestion of searching PATH for argv[0].

-Keith

On Windows, I've found using GetModuleHandle(0) and GetModuleFileName
to work fairly well.
I am not sure it works in all cases, but might be a good starting point.

-Matthew Jimenez

Ok, I'll see what I can do with argv[0]. If this doesn't work on windows, hopefully someone working there can help :slight_smile:

-Chris

Unfortunately, the argv[0] thing is fragile -- there's no requirement
that the invoking process fill either argv[0] or PATH in such a way
that we can find the executable.

It sounds like Mac OS X, Linux and Windows have good robust
platform-specific solutions; is there anyone out there who can comment
on the other OSes (I guess Solaris and various BSDs at least are
interesting).

Or perhaps we have to admit that POSIX programs hard-code absolute
paths to their data files with good reason :wink:

There is also the issue of clang-as-library, where should it look for
its data files then? Or is this handled outside that scope?

-Keith

Ok, I'll see what I can do with argv[0]. If this doesn't work on
windows, hopefully someone working there can help :slight_smile:

Unfortunately, the argv[0] thing is fragile -- there's no requirement
that the invoking process fill either argv[0] or PATH in such a way
that we can find the executable.

It sounds like Mac OS X, Linux and Windows have good robust
platform-specific solutions; is there anyone out there who can comment
on the other OSes (I guess Solaris and various BSDs at least are
interesting).

Or perhaps we have to admit that POSIX programs hard-code absolute
paths to their data files with good reason :wink:

I can't believe this, there has to be a somewhat decent way, tell me it's so! :wink:

There is also the issue of clang-as-library, where should it look for
its data files then? Or is this handled outside that scope?

It is client specific. All the code I add will be in clang.cpp, not one of the libraries.

-Chris

Actually, dladdr seems useful on unix'y systems. Does this work on linux?

A quick trip to Google suggests that dladdr is nonstandard,
implemented on Solaris, Linux (glibc), Mac OS X, maybe FreeBSD,
definitely not OpenBSD.

-Keith

Keith Bauer wrote:

  

Actually, dladdr seems useful on unix'y systems. Does this work on
linux?
    
A quick trip to Google suggests that dladdr is nonstandard,
implemented on Solaris, Linux (glibc), Mac OS X, maybe FreeBSD,
definitely not OpenBSD.

It depends on OpenBSD version, on 4.2 it works[*], but only if you pass
an address of a symbol from a dynamic libray, not the main executable.
So this works:
$ gcc -shared p.c -o p.so
$ gcc p.so
$ LD_LIBRARY_PATH=. ./a.out
1
./p.so

Note that you'll get the path to the library!
[*] it looks like it works since OpenBSD 3.6 (2004): "Add dladdr(3)
<dlfcn(3) - OpenBSD manual pages; support
to the dynamic loader" (OpenBSD 3.6 Changelog)

Also on Linux you need to #define _GNU_SOURCE, otherwise you get a
compile error (Dl_info undeclared).

Have a look at dlloader.h from XFree86 (TinyURL.com - shorten that long URL into a tiny URL)
#if (defined(linux) && defined(__GLIBC__)) || \

   (defined(__FreeBSD__) && defined(__ELF__)) || \
    defined(__NetBSD__) || \
    (defined(__OpenBSD__) && defined(OpenBSD) && OpenBSD >= 200411) || \
    (defined(sun) && defined(SVR4)) || \
    defined(sgi)
#define *HAVE_DLADDR*
#endif

Best regards,
--Edwin

Okay, I just checked in the makefile support and a very simple, but working, solution using dladdr. It should build on all platforms, but won't work in some cases (such as this above). I'd appreciate it if people could help improve the sys::Path::GetMainExecutable to work on their hosts. Also, I now get this warning from G++:

clang.cpp:883: warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object

This is true, but not very helpful. I'm not sure how to work around this other than not building with -pedantic.

A simple test:

$ echo "#include <stdbool.h>" | clang -E -C | grep Eli
  * Copyright (c) 2008 Eli Friedman

-Chris

union {
  void *ptr;
  void (*func)(void);
};

timo