Hi,
please see the attached patches that contain various fixes that enable Ice to compile using clang 3.0 and new versions of gcc. The patches have been tested (compilation and unit tests) using:
- clang 3.0:
- gcc 4.7.0 20120128
- gcc 4.2.1 (to make sure nothing broke and all changes are backwards compatible)
Content
There are three patches attached, usually you only need one of them:
- ice_for_clang.patch.txt: This contains all changes for all compilers
- ice_for_clang_only.patch.txt: This contains only the changes necessary to compile using clang (smaller changeset)
- freebsd_port_devel_ice.patch.txt: Patch for FreeBSD ports (see below how to use)
All three patches also contain the patches Two small patches for Freeze and IceGrid (the former potentially bad) and Improvements to unit tests (fix in encoding and FreeBSD support). Note that these changes only affect Ice for C++ and other language mappings have neither been changed nor tested.
What has been changed?
The patch fixes a couple of problems with the current implementation of Ice in terms of C++ standard compliance. The biggest issue is the way the upCast functions are overloaded. The standard says:
First, the compiler does unqualified lookup in the scope where the name was written. For a template, this means the lookup is done at the point where the template is defined, not where it's instantiated. Since Multiply hasn't been declared yet at this point, unqualified lookup won't find it.
Second, if the name is called like a function, then the compiler also does argument-dependent lookup (ADL). (Sometimes unqualified lookup can suppress ADL; see [basic.lookup.argdep]p3 for more information.) In ADL, the compiler looks at the types of all the arguments to the call. When it finds a class type, it looks up the name in that class's namespace; the result is all the declarations it finds in those namespaces, plus the declarations from unqualified lookup. However, the compiler doesn't do ADL until it knows all the argument types.
Since most of the upCast overloads are provided on incomplete types and after Handle has been included, the only way to lookup the correct overload (which has to be matching, since the forward declared types naturally don't provide any information on object hierarchy) is by ADL. For ADL to work, the overload has to be provided within the types namespace. Therefore a large portion of this patch is moving upCast overloads out of IceInternal into the Ice namespace. On the one hand this litters the Ice namespace with many different overloads of upCast, on the other this seemed the easiest and most straight forward solution within breaking any internals and massive testing. Since upCast is also used within generated code slice2cpp has been changed accordingly.
The patch also fixes a cyclic inclusion problem caused by clang's stricter evaluation of template types (throwing a forward declared exception from within a template class) and other minor declaration order problems and glitches (old) gcc was fine with.
The changes implemented for gcc 4.7 are mostly cosmetic, a lot of compiler warning suppression (NDEBUG/assert).
Compilation flags
clang:Plain clang++, no further parameters (therefore C++03, system's stdc++)
gcc 4.7.1: CXX=g++47 -std=gnu++11 -I/usr/local/lib/gcc47/include/c++ -Wno-deprecated-declarations
gcc 4.2.1: g++
Caveats
This didn't compile yet using -std=c++11 since there are unresolved issues with strtoll on my platform. Ultimately I would like to see this compile using clang, C++11 and clang's libc++. Right now I can't get my hands on it in a near production environment so this has to wait.
Instructions for FreeBSD ports
Assuming you want to compile Ice using clang:
Make sure you've set
Code:
CC=clang
CXX=clang++
CPP=clang -E
(e.g. in your make.conf)
Make sure you have the latest port collection (portsnap fetch update) and patch the ice port using:
Code:
patch -p0 </path/to/freebsd_port_devel_ice.patch.txt
From there it's basically make install:
Code:
cd /usr/ports/devel/ice
make install clean
Conclusion/Disclaimer
After applying the patch, compiling Ice using clang works flawlessly and only a few intentional deprecation warnings show up. Switching to C++11 and clang's own libc++ will be the next logical step. Obviously I cannot give any guarantees for any of the code, but by all I can tell Ice behaves pretty much like it should.
Cheers,
Michael