Build with Clang/LLVM when available.

git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk@1164964 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/INSTALL b/INSTALL
index 9c8a9bd..01a7227 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,11 +1,11 @@
 Apache Tuscany SCA Runtime
 ==========================
 
-Automated installation on Ubuntu Server 10.10
-=============================================
+Automated installation on Ubuntu Server 10.10 and 11.04
+=======================================================
 
-Tuscany provides two automated install scripts for Ubuntu Server 10.10. You can
-start with a fresh Ubuntu Server 10.10 system and these scripts will take care
+Tuscany provides automated install scripts for Ubuntu Server 10.10 and 11.04.
+You can start with a fresh Ubuntu Server system and these scripts will take care
 of all the download, build and installation steps for you.
 
 ubuntu/ubuntu-install:
@@ -29,35 +29,19 @@
 The installation script will display each command as it's executed.
 
 That's all you need to do to build and install the Tuscany SCA runtime on
-Ubuntu Server 10.10.
+Ubuntu Server.
 
 Automated installation on Max OS X 10.6.7
 =========================================
 
-Tuscany provides an automated install script for Mac OS X 10.6.7. You can start
-with a fresh Mac OS X 10.6.7 system and the script will take care of all the
-download, build and installation steps for you.
+Tuscany provides an automated install script for Mac OS X 10.6.7 and Xcode 4.1.
+You can start with a fresh Mac OS X 10.6.7 + Xcode 4.1 system and the script
+will take care of all the download, build and installation steps for you.
 
 macos/macos-install:
 Build and installation of the most commonly used Tuscany features with all
 dependencies built from source.
 
