clang3.2(trunk) on MinGW(MSYS) with GCC 4.7.0

clangのコンパイル方法は日本語でもあちこちにあるので省略。
現時点のsvn trunkからcheak outしたソースを使用した場合、
MinGWでGCC4.7.0を使っていると色々と問題が出るのでその修正方法を書きます。

1.Include Pathの解決(既に知っている人が多いと思いますが)
MinGWがc\mingw以外にインストールされている場合Include Pathが解決できずにコンパイルに失敗します。
たとえばMinGWをd\mingwにインストールした場合は下記のように修正します。

clang/lib/Frontend/InitHeaderSearch.cpp
InitHeaderSearch.cpp(line:323)

      AddPath("/mingw/include", System, true, false, false);
#if defined(_WIN32)
      AddPath("c:/mingw/include", System, true, false, false); 
      AddPath("d:/mingw/include", System, true, false, false);  // 追加
#endif

InitHeaderSearch.cpp(line:401)

    // mingw.org C++ include paths
    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
#if defined(_WIN32)
    AddMinGWCPlusPlusIncludePaths("d:/MinGW/lib/gcc", "mingw32", "4.7.0");  // 追加
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2");
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1");
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2");
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
#endif

2.ABI修正
GCC 4.7 changelogに以下の文があります。
Windows x86 targets are using the __thiscall calling convention for C++ class-member functions.
GCC4.7ではメンバ関数コールを__thiscallにする変更が入ってます。これをclang側にも適応します。
clang/lib/AST/ItaniumCXXABI.cpp(line:42)下記を

  CallingConv getDefaultMethodCallConv(bool isVariadic) const {
    return CC_C;
  }

このように修正します。

  CallingConv getDefaultMethodCallConv(bool isVariadic) const {
    if (!isVariadic && Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
      return CC_X86ThisCall;
    else
      return CC_C;
  }

3.memoryヘッダの修正
memoryヘッダをインクルードするとコンパイルエラーになります。
これは4.6.2でも下記のようにエラーになるようです。

c:/MinGW/lib/gcc/mingw32/4.6.2/include/c++\ext/concurrence.h:228:2: error: no
      matching function for call to '_S_destroy'
        _S_destroy(&_M_mutex);
        ^~~~~~~~~~
c:/MinGW/lib/gcc/mingw32/4.6.2/include/c++\ext/concurrence.h:273:7: note:
      candidate template ignored: substitution failure [with _Rm =
      __gthread_recursive_mutex_t]: non-type template argument evaluates to 4,
      which cannot be narrowed to type 'bool'
      _S_destroy(_Rm* __mx)
      ^
c:/MinGW/lib/gcc/mingw32/4.6.2/include/c++\ext/concurrence.h:282:7: note:
      candidate template ignored: substitution failure [with _Rm =
      __gthread_recursive_mutex_t]: no member named 'actual' in
      '__gthread_recursive_mutex_t'
      _S_destroy(_Rm* __mx)
      ^
c:/MinGW/lib/gcc/mingw32/4.6.2/include/c++\ext/concurrence.h:290:7: note:
      candidate template ignored: substitution failure [with _Rm =
      __gthread_recursive_mutex_t]: no type named '__type' in
      '__gnu_cxx::__enable_if'
      _S_destroy(_Rm* __mx)
      ^

これはlibstdc++のバグで、gccのヘッダを修正します。
ext/concurrence.h(line:273)
下記コードを

    template<typename _Rm> 
      static typename __enable_if<sizeof(&_Rm::sema), void>::__type 
      _S_destroy(_Rm* __mx) 

以下のように修正します。

    template<typename _Rm> 
//      static typename __enable_if<sizeof(&_Rm::sema), void>::__type 
      static typename __enable_if<(bool)sizeof(&_Rm::sema), void>::__type 
      _S_destroy(_Rm* __mx) 

参考:[clang-3.2] unique_ptr: compiler errors