-The only required system dependency is the GCC C++ compiler 4.4.5+. All other
-dependencies are downloaded and built from source in the current directory.
-
-Before running the automated installation install GCC 4.6 from the HPC for Mac
-OS X project (http://hpc.sourceforge.net/) like this:
-curl -OL http://prdownloads.sourceforge.net/hpc/gcc-snwleo-intel-bin.tar.gz
-sudo tar -xf $build/gcc-snwleo-intel-bin.tar.gz -C /
-
-or if you prefer to use GCC from Macports (http://www.macports.org/), install
-GCC 4.4.5+ like this:
-sudo port install gcc44
-
-then adjust the following line in macos/macos-install:
-./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++ ...
-to point to the GCC binaries you've installed.
-
 To run the automated installation:
 mkdir tuscany
 cd tuscany
@@ -67,15 +51,18 @@
 
 The installation script will display each command as it's executed.
 
+The dependencies will be built using the GCC compiler. The Tuscany SCA runtime
+will be built using the Apple Clang/LLVM compiler.
+
 That's all you need to do to build and install the Tuscany SCA runtime on Mac
-OS X 10.6.7.
+OS X.
 
 
 Step by step build and installation
 ===================================
 
-For manual build and install steps on systems other than Ubuntu 10.10 and
-Mac OS X 10.6.7, or if you need to customize your installation, read on...
+For manual build and install steps on other systems than Ubuntu Server and Mac
+OS X, or if you need to customize your installation, read on...
 
 The Tuscany SCA Linux build uses the GNU Autotools tool chain.
 
@@ -221,35 +208,35 @@
 ./configure --help
 
 
-Here's an example configuration tested on Ubuntu 10.10, with the system
+Here's an example configuration tested on Ubuntu Server, with the system
 dependencies installed in the standard system directories and some of the
-dependencies installed under $HOME:
+dependencies installed under $build:
 
-./configure --prefix=$HOME/tuscany-sca-cpp-bin \
---with-apr=$HOME/apr-1.4.x-bin --with-httpd=$HOME/httpd-2.3.10-bin \
---with-memcached=$HOME/memcached-1.4.7-bin \
---with-tinycdb=$HOME/tinycdb-0.77-bin \
---with-curl=$HOME/curl-7.19.5-bin --with-libxml2=/usr \
---with-js-include=$HOME/js-1.8.5-bin/include \
---with-js-lib=$HOME/js-1.8.5-bin/lib \
+./configure --prefix=$build/tuscany-sca-cpp-bin \
+--with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin \
+--with-memcached=$build/memcached-1.4.7-bin \
+--with-tinycdb=$build/tinycdb-0.77-bin \
+--with-curl=$build/curl-7.19.5-bin --with-libxml2=/usr \
+--with-js-include=$build/js-1.8.5-bin/include \
+--with-js-lib=$build/js-1.8.5-bin/lib \
 --enable-libcloud \
---with-libcloud=$HOME/libcloud-0.3.1-bin \
+--with-libcloud=$build/libcloud-0.3.1-bin \
 --enable-threads \
 --enable-python --with-python=/usr \
 --enable-opencl --with-opencl-include=/usr/include --with-opencl-lib=/usr/lib \
---enable-gae --with-gae=$HOME/google_appengine \
+--enable-gae --with-gae=$build/google_appengine \
 --enable-java --with-java=/usr/lib/jvm/default-java \
---enable-webservice --with-axis2c=$HOME/axis2c-1.6.0-bin \
---with-libxml2=$HOME/libxml2-2.7.7-bin \
---enable-queue --with-qpidc=$HOME/qpidc-0.6-bin \
---enable-chat --with-libstrophe=$HOME/libstrophe-bin \
---with-vysper=$HOME/vysper-0.5 \
---enable-sqldb --with-pgsql=$HOME/postgresql-9.0.3-bin \
---enable-log --with-thrift=$HOME/thrift-0.2.0-bin \
---with-scribe=$HOME/scribe-2.2-bin \
---enable-openid --with-mod-auth-openid=$HOME/mod-auth-openid-bin \
---enable-oauth --with-liboauth=$HOME/liboauth-0.9.1-bin \
---enable-mod-security --with-mod-security=$HOME/modsecurity-apache-2.6.0-bin \
+--enable-webservice --with-axis2c=$build/axis2c-1.6.0-bin \
+--with-libxml2=$build/libxml2-2.7.7-bin \
+--enable-queue --with-qpidc=$build/qpidc-0.6-bin \
+--enable-chat --with-libstrophe=$build/libstrophe-bin \
+--with-vysper=$build/vysper-0.5 \
+--enable-sqldb --with-pgsql=$build/postgresql-9.0.3-bin \
+--enable-log --with-thrift=$build/thrift-0.2.0-bin \
+--with-scribe=$build/scribe-2.2-bin \
+--enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin \
+--enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin \
+--enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.0-bin \
 --enable-maintainer-mode
 
 
diff --git a/configure.ac b/configure.ac
index eeba817..d0f5a29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,17 +27,18 @@
 
 # Check for required programs.
 AC_MSG_NOTICE([checking for programs])
-AC_MSG_CHECKING([for gcc-4.5])
-if test -x "/usr/bin/g++-4.5"; then
-    # Use GCC 4.5 if available
-    CXX=/usr/bin/g++-4.5
-    CPP=/usr/bin/cpp-4.5
-    CC=/usr/bin/gcc-4.5
-    AC_MSG_RESULT(/usr/bin/gcc-4.5)
-    AM_CONDITIONAL([WANT_GCC45], true)
-    AC_DEFINE([WANT_GCC45], 1, [compile with gcc-4.5])
-else
-    AM_CONDITIONAL([WANT_GCC45], false)
+if test "${CXX}" = ""; then
+  AC_MSG_CHECKING([for clang++])
+  if test -x "/usr/bin/clang++"; then
+    # Use CLang++/LLVM if available
+    CXX=/usr/bin/clang++
+    CC=/usr/bin/clang
+    AC_MSG_RESULT(/usr/bin/clang++)
+    AM_CONDITIONAL([WANT_LLVM], true)
+    AC_DEFINE([WANT_LLVM], 1, [compile with clang++/llvm])
+  else
+    AM_CONDITIONAL([WANT_LLVM], false)
+  fi
 fi
 AC_PROG_CXX
 AC_PROG_AWK
@@ -49,6 +50,12 @@
 AC_PROG_LIBTOOL
 
 # Initialize default GCC C++ and LD options.
+cxxname=`basename ${CXX}`
+if test "${cxxname}" = "clang++"; then
+  cxxtype="clang"
+else
+  cxxtype="gcc"
+fi
 cxxflags="${CXXFLAGS}"
 ldflags="${LDFLAGS}"
 defaultlibs="${LIBS}"
@@ -107,12 +114,20 @@
   esac ],
 [ AC_MSG_RESULT(no)])
 if test "${want_maintainer_mode}" = "true"; then
-  cxxflags="${cxxflags} -D_DEBUG -O2 -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Wno-strict-aliasing -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Wconversion -Waddress -Wlogical-op -Wredundant-decls -std=c++0x -fmessage-length=0"
+  cxxflags="${cxxflags} -D_DEBUG -O2 -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Wno-strict-aliasing -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Waddress -Wredundant-decls -std=c++0x -fmessage-length=0"
+  if test "${cxxtype}" = "clang"; then
+    cxxflags="${cxxflags} -stdlib=libc++"
+  else
+    cxxflags="${cxxflags} -Wlogical-op -Wconversion"
+  fi
   ldflags="${ldflags} -pg"
   AM_CONDITIONAL([WANT_MAINTAINER_MODE], true)
   AC_DEFINE([WANT_MAINTAINER_MODE], 1, [compile with debugging and compile-time warnings])
 else
   cxxflags="${cxxflags} -g -O2 -std=c++0x -fmessage-length=0"
+  if test "${cxxtype}" = "clang"; then
+    cxxflags="${cxxflags} -stdlib=libc++"
+  fi
   AM_CONDITIONAL([WANT_MAINTAINER_MODE], false)
 fi
 
diff --git a/kernel/config.hpp b/kernel/config.hpp
index f700829..5b447e1 100644
--- a/kernel/config.hpp
+++ b/kernel/config.hpp
@@ -34,10 +34,36 @@
 /**
  * Platform configuration and debug functions.
  */
-
 namespace tuscany
 {
 
+/**
+ * Attribute used to mark unused parameters.
+ */
+#ifndef unused
+#define unused __attribute__ ((unused))
+#endif
+
+/**
+ * Compiler feature detection.
+ */
+#ifdef __clang__
+
+#if __has_feature(cxx_lambdas)
+#define HAS_CXX0X_LAMBDAS 1
+#endif
+
+#else
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
+#define HAS_CXX0X_LAMBDAS 1
+#endif
+
+#endif
+
+/**
+ * Debug utilities.
+ */
 #ifdef WANT_MAINTAINER_MODE
 
 /**
@@ -46,7 +72,7 @@
 //#define WANT_MAINTAINER_WATCH
 
 /**
- * Increment / decrement a debug counter.
+ * Increment/decrement a debug counter.
  */
 bool debug_inc(long int& c) {
     c++;
@@ -65,12 +91,5 @@
 
 #endif
 
-/**
- * Attribute used to mark unused parameters.
- */
-#ifndef unused
-#define unused __attribute__ ((unused))
-#endif
-
 }
 #endif /* tuscany_config_hpp */
diff --git a/kernel/fstream.hpp b/kernel/fstream.hpp
index d57de2d..6888e7d 100644
--- a/kernel/fstream.hpp
+++ b/kernel/fstream.hpp
@@ -164,7 +164,7 @@
     logfstream(FILE* file, const string& type) : file(file), type(type), owner(false), head(false) {
     }
 
-    logfstream(const logfstream& os) : file(os.file), type(type), owner(false), head(os.head) {
+    logfstream(const logfstream& os) : file(os.file), type(os.type), owner(false), head(os.head) {
     }
 
     ~logfstream() {
diff --git a/kernel/gc.hpp b/kernel/gc.hpp
index 30cc637..28ca80e 100644
--- a/kernel/gc.hpp
+++ b/kernel/gc.hpp
@@ -47,7 +47,7 @@
  */
 bool assertOrFail(const bool expr) {
     if (!expr)
-        *(char*)NULL = '\0';
+        abort();
     return true;
 }
 
@@ -183,7 +183,8 @@
 class gc_pool_stack_t {
 public:
     gc_pool_stack_t() {
-        pthread_key_create(&key, NULL);
+        int rc = pthread_key_create(&key, NULL);
+        assertOrFail(rc == 0);
     }
 
     operator apr_pool_t*() const {
@@ -204,21 +205,6 @@
 #endif
 
 /**
- * Return the current memory pool.
- */
-apr_pool_t* gc_current_pool() {
-    apr_pool_t* apr_pool = gc_pool_stack;
-    if (apr_pool != NULL)
-        return apr_pool;
-
-    // Create a parent pool for the current thread
-    apr_pool_create(&apr_pool, NULL);
-    assertOrFail(apr_pool != NULL);
-    gc_pool_stack = apr_pool;
-    return apr_pool;
-}
-
-/**
  * Push a pool onto the stack.
  */
 apr_pool_t* gc_push_pool(apr_pool_t* pool) {
@@ -237,6 +223,21 @@
 }
 
 /**
+ * Return the current memory pool.
+ */
+apr_pool_t* gc_current_pool() {
+    apr_pool_t* p = gc_pool_stack;
+    if (p != NULL)
+        return p;
+
+    // Create a parent pool for the current thread
+    apr_pool_create(&p, NULL);
+    assertOrFail(p != NULL);
+    gc_push_pool(p);
+    return p;
+}
+
+/**
  * A memory pool scope, used to setup a scope in which a particular pool
  * will be used for all allocations.
  */
@@ -302,7 +303,7 @@
 }
 
 template<typename T> T* gc_anew(apr_pool_t* p, size_t n) {
-    size_t* gc_anew_ptr = static_cast<size_t*>(apr_palloc(p, sizeof(size_t) + sizeof(T[n])));
+    size_t* gc_anew_ptr = static_cast<size_t*>(apr_palloc(p, sizeof(size_t) + sizeof(T) * n));
     assertOrFail(gc_anew_ptr != NULL);
     *gc_anew_ptr = n;
     apr_pool_cleanup_register(p, gc_anew_ptr, gc_pool_acleanup<T>, apr_pool_cleanup_null) ;
diff --git a/kernel/hash.hpp b/kernel/hash.hpp
index 9de13dd..993511e 100644
--- a/kernel/hash.hpp
+++ b/kernel/hash.hpp
@@ -122,7 +122,7 @@
     // Mix 4 bytes at a time into the hash
     const unsigned char* data = (const unsigned char*)key;
     while(len >= 4) {
-        unsigned int k = *(unsigned int*)data;
+        unsigned int k = *(unsigned int*)(void*)data;
         k *= m; 
         k ^= k >> r; 
         k *= m; 
diff --git a/kernel/lambda-test.cpp b/kernel/lambda-test.cpp
index a72f01f..e17cf57 100644
--- a/kernel/lambda-test.cpp
+++ b/kernel/lambda-test.cpp
@@ -31,7 +31,7 @@
 
 namespace tuscany {
 
-#ifdef WANT_GCC45
+#ifdef HAS_CXX0X_LAMBDAS
 
 const lambda<const int(const int)> inc(const int i) {
     return [=](const int x)->const int {
@@ -89,11 +89,11 @@
 int main() {
     tuscany::cout << "Testing..." << tuscany::endl;
 
-#ifdef WANT_GCC45
+#ifdef HAS_CXX0X_LAMBDAS
     tuscany::testLambda();
     tuscany::testCppPerf();
 #else
-    tuscany::cout << "Skipped GCC 4.5 tests" << tuscany::endl;
+    tuscany::cout << "Skipped C++0x lambda tests" << tuscany::endl;
 #endif
 
     tuscany::cout << "OK" << tuscany::endl;
diff --git a/macos/macos-install b/macos/macos-install
index 14804e3..9e981d0 100755
--- a/macos/macos-install
+++ b/macos/macos-install
@@ -25,12 +25,6 @@
 # Build and install in the current directory
 build=`pwd`
 
-# Install core dev tools missing on MacOS
-
-# Install and use GCC 4.6, required for c++0x
-#curl -OL http://prdownloads.sourceforge.net/hpc/gcc-snwleo-intel-bin.tar.gz
-#sudo tar -xf $build/gcc-snwleo-intel-bin.tar.gz -C /
-
 # Install pkg-config
 curl -OL http://pkgconfig.freedesktop.org/releases/pkg-config-0.25.tar.gz
 tar xzf pkg-config-0.25.tar.gz
@@ -285,7 +279,7 @@
 git clone git://git.apache.org/tuscany-sca-cpp.git
 cd tuscany-sca-cpp
 ./bootstrap
-./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++ --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-opencl --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.0-bin
+./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-opencl --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.0-bin
 make
 make install
 if [ "$?" != "0" ]; then
diff --git a/modules/http/httpd.hpp b/modules/http/httpd.hpp
index 9440fe3..3a651fa 100644
--- a/modules/http/httpd.hpp
+++ b/modules/http/httpd.hpp
@@ -34,6 +34,8 @@
 #include <apr_base64.h>
 
 #include <httpd.h>
+// Hack to workaround compile error with CLang/LLVM
+#undef strtoul
 // Hack to workaround compile error with HTTPD 2.3.8
 #define new new_
 #include <http_config.h>
@@ -427,10 +429,6 @@
  * Create an HTTPD internal redirect request.
  * Similar to httpd/modules/http/http_request.c::internal_internal_redirect.
  */
-extern "C" {
-    AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p);
-}
-
 const failable<request_rec*, int> internalRedirectRequest(const string& nr_uri, request_rec* r) {
     if (ap_is_recursion_limit_exceeded(r))
         return mkfailure<request_rec*, int>(HTTP_INTERNAL_SERVER_ERROR);
@@ -498,10 +496,6 @@
  * Process an HTTPD internal redirect request.
  * Similar to httpd/modules/http/http_request.c::ap_internal_redirect.
  */
-extern "C" {
-    AP_DECLARE(int) ap_invoke_handler(request_rec *r);
-}
-
 const int internalRedirect(request_rec* nr) {
     int status = ap_run_quick_handler(nr, 0);
     if (status == DECLINED) {
diff --git a/modules/http/mod-ssltunnel.cpp b/modules/http/mod-ssltunnel.cpp
index 0fd347c..521b866 100644
--- a/modules/http/mod-ssltunnel.cpp
+++ b/modules/http/mod-ssltunnel.cpp
@@ -34,6 +34,11 @@
 #include "httpd.hpp"
 #include "http.hpp"
 
+// Ignore cast align warnings in APR macros
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
+
 extern "C" {
 extern module AP_MODULE_DECLARE_DATA mod_tuscany_ssltunnel;
 }
@@ -212,6 +217,7 @@
                     if (rl == 0)
                         return close(conn, csock);
 
+
                     // Send bucket to client
                     debug(string(data, rl), "modssltunnel::tunnel::sendToClient");
                     APR_BRIGADE_INSERT_TAIL(ob, apr_bucket_transient_create(data, rl, conn->bucket_alloc));
@@ -364,3 +370,9 @@
 };
 
 }
+
+// Reenable cast align warnings
+#ifdef WANT_MAINTAINER_MODE
+#pragma GCC diagnostic warning "-Wcast-align"
+#endif
